{"id":17215203,"url":"https://github.com/doctormckay/node-b2ens","last_synced_at":"2025-10-04T11:54:02.545Z","repository":{"id":57188764,"uuid":"188524078","full_name":"DoctorMcKay/node-b2ens","owner":"DoctorMcKay","description":"This is a utility that is designed to back up (synchronize) a local directory to a Backblaze B2 bucket, encrypting the files along the way.","archived":false,"fork":false,"pushed_at":"2024-01-05T09:39:12.000Z","size":198,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-21T23:28:46.184Z","etag":null,"topics":["b2","backblaze","backblaze-b2","backup"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/b2ens","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DoctorMcKay.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}},"created_at":"2019-05-25T05:20:16.000Z","updated_at":"2022-01-19T07:20:21.000Z","dependencies_parsed_at":"2024-12-08T11:46:47.410Z","dependency_job_id":null,"html_url":"https://github.com/DoctorMcKay/node-b2ens","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/DoctorMcKay/node-b2ens","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorMcKay%2Fnode-b2ens","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorMcKay%2Fnode-b2ens/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorMcKay%2Fnode-b2ens/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorMcKay%2Fnode-b2ens/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DoctorMcKay","download_url":"https://codeload.github.com/DoctorMcKay/node-b2ens/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DoctorMcKay%2Fnode-b2ens/sbom","scorecard":{"id":41479,"data":{"date":"2025-08-11","repo":{"name":"github.com/DoctorMcKay/node-b2ens","commit":"82263c14a82005695437bfb2a0ec6dbc3c4400cf"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-14T21:40:54.111Z","repository_id":57188764,"created_at":"2025-08-14T21:40:54.111Z","updated_at":"2025-08-14T21:40:54.111Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278308625,"owners_count":25965654,"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","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["b2","backblaze","backblaze-b2","backup"],"created_at":"2024-10-15T03:23:36.889Z","updated_at":"2025-10-04T11:54:02.526Z","avatar_url":"https://github.com/DoctorMcKay.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# B2ENS\n\n*B2 Encrypt-n-Sync*\n\nThis is a utility that is designed to back up (synchronize) a local directory to a [Backblaze B2](https://www.backblaze.com)\nbucket, encrypting the files along the way.\n\n# Sync Rules\n\nThe application compares the local directory and the remote bucket, and for each file:\n\n- If the file exists locally but not remotely, uploads it\n- If the file exists remotely but not locally, hides it on B2\n- If the file exists both locally and remotely but the modification times are different, uploads the local copy and overwrites the remote copy\n\t- **Note:** It will still upload the local copy even if the remote modification time is newer!\n\t\nLocal files will **never** be modified. This tool is intended to allow you to backup a local directory to Backblaze B2,\nnot to use B2 as a sort of Dropbox.\n\nB2ENS assumes it has exclusive control over the bucket you configure it to use. If you upload files without using B2ENS,\nthey will be hidden (deleted) the next time B2ENS runs. \n\n# Usage\n\nInstall it from npm by running `npm install -g b2ens` in an administrator command prompt (on Windows) or as root (on Linux).\n\nUse it by running `b2ens \u003ccommand\u003e` on the command line. Available commands:\n\n```\n$ b2ens sync \u003cpath to syncfile\u003e\n    See \"Syncfiles\" section below\n\n$ b2ens generate-keypair \u003cpublic key output file path\u003e \u003cprivate key output file path\u003e\n\n$ b2ens generate-syncfile\n    Interactively guides you through creating a syncfile\n\n$ b2ens download\n\tDownload and decrypt files from the B2 bucket\n\t\n\tOptions:\n\t      --help         Show help\n\t      --dir          Remote directory to download. Omit to download everything\n\t  -o, --output       Path to output directory on local disk (files will be overwritten)    [required]\n\t  -s, --syncfile     Optional path to syncfile. If provided, you don't need to\n\t                     separately pass --bucket, --key-id, or --app-key\n\t  -b, --bucket       name of bucket to download files from\n\t      --key-id       B2 key ID to use to access your bucket\n\t      --app-key      B2 application key to use to access your bucket\n\t      --private-key  Path to PEM-encoded private key used to decrypt files                 [required]\n\n$ b2ens encrypt-file \u003cpath to public or private key\u003e \u003cinput file path\u003e [output file path]\n\n$ b2ens decrypt-file \u003cpath to private key\u003e \u003cinput file path\u003e [output file path] \n\n$ b2ens decrypt-folder \u003cpath to private key\u003e \u003cinput folder path\u003e \u003coutput folder path\u003e\n```\n\n# Syncfiles\n\nA *syncfile* is a JSON file containing the configuration for a sync. It should look like this:\n\n```json\n{\n\t\"local\": {\n\t\t\"directory\": \"/path/to/directory/to/backup\",\n\t\t\"exclude\": [\"/optional/array\", \"/of/files/or/directories\", \"/to/exclude\"]\n\t},\n\t\"remote\": {\n\t\t\"bucket\": \"name-of-bucket\",\n\t\t\"prefix\": \"somefolder/\"\n\t},\n\t\"keyId\": \"backblaze key id\",\n\t\"applicationKey\": \"backblaze application key\",\n\t\"encryptionKey\": {\n\t\t\"publicKeyPath\": \"/path/to/pem/encoded/rsa/key\",\n\t\t\"publicKey\": \"-----BEGIN PUBLIC KEY-----\\nblahblah\\n-----END PUBLIC KEY-----\"\n\t}\n}\n```\n\n- `local`\n\t- `directory` - The local directory to be backed up to Backblaze\n\t- `exclude` - An optional array of files and/or directories to exclude\n\t\t- For example, if you are backing up `/var/www/html`, then you would set `local.directory` = `/var/www/html`\n\t\t- If you wanted to exclude `/var/www/html/some-dir` and `/var/www/html/some-file`, then you would set `local.exclude` to `[\"/var/www/html/some-dir\", \"/var/www/html/some-file\"]`\n\t\t- As of v1.5.0, it is possible to use wildcards in exclusions\n\t\t\t- To signal that an exclusion contains wildcards, prefix it with `!`\n\t\t\t- `*` is interpreted as zero or more characters, excluding slashes\n\t\t\t- `**` is interpreted as zero or more characters, including slashes\n\t\t\t- If you want to exclude an entire directory and all its subdirectories, you should end your string with `/**`\n\t\t\t- Examples:\n\t\t\t\t- `!/var/www/html/some-dir/**` will match all files and subdirectories in `/var/www/html/some-dir`\n\t\t\t\t- `!/var/www/html/users/*/some-file` will match all files by name `some-file` contained within all directories in `/var/www/html/users`\n\t\t\t\t- `!/var/www/html/users/*/some-dir/**` will match all files and subdirectories in the `some-dir` directory contained within all directories in `/var/www/html/users`\n- `remote`\n\t- `bucket` - The name of the bucket (not the bucket ID) you want to back up to\n\t- `prefix` - If you want your backup root in the remote bucket to be in a folder, put the full path to the folder relative to the bucket root here. No leading slash, trailing slash required. Example: \"somefolder/\" or \"some/folder/\". If you omit the trailing slash, then all files will be uploaded to the bucket root, but with this value prefixed to their filenames. For example, a prefix of \"foo\" will cause a file named \"test.txt\" to be uploaded as \"footest.txt\".\n- `keyId` - The key ID you want to use to authenticate with Backblaze. For security reasons, this should be an application key that can only access your one bucket.\n- `applicationKey` - The Backblaze application key\n- `uploadThreads` - The number of threads to use when uploading large files (default 5). Lower this if you're having network issues.\n- `encryptionKey` - You only need to specify **one** of the following\n\t- `publicKeyPath` - The path to a PEM-encoded file contaning an RSA public key\n\t- `publicKey` - A PEM-encoded RSA public key\n\n# Encryption\n\nEach file is encrypted using `AES-256-CTR` with a per-file key. The symmetric key is RSA-encrypted and stored in the\nuploaded file alongside the encrypted data. The final 20 bytes of each uploaded file are a HMAC.\n\nFiles under 100 MB are streamed from disk, encrypted as a stream, and uploaded in a single part.\nFiles larger than 100 MB will be uploaded in chunks at most 50 MB in size.\n**Please note:** Due to the nature of multi-threaded encrypted uploads, each chunk in a large file must be loaded into\nmemory prior to being uploaded. Therefore, a large-file upload will consume at least `uploadThreads` × 50 MB. Please\ntake this into consideration on a device with limited RAM (e.g. a Raspberry Pi).\n\n# Decryption\n\nThere is no functionality implemented in B2ENS to download and decrypt files. You will need to download either an\nindividual file or some number of files and use either `decrypt-file` or `decrypt-folder` to decrypt them.\n\nIf you wanted to decrypt an entire bucket, you might want to either\n[create and download a bucket snapshot](https://help.backblaze.com/hc/en-us/articles/115002731014-Snapshot-information)\nor use the [B2 command line tool](https://www.backblaze.com/b2/docs/quick_command_line.html) to download your bucket\ncontents. Once downloaded, you can use the `decrypt-folder` command to decrypt the entire bucket's contents.\n\n**Please note that the `decrypt-folder` command will delete input files after they are successfully decrypted to the\noutput folder.** This is to prevent it being necessary to have enough free disk space to hold two copies of the files.\nAdditionally, this makes it apparent if any files were unable to be decrypted, since they will be all that's left in\nthe input folder after the process completes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoctormckay%2Fnode-b2ens","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoctormckay%2Fnode-b2ens","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoctormckay%2Fnode-b2ens/lists"}