braidfs 0.0.121 → 0.0.123
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +91 -28
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -133,11 +133,6 @@ async function main() {
|
|
|
133
133
|
|
|
134
134
|
if (req.url === '/favicon.ico') return
|
|
135
135
|
|
|
136
|
-
if (!['::ffff:127.0.0.1', '127.0.0.1', '::1'].includes(req.socket.remoteAddress)) {
|
|
137
|
-
res.writeHead(403, { 'Content-Type': 'text/plain' })
|
|
138
|
-
return res.end('Access denied: only accessible from localhost')
|
|
139
|
-
}
|
|
140
|
-
|
|
141
136
|
// Free the CORS
|
|
142
137
|
free_the_cors(req, res)
|
|
143
138
|
if (req.method === 'OPTIONS') return
|
|
@@ -200,7 +195,7 @@ async function main() {
|
|
|
200
195
|
res.writeHead(500, { 'Error-Message': '' + e })
|
|
201
196
|
res.end('' + e)
|
|
202
197
|
}
|
|
203
|
-
}).listen(config.port, () => {
|
|
198
|
+
}).listen(config.port, 'localhost', () => {
|
|
204
199
|
console.log(`daemon started on port ${config.port}`)
|
|
205
200
|
console.log('!! only accessible from localhost !!')
|
|
206
201
|
|
|
@@ -476,6 +471,20 @@ async function sync_url(url) {
|
|
|
476
471
|
|
|
477
472
|
if (!self.peer) self.peer = Math.random().toString(36).slice(2)
|
|
478
473
|
|
|
474
|
+
// create file if it doesn't exist
|
|
475
|
+
var fullpath = await get_fullpath()
|
|
476
|
+
if (freed) return
|
|
477
|
+
if (!(await file_exists(fullpath))) {
|
|
478
|
+
if (freed) return
|
|
479
|
+
await wait_on(require('fs').promises.writeFile(fullpath, ''))
|
|
480
|
+
if (freed) return
|
|
481
|
+
var stat = await require('fs').promises.stat(fullpath, { bigint: true })
|
|
482
|
+
if (freed) return
|
|
483
|
+
self.file_mtimeNs_str = '' + stat.mtimeNs
|
|
484
|
+
self.last_touch = Date.now()
|
|
485
|
+
}
|
|
486
|
+
if (freed) return
|
|
487
|
+
|
|
479
488
|
await save_meta()
|
|
480
489
|
})
|
|
481
490
|
if (freed) return
|
|
@@ -531,7 +540,7 @@ async function sync_url(url) {
|
|
|
531
540
|
subscribe: true,
|
|
532
541
|
heartbeats: 120,
|
|
533
542
|
peer: self.peer,
|
|
534
|
-
|
|
543
|
+
parents: self.version != null ? ['' + self.version] : []
|
|
535
544
|
})
|
|
536
545
|
if (freed || closed) return
|
|
537
546
|
|
|
@@ -540,7 +549,16 @@ async function sync_url(url) {
|
|
|
540
549
|
if (res.status !== 209)
|
|
541
550
|
return log_error(`Can't sync ${url} -- got bad response ${res.status} from server (expected 209)`)
|
|
542
551
|
|
|
543
|
-
|
|
552
|
+
self.file_read_only = res.headers.get('editable') === 'false'
|
|
553
|
+
|
|
554
|
+
await wait_on(within_fiber(url, async () => {
|
|
555
|
+
var fullpath = await get_fullpath()
|
|
556
|
+
if (freed || closed) return
|
|
557
|
+
|
|
558
|
+
await set_read_only(fullpath, self.file_read_only)
|
|
559
|
+
}))
|
|
560
|
+
|
|
561
|
+
console.log(`connected to ${url}${self.file_read_only ? ' (readonly)' : ''}`)
|
|
544
562
|
|
|
545
563
|
reconnect_rate_limiter.on_conn(url)
|
|
546
564
|
|
|
@@ -559,8 +577,12 @@ async function sync_url(url) {
|
|
|
559
577
|
var fullpath = await get_fullpath()
|
|
560
578
|
if (freed || closed) return
|
|
561
579
|
|
|
580
|
+
await wait_on(set_read_only(fullpath, false))
|
|
581
|
+
if (freed || closed) return
|
|
562
582
|
await wait_on(require('fs').promises.writeFile(fullpath, update.body))
|
|
563
583
|
if (freed || closed) return
|
|
584
|
+
await wait_on(set_read_only(fullpath, self.file_read_only))
|
|
585
|
+
if (freed || closed) return
|
|
564
586
|
|
|
565
587
|
var stat = await require('fs').promises.stat(fullpath, { bigint: true })
|
|
566
588
|
if (freed || closed) return
|
|
@@ -571,6 +593,55 @@ async function sync_url(url) {
|
|
|
571
593
|
})
|
|
572
594
|
}, retry)
|
|
573
595
|
|
|
596
|
+
async function send_file(fullpath) {
|
|
597
|
+
var body = await require('fs').promises.readFile(fullpath)
|
|
598
|
+
if (freed || closed) return
|
|
599
|
+
|
|
600
|
+
try {
|
|
601
|
+
var a = new AbortController()
|
|
602
|
+
aborts.add(a)
|
|
603
|
+
var r = await braid_fetch(url, {
|
|
604
|
+
method: 'PUT',
|
|
605
|
+
signal: a.signal,
|
|
606
|
+
version: ['' + self.version],
|
|
607
|
+
body,
|
|
608
|
+
headers: {
|
|
609
|
+
...(x => x && {Cookie: x})(config.cookies?.[new URL(url).hostname])
|
|
610
|
+
},
|
|
611
|
+
})
|
|
612
|
+
if (freed || closed) return
|
|
613
|
+
|
|
614
|
+
// if we're not authorized,
|
|
615
|
+
if (r.status == 401 || r.status == 403) {
|
|
616
|
+
// then revert it
|
|
617
|
+
console.log(`access denied: reverting local edits`)
|
|
618
|
+
unsync_url(url)
|
|
619
|
+
sync_url(url)
|
|
620
|
+
} else if (!r.ok) {
|
|
621
|
+
retry(new Error(`unexpected PUT status: ${r.status}`))
|
|
622
|
+
}
|
|
623
|
+
} catch (e) { retry(e) }
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// if what we have now is newer than what the server has,
|
|
627
|
+
// go ahead and send it
|
|
628
|
+
await within_fiber(url, async () => {
|
|
629
|
+
if (freed || closed) return
|
|
630
|
+
var fullpath = await get_fullpath()
|
|
631
|
+
if (freed || closed) return
|
|
632
|
+
try {
|
|
633
|
+
var stat = await require('fs').promises.stat(fullpath, { bigint: true })
|
|
634
|
+
} catch (e) { return }
|
|
635
|
+
if (freed || closed) return
|
|
636
|
+
|
|
637
|
+
var server_v = JSON.parse(`[${res.headers.get('current-version')}]`)
|
|
638
|
+
if (self.version != null &&
|
|
639
|
+
'' + stat.mtimeNs === self.file_mtimeNs_str && (
|
|
640
|
+
!server_v.length ||
|
|
641
|
+
1*server_v[0] < self.version
|
|
642
|
+
)) await send_file(fullpath)
|
|
643
|
+
})
|
|
644
|
+
|
|
574
645
|
self.signal_file_needs_reading = () => {
|
|
575
646
|
within_fiber(url, async () => {
|
|
576
647
|
if (freed || closed) return
|
|
@@ -591,22 +662,7 @@ async function sync_url(url) {
|
|
|
591
662
|
self.last_touch = Date.now()
|
|
592
663
|
|
|
593
664
|
await save_meta()
|
|
594
|
-
|
|
595
|
-
var body = await require('fs').promises.readFile(fullpath)
|
|
596
|
-
if (freed || closed) return
|
|
597
|
-
|
|
598
|
-
var a = new AbortController()
|
|
599
|
-
aborts.add(a)
|
|
600
|
-
|
|
601
|
-
await braid_fetch(url, {
|
|
602
|
-
method: 'PUT',
|
|
603
|
-
signal: a.signal,
|
|
604
|
-
version: ['' + self.version],
|
|
605
|
-
body,
|
|
606
|
-
headers: {
|
|
607
|
-
...(x => x && {Cookie: x})(config.cookies?.[new URL(url).hostname])
|
|
608
|
-
},
|
|
609
|
-
})
|
|
665
|
+
await send_file(fullpath)
|
|
610
666
|
}
|
|
611
667
|
})
|
|
612
668
|
}
|
|
@@ -1107,12 +1163,12 @@ async function sync_url(url) {
|
|
|
1107
1163
|
if (res.status !== 209)
|
|
1108
1164
|
return log_error(`Can't sync ${url} -- got bad response ${res.status} from server (expected 209)`)
|
|
1109
1165
|
|
|
1110
|
-
console.log(`connected to ${url}${res.headers.get('editable') !== 'true' ? ' (readonly)' : ''}`)
|
|
1111
|
-
|
|
1112
1166
|
reconnect_rate_limiter.on_conn(url)
|
|
1113
1167
|
|
|
1114
1168
|
self.file_read_only = res.headers.get('editable') === 'false'
|
|
1115
1169
|
self.signal_file_needs_writing()
|
|
1170
|
+
|
|
1171
|
+
console.log(`connected to ${url}${self.file_read_only ? ' (readonly)' : ''}`)
|
|
1116
1172
|
|
|
1117
1173
|
initial_connect_done()
|
|
1118
1174
|
res.subscribe(async update => {
|
|
@@ -1528,8 +1584,15 @@ async function set_read_only(fullpath, read_only) {
|
|
|
1528
1584
|
})
|
|
1529
1585
|
} else {
|
|
1530
1586
|
let mode = (await require('fs').promises.stat(fullpath)).mode
|
|
1531
|
-
|
|
1532
|
-
|
|
1587
|
+
|
|
1588
|
+
// Check if chmod is actually needed
|
|
1589
|
+
if (read_only && (mode & 0o222) === 0) return
|
|
1590
|
+
if (!read_only && (mode & 0o200) !== 0) return
|
|
1591
|
+
|
|
1592
|
+
// Perform chmod only if necessary
|
|
1593
|
+
if (read_only) mode &= ~0o222 // Remove all write permissions
|
|
1594
|
+
else mode |= 0o200 // Add owner write permission
|
|
1595
|
+
|
|
1533
1596
|
await require('fs').promises.chmod(fullpath, mode)
|
|
1534
1597
|
}
|
|
1535
1598
|
}
|