{"id":15372974,"url":"https://github.com/vi/duplo","last_synced_at":"2026-01-21T13:33:35.345Z","repository":{"id":66289252,"uuid":"603914580","full_name":"vi/duplo","owner":"vi","description":"Web application for anonymous file sharing in intranet environments.","archived":false,"fork":false,"pushed_at":"2024-10-10T15:18:12.000Z","size":480,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-02T02:29:30.983Z","etag":null,"topics":["cli-app","file-sharing","file-upload","intranet","web"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/vi.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":"2023-02-19T23:20:41.000Z","updated_at":"2025-07-25T05:06:10.000Z","dependencies_parsed_at":"2024-10-16T12:41:32.800Z","dependency_job_id":"9fec2f1f-217e-428c-afba-3bff38a82223","html_url":"https://github.com/vi/duplo","commit_stats":{"total_commits":11,"total_committers":1,"mean_commits":11.0,"dds":0.0,"last_synced_commit":"1ad5e27a027a58c572c7c4bdabebfcb527879f46"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/vi/duplo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vi%2Fduplo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vi%2Fduplo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vi%2Fduplo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vi%2Fduplo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vi","download_url":"https://codeload.github.com/vi/duplo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vi%2Fduplo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28633763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"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":["cli-app","file-sharing","file-upload","intranet","web"],"created_at":"2024-10-01T13:53:51.331Z","updated_at":"2026-01-21T13:33:35.328Z","avatar_url":"https://github.com/vi.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Duplo\n\nWeb application for anonymous file sharing. Alternative backend for [Mikhalevich/filesharing](https://github.com/Mikhalevich/filesharing).\n\n![screenshot](screenshot.png)\n\n# Features\n\n* Uploading files to server from browser, including by drag and drop.\n* Easy way to publish a text snippet (pastebin-style).\n* Uploaded html pages immediately become viewable in browser. `index.html` is searched in directories. MIME types are guessed.\n* Automatic cleanup of old files in one of the two directories.\n* Quotas to prevent excessive files count or total byte size.\n* Easy deployment: executable embeds static assets, is usable as is (without a separate Web server).\n* Supports HTTP/2.\n* Logging that inclues uploads, removes and cleanups.\n\n# Limitations\n\n* No authentication (unlike in original \"filesharing\" project).\n* No overload protection (besides disk quotas) - DoS of the host that has Duplo deployed may be possible.\n* Iffy web security. Uploaded html files are served as `text/html`, which affects web security of the origin Duplo is deployed at.\n* Configuration is not very flexible. Unlike original \"filesharing\" there always two shares. You may want to override \"Content-Security-Policy\" header for served content for more permissive or more restrictive rules.\n* Not tested on non-Linux\n* No support for creating, listing or removing directories.\n\nDeploying globally accessible instances of Duplo is not recommended.\n\n# Deployment\n\n1. Download pre-built release of Duplo from [Github Releases](https://github.com/vi/duplo/releases) or build it from the source code with `cargo install --path .`\n2. Choose two directories: transient (old files are clean up daily) and permanent (no cleanup happens).\n3. Choose port to serve incomding requests on.\n4. Start the application: `duplo 0.0.0.0:80 -t /path/to/directory_where_old_files_disappear -p /path/to/permanent_directory`\n5. Navigate to `http://127.0.0.1:80/` - redirect would take you to the transient fileshare. There is no link to permanent fileshare anywhere - you need to access it by explicit URL: `http://127.0.0.1:80/permanent/`. Test that some upload or text share work.\n\nIt should not be tricky to deploy it as a SystemD service or in Docker.\n\nDefault quotas as 10GB and 1000 files. By default, cleanup happens at 00:00 GMT+0 and removes files older than 24 hours.\n\nThere is no option to opt out of one of the two fileshares - you can specify empty directory without write access to workaround this.\n\n# Usage message\n\n\u003cdetails\u003e\u003csummary\u003e`duplo --help` output\u003c/summary\u003e\n\n```\nUsage: duplo \u003clisten_socket\u003e -t \u003ctransiet-directory\u003e -p \u003cpermanent-directory\u003e [--max-files \u003cmax-files\u003e] [--max-bytes \u003cmax-bytes\u003e] [--cleanup-time-utc \u003ccleanup-time-utc\u003e] [--cleanup-maxhours \u003ccleanup-maxhours\u003e] [--transient-title \u003ctransient-title\u003e] [--permanent-title \u003cpermanent-title\u003e] [--content-security-policy \u003ccontent-security-policy\u003e]\n\nsimple insecure HTTP server with anonymous file upload (including html/js upload and publication)\n\nPositional Arguments:\n  listen_socket     socket address to bind TCP socket and listen for including\n                    HTTP requests\n\nOptions:\n  -t, --transiet-directory\n                    serve (and upload) files from this directory at /transient/\n  -p, --permanent-directory\n                    serve (and upload) files from this directory at /permanent/\n  --max-files       maximum number of files allowed to reside in transient and\n                    permanent directories. Default is 1000\n  --max-bytes       maximum number of bytes allowed to reside in transient and\n                    permanent directories. Default is 10GB\n  --cleanup-time-utc\n                    time of day (UTC+0 timezone) to trigger the cleanup event\n                    on. Default is `00:00:00`\n  --cleanup-maxhours\n                    clean up files older than this number of hours from the\n                    transient directory. Default is 24.\n  --transient-title page title for transient directory's filelist\n  --permanent-title page title for permanent directory's filelist\n  --content-security-policy\n                    set this Content-Security-Policy header for served files\n  --help            display usage information\n\n```\n\n\u003c/details\u003e\n\n# License\n\nCode in `src/` directory is original and is licensed with MIT or Apache-2.0.  \nCode within `res/` directory (e.g. jquery, dropzone.js, bootstrap) originates from multiple sources and typically have MIT-like licenses. Those files are embedded into the executable at build time.  \nCode in `templates/` is based on [filesharing-web-service](https://github.com/Mikhalevich/filesharing-web-service/tree/22e686e89aee40447e0a0942c444170806bd3cfb), which does not specify a licence.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvi%2Fduplo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvi%2Fduplo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvi%2Fduplo/lists"}