npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

secure-file-transfer

v0.0.8

Published

A library to encrypt and transfer files P2P in the browser

Downloads

309

Readme

secure-file-transfer

API documentation

Install

npm i --save secure-file-transfer

secure-file-transfer (SFT) is the easiest solution for securely getting a file from one web browser to another. It works by connecting two people via WebTorrent and transferring files peer-to-peer via WebRTC. Files are encrypted prior to transmission and decrypted upon receipt, so data is never exposed to anyone other than the intended recipient. Files are never sent to a server, and no server setup is needed to use SFT.

SFT is the library that Chitchatter uses to transfer files to connected peers.

Why use secure-file-transfer?

SFT builds on top of WebTorrent and several other excellent JavaScript libraries. It is specially tuned to minimize memory usage, thus enabling the delivery of very large files (as much as your browser can handle).

WebTorrent is a powerful library, but there are a number of important things it doesn't do:

  • File encryption
    • This is critical when using public WebTorrent trackers. Without encryption, anyone with access to the tracker could intercept files being transferred between peers. Short of running your own private tracker, encrypting data prior to sending it is the best way to ensure that only the intended party can access transferred file. SFT uses wormhole-crypto to do this automatically.
  • File saving
    • This functionality is left up to WebTorrent users to implement. The most straightforward solution for closing this gap is FileSaver.js. However, FileSaver.js has limited file size support. A more scalable solution is to stream data to disk, which SFT uses StreamSaver.js to do automatically.

By default, WebTorrent stores torrents in system memory. This is also not suitable for very large files. To work around this, SFT uses idb-chunk-store to stream data directly from the sender's disk to the receiver's and keep memory usage low.

Limitations

SFT has no file size limits. However, since transferred data is cached in IndexedDB via idb-chunk-store (to minimize memory usage and enable larger file transfers), it is subject to browser storage limits.

Example

On one page have, something like this (in TypeScript):

import { fileTransfer } from "secure-file-transfer";

document.body.innerHTML = `
<input type="text" placeholder="Encryption key" />
<input type="file" multiple />
<h1>Magnet URI:</h1>
<p />
`;

const fileInput = document.querySelector('[type="file"]');
const passwordInput = document.querySelector('[type="text"]');
const p = document.querySelector("p");

const handleChange = async (evt: Event) => {
  const password = passwordInput.value;
  const magnetURI = await fileTransfer.offer(evt.target.files, password);
  p.innerText = magnetURI;
};

fileInput?.addEventListener("change", handleChange);

Then on another page, something like this:

import { fileTransfer } from "secure-file-transfer";

document.body.innerHTML = `
<input type="text" placeholder="Encryption key" style="display: block;" />
<textarea placeholder="Magnet URI"></textarea>
<button style="display: block;">Download file(s)</button>
<p></p>
`;

const downloadButton = document.querySelector("button");
const passwordInput = document.querySelector('[type="text"]');
const magnetUriInput = document.querySelector("textarea");
const status = document.querySelector("p");

const handleDownloadClick = async (evt: Event) => {
  status?.innerText = "Downloading...";
  const password = passwordInput.value;
  const magnetUri = magnetUriInput.value;
  await fileTransfer.download(magnetUri, password, { doSave: true });
  status?.innerText = "Done!";
};

downloadButton.addEventListener("click", handleDownloadClick);

If the encryption keys match, the file will be transferred directly from the offerer to the receiver and saved to the local file system (so long as both peers keep their pages open).

License

MIT.