Skip to content

Commit 78903df

Browse files
authored
Merge pull request #29 from nexus-uw/share_target
share target - moved service worker script to root dir so that fetch events would be caught - lazily copied page code into sw - imp note saved page
2 parents 9c65096 + f7dc3b3 commit 78903df

11 files changed

Lines changed: 190 additions & 7 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
node_modules
44
public/*
55
main
6-
assets
6+
assets/*
7+
!assets/manifest.json
78
database
89
mokintoken

assets/manifest.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "mokintoken",
3+
"icons": [],
4+
"start_url": "/",
5+
"display": "standalone",
6+
"theme_color": "#000000",
7+
"background_color": "#ffffff",
8+
"serviceworker": {
9+
"src": "/service-worker.js"
10+
},
11+
"share_target": {
12+
"action": "/share-target/",
13+
"method": "POST",
14+
"enctype": "multipart/form-data",
15+
"params": {
16+
"text": "text"
17+
}
18+
}
19+
}

mokintoken.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,12 @@ func cleanUpDb(db *sql.DB) {
235235
}
236236
}
237237

238+
func serveSingle(pattern string, filename string) {
239+
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
240+
http.ServeFile(w, r, filename)
241+
})
242+
}
243+
238244
func main() {
239245

240246
db, err := sql.Open("sqlite3", "./database/mokintoken.sqlite")
@@ -249,12 +255,16 @@ func main() {
249255

250256
http.HandleFunc("/", userViews("home"))
251257
http.HandleFunc("/about", userViews("about"))
258+
http.HandleFunc("/noteSaved", userViews("noteSaved"))
252259
http.HandleFunc("/decrypt/", decryptHandler(db))
253260
http.HandleFunc("/api/save-note", saveNoteHandler(db))
254261
http.HandleFunc("/ping", ping(db))
255262
// this should be handled by a cdn
256263
http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets"))))
257264

265+
serveSingle("/service-worker.js", "./assets/service-worker.js")
266+
267+
258268
port := os.Getenv("PORT")
259269
if port == "" {
260270
port = "8080"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
},
1010
"scripts": {
1111
"test": "echo \"Error: no test specified\" && exit 1",
12-
"build": "rollup --config && cp node_modules/tachyons/css/tachyons.min.css assets",
12+
"build": "rollup --config && rollup --config rollup-serviceworker.config.js && cp node_modules/tachyons/css/tachyons.min.css assets",
1313
"dev": "rollup --config -w"
1414
},
1515
"author": "",

resources/js/index.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,33 @@ async function main() {
88
const { Decrypt } = await import('./decrypt')
99
new Decrypt()
1010
}
11+
12+
if (location.pathname.startsWith('/noteSaved')) {
13+
const { NoteSaved } = await import('./noteSaved')
14+
new NoteSaved()
15+
}
1116
}
1217
main()
18+
19+
const registerServiceWorker = async () => {
20+
if ("serviceWorker" in navigator) {
21+
try {
22+
const registration = await navigator.serviceWorker.register("/service-worker.js", {
23+
scope: "/",
24+
})
25+
if (registration.installing) {
26+
console.log("Service worker installing")
27+
} else if (registration.waiting) {
28+
console.log("Service worker installed")
29+
} else if (registration.active) {
30+
console.log("Service worker active")
31+
}
32+
} catch (error) {
33+
console.error(`Registration failed with ${error}`)
34+
}
35+
}
36+
}
37+
if (window.matchMedia('(display-mode: standalone)').matches) {
38+
registerServiceWorker()
39+
}
40+

resources/js/noteSaved.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import QRCode from 'qrcode'
2+
3+
4+
export class NoteSaved {
5+
6+
constructor() {
7+
const hash = window.location.hash.slice(1)
8+
const id = new URLSearchParams(window.location.search).get('id')
9+
10+
const clearnetShareLink = `${document.querySelector('meta[name="clearnet"]').getAttribute('content')}/decrypt/${id}#${hash}`
11+
document.getElementById('clearnetShareLink').href = clearnetShareLink
12+
13+
const dakrnetShareLink = `${document.querySelector('meta[name="darknet"]').getAttribute('content')}/decrypt/${id}#${hash}`
14+
document.getElementById('dakrnetShareLink').href = dakrnetShareLink
15+
16+
Promise.all([
17+
QRCode.toCanvas(document.getElementById('clearnetShareQR'), clearnetShareLink),
18+
QRCode.toCanvas(document.getElementById('darknetShareQR'), dakrnetShareLink)
19+
])
20+
}
21+
}

resources/js/service-worker.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import nacl from 'tweetnacl'
2+
import naclUutil from 'tweetnacl-util'
3+
import { Base64 } from 'js-base64'
4+
5+
console.log("ass " + nacl + naclUutil + Base64)
6+
// https://stackoverflow.com/questions/51562781/service-worker-fetch-event-is-not-firing
7+
self.addEventListener('activate', function (event) {
8+
console.log('Claiming control')
9+
return self.clients.claim()
10+
})
11+
self.addEventListener("fetch", (event) => {
12+
13+
// Regular requests not related to Web Share Target.
14+
if (event.request.method !== "POST" || new URL(event.request.url).pathname != "/share-target/") {
15+
event.respondWith(fetch(event.request))
16+
return
17+
}
18+
19+
// Requests related to Web Share Target.
20+
event.respondWith(
21+
(async () => {
22+
23+
const formData = await event.request.formData()
24+
const nonce = nacl.randomBytes(nacl.secretbox.nonceLength)
25+
const key = nacl.randomBytes(nacl.secretbox.keyLength)
26+
// encrypt note or image
27+
// send to fetch api
28+
const imgBase64 = null // todo - base64
29+
const f = await fetch('/api/save-note', {
30+
method: 'POST',
31+
headers: {
32+
'Content-Type': 'application/json'
33+
},
34+
body: JSON.stringify({
35+
encryptedText: naclUutil.encodeBase64(
36+
nacl.secretbox(
37+
naclUutil.decodeUTF8(formData.get('text')),
38+
nonce,
39+
key
40+
)
41+
),
42+
encryptedImg: imgBase64 != null ? naclUutil.encodeBase64(
43+
nacl.secretbox(
44+
naclUutil.decodeUTF8(imgBase64),
45+
nonce,
46+
key
47+
)
48+
) : null,
49+
// code is hard
50+
expiresHours: "4",
51+
expiresViews: "1"
52+
})
53+
})
54+
const { id } = await f.json()
55+
56+
const hash = Base64.encode(
57+
JSON.stringify({
58+
nonce: naclUutil.encodeBase64(nonce),
59+
key: naclUutil.encodeBase64(key)
60+
})
61+
)
62+
// respond with saved note page
63+
return Response.redirect(`/noteSaved?id=${id}#${hash}`, 303)
64+
})(),
65+
)
66+
})

resources/js/welcome.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ async function getImgBase64(ele) {
1717

1818
export class Welcome {
1919
loadNonceAndKey() {
20-
window.location.hash = '' // clear out old key
20+
//window.location.hash = '' // clear out old key
2121
// always generate new nonce
2222
const nonce = nacl.randomBytes(nacl.secretbox.nonceLength)
2323
const key = nacl.randomBytes(nacl.secretbox.keyLength)
@@ -38,7 +38,7 @@ export class Welcome {
3838
try {
3939

4040
const imgBase64 = await getImgBase64(document.getElementById('img'))
41-
41+
// maybe refactor this with service worker code
4242
const f = await fetch('/api/save-note', {
4343
method: 'POST',
4444
headers: {

rollup-serviceworker.config.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import commonjs from '@rollup/plugin-commonjs'
2+
import resolve from '@rollup/plugin-node-resolve'
3+
import builtins from 'rollup-plugin-node-builtins'
4+
import globals from 'rollup-plugin-node-globals'
5+
module.exports = {
6+
input: 'resources/js/service-worker.js',
7+
output: {
8+
dir: 'assets'
9+
},
10+
plugins: [
11+
commonjs(),
12+
resolve({
13+
browser: true,
14+
preferBuiltins: false
15+
}),
16+
builtins(),
17+
globals()
18+
]
19+
}

views/noteSaved.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{{define "content"}}
2+
3+
<main>
4+
<div id="" class="tc">
5+
<h1>note successfully encrypted and ready to share</h1>
6+
<h4>either share <a id="clearnetShareLink" target="_blank" style="margin-right: 7px;">this link</a></h4>
7+
<div class="db"> <canvas id="clearnetShareQR" style="display:block; margin: auto;"></canvas></div>
8+
<h5>or this QR code</h5>
9+
<hr />
10+
<h4>For hidden service access <a id="dakrnetShareLink" target="_blank" style="margin-right: 7px;">link</a></h4>
11+
<div class="db"> <canvas id="darknetShareQR" style="display:block; margin: auto;"></canvas></div>
12+
13+
</div>
14+
</main>
15+
{{end}}

0 commit comments

Comments
 (0)