├── LICENSE
├── README.md
├── deaddrop-page
├── deaddrop.js
├── fonts
│ ├── ceva-c2.ttf
│ └── ceva-c2.woff
├── images
│ └── stars.jpg
├── index.html
├── style
│ └── deaddrop.css
└── vendor
│ └── qrcode.min.js
├── qrcode-page
└── index.html
├── spec
└── fixtures
│ ├── empty.json
│ ├── error.json
│ ├── garbled.json
│ ├── progress-0.json
│ ├── progress-50.json
│ └── result.json
└── udev-script
├── dumpusb
├── dumpusb.py
└── rules.d
└── mount.rules
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Uwe Kamper
4 | Copyright (c) 2016 Henri Bergius
5 | Copyright (c) 2016 Smile
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IPFS Dead Drop
2 |
3 | This is the source code for an IPFS dead drop.
4 |
5 | The IPFS dead drop is a variant of the
6 | USB dead drop (see https://deaddrops.com/ for more information on USB dead drops).
7 |
8 | When you plug a USB memory into the device it will automatically access the memory
9 | stick and publish all the files on the web. It does so using the
10 | InterPlanetary File System (IPFS). Thanks to IPFS the files are instantly available
11 | to the whole world (see http://ipfs.io/ to find out more about IPFS).
12 |
13 | When the IPFS dead drop is finished uploading it opens a web page that displays a
14 | QR code that contains the IPFS address of your files. Just scan that and share the
15 | address with anyone.
16 |
17 |  
18 |
19 | ## How to use?
20 |
21 | * Bring a USB memory stick (FAT-formatted) with the file(s) you want to share and smartphone with a QR code scanner app.
22 | * Plug a USB memory stick into the dead drop host.
23 | * Wait ca. 5 seconds until the dead drop starts copying your files.
24 | * Wait until the whole process is complete. The QR code will be shown once it is completed.
25 | * Scan the QR code with your mobile and share the URL with your friends.
26 | * The QR code contains the content hash that you need to access your files using IPFS.
27 |
28 | ## Prerequisites
29 |
30 | * You need a Linux-device with udev
31 | * IPFS should be installed and your local system should be a IPFS node (e.g. you should be able to add files using `ipfs add ...`).
32 |
33 | ## How to install?
34 |
35 | * Copy the udev-rule-script to `/etc/udev/rules.d/mount.rules`
36 | * Reload your udev rules afterwards: `udevadm control --reload-rules`
37 | * Copy the dumper script to `/usr/local/bin/dumpusb` and edit it to configure to your needs.
38 | * Make sure the a copy of the QR code page is available by pinning it to your local IPFS node. Currently with `ipfs pin add QmUzER8RFyFMKfcE5WKcCWdK1pFXJMVKoCzeHEw2XWpibA`.
39 |
40 | ## Mirroring
41 |
42 | It is easy to set up a mirror of the dead drops using [ipfs-ringpin](https://github.com/c-base/ipfs-ringpin). The IPNS address for c-base's Siri is:
43 |
44 | ```
45 | /ipns/QmdCYibjHMinqnh7eWw8WEMsopi5CWz5yD2R86nYegL2Sr/pinlist/deaddrop
46 | ```
47 |
--------------------------------------------------------------------------------
/deaddrop-page/deaddrop.js:
--------------------------------------------------------------------------------
1 | var state = {
2 | view: 'welcome',
3 | url: 'http://siri.cbrp3.c-base.org/deaddrop.json',
4 | progress: {
5 | message: null,
6 | percent: 100,
7 | qrcode: null
8 | }
9 | };
10 |
11 | var drawQr = function (size, element, address) {
12 | element.innerHTML = '';
13 | var qrcode = new QRCode(element.id, {
14 | width: size,
15 | height: size
16 | });
17 | qrcode.makeCode(address);
18 | };
19 |
20 | var renderQr = function () {
21 | var size = window.innerHeight * 0.5;
22 | var qrcodeEl = document.getElementById('qrcode')
23 | drawQr(size, qrcodeEl, state.progress.qrcode);
24 | qrcodeEl.style.width = size + 'px';
25 | qrcodeEl.style.height = size + 'px';
26 |
27 | qrcodeEl.addEventListener('click', function () {
28 | window.location.href = state.progress.qrcode;
29 | });
30 | var parts = state.progress.qrcode.split('/ipfs/');
31 | if (parts.length == 1) {
32 | var qrString = state.progress.qrcode;
33 | } else {
34 | var qrString = parts[0] + '/ipfs/ ' + parts[1];
35 | }
36 | document.getElementById('address').innerHTML = qrString;
37 | };
38 |
39 | var renderProgress = function () {
40 | var statusEl = document.getElementById('status');
41 | statusEl.value = state.progress.percent;
42 | };
43 |
44 | var determineView = function () {
45 | if (state.progress.changed) {
46 | var changedDate = new Date(state.progress.changed);
47 | var now = new Date();
48 | var elapsed = now.getTime() - changedDate.getTime();
49 | if (elapsed > 4 * 60 * 1000) {
50 | state.progress.qrcode = null;
51 | state.progress.message = '';
52 | }
53 | }
54 |
55 | if (state.progress.qrcode) {
56 | state.view = 'result';
57 | return;
58 | }
59 | if (state.progress.percent === 100) {
60 | state.view = 'welcome';
61 | return;
62 | }
63 | state.view = 'progress';
64 | };
65 |
66 | var render = function () {
67 | var welcomeEl = document.getElementById('welcome');
68 | var progressEl = document.getElementById('progress');
69 | var resultEl = document.getElementById('result');
70 |
71 | switch (state.view) {
72 | case 'welcome':
73 | progressEl.style.display = 'none';
74 | resultEl.style.display = 'none';
75 | welcomeEl.style.display = 'block';
76 | break;
77 | case 'progress':
78 | state.lastShown = null;
79 | resultEl.style.display = 'none';
80 | welcomeEl.style.display = 'none';
81 | progressEl.style.display = 'block'
82 | renderProgress();
83 | break;
84 | case 'result':
85 | progressEl.style.display = 'none'
86 | welcomeEl.style.display = 'none';
87 | resultEl.style.display = 'block';
88 | renderQr();
89 | break;
90 | }
91 | var messageEl = document.getElementById('message');
92 | messageEl.innerHTML = state.progress.message;
93 | document.body.className = state.view;
94 | };
95 |
96 | var address = 'http://siri.cbrp3.c-base.org/deaddrop.json';
97 | if (window.location.search) {
98 | address = window.location.search.substr(1);
99 | }
100 | state.url = address;
101 |
102 | document.addEventListener('DOMContentLoaded', function () {
103 | render();
104 | setInterval(function () {
105 | fetchState();
106 | }, 1000);
107 | fetchState();
108 | });
109 | window.addEventListener('resize', function () {
110 | render();
111 | });
112 |
113 | var fetchState = function () {
114 | var req = new XMLHttpRequest;
115 | req.open('GET', state.url, true);
116 | req.onload = function() {
117 | if (req.readyState !== 4) {
118 | return;
119 | }
120 | if (req.status === 200) {
121 | try {
122 | state.progress = JSON.parse(req.responseText);
123 | } catch (e) {
124 | state.progress.message = "Error parsing server file";
125 | }
126 | determineView();
127 | render();
128 | }
129 | };
130 | req.send(null);
131 | };
132 |
--------------------------------------------------------------------------------
/deaddrop-page/fonts/ceva-c2.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c-base/ipfs-deaddrop/74309d0c22a655f153128f063d4e8a2fd3772e07/deaddrop-page/fonts/ceva-c2.ttf
--------------------------------------------------------------------------------
/deaddrop-page/fonts/ceva-c2.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c-base/ipfs-deaddrop/74309d0c22a655f153128f063d4e8a2fd3772e07/deaddrop-page/fonts/ceva-c2.woff
--------------------------------------------------------------------------------
/deaddrop-page/images/stars.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/c-base/ipfs-deaddrop/74309d0c22a655f153128f063d4e8a2fd3772e07/deaddrop-page/images/stars.jpg
--------------------------------------------------------------------------------
/deaddrop-page/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | USB Dead Drop
6 |
7 |
8 |
9 |
10 |
11 |
12 |
USB Dead Drop
13 |
14 |
15 |
16 | This is a USB Dead Drop web publishing system that can publish the contents of a USB thumbdrive to the Interplanetary Filesystem, a peer-to-peer internet filesystem aiming to serve the permanent web.
17 |
18 |
19 | Once the contents of your USB thumbdrive have been uploaded to the IPFS network, you will receive a permanent, public URL to them.
20 |