nodio-cli 1.1.0 → 1.1.1
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/package.json +1 -1
- package/src/server/index.js +1 -1
- package/src/server/routes.js +44 -0
- package/src/user/commands.js +19 -35
package/package.json
CHANGED
package/src/server/index.js
CHANGED
|
@@ -35,7 +35,7 @@ async function startServer() {
|
|
|
35
35
|
|
|
36
36
|
app.use(cors(corsOptions));
|
|
37
37
|
app.options(/.*/, cors(corsOptions));
|
|
38
|
-
app.use(express.json({ limit: '
|
|
38
|
+
app.use(express.json({ limit: '50mb' }));
|
|
39
39
|
app.use('/api', buildRoutes(config));
|
|
40
40
|
|
|
41
41
|
app.use((error, _req, res, _next) => {
|
package/src/server/routes.js
CHANGED
|
@@ -9,6 +9,7 @@ const {
|
|
|
9
9
|
ReplicationTaskModel,
|
|
10
10
|
RelayTaskModel
|
|
11
11
|
} = require('./models');
|
|
12
|
+
const { uploadToFilecoin } = require('../../services/filecoin');
|
|
12
13
|
const {
|
|
13
14
|
chooseDistinctOnlineNodes,
|
|
14
15
|
ensureEmergencyReplicasForShard
|
|
@@ -574,6 +575,49 @@ function buildRoutes(config) {
|
|
|
574
575
|
}
|
|
575
576
|
});
|
|
576
577
|
|
|
578
|
+
router.post('/files/:fileId/filecoin/upload', async (req, res, next) => {
|
|
579
|
+
try {
|
|
580
|
+
const { fileId } = req.params;
|
|
581
|
+
const { dataBase64 } = req.body;
|
|
582
|
+
|
|
583
|
+
if (!fileId) {
|
|
584
|
+
return res.status(400).json({ error: 'fileId is required' });
|
|
585
|
+
}
|
|
586
|
+
if (!dataBase64 || typeof dataBase64 !== 'string') {
|
|
587
|
+
return res.status(400).json({ error: 'dataBase64 is required' });
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
const payload = Buffer.from(dataBase64, 'base64');
|
|
591
|
+
if (!payload || payload.length === 0) {
|
|
592
|
+
return res.status(400).json({ error: 'dataBase64 decoded to empty payload' });
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
const cid = await uploadToFilecoin(payload, fileId);
|
|
596
|
+
if (!cid) {
|
|
597
|
+
return res.status(502).json({ error: 'filecoin upload failed' });
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
const file = await FileModel.findOneAndUpdate(
|
|
601
|
+
{ fileId },
|
|
602
|
+
{
|
|
603
|
+
$set: {
|
|
604
|
+
filecoinCid: cid,
|
|
605
|
+
filecoinBackedUp: true
|
|
606
|
+
}
|
|
607
|
+
},
|
|
608
|
+
{ new: true }
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
if (!file) {
|
|
612
|
+
return res.status(404).json({ error: 'file not found' });
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
res.json({ ok: true, fileId: file.fileId, filecoinCid: cid });
|
|
616
|
+
} catch (error) {
|
|
617
|
+
next(error);
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
|
|
577
621
|
router.post('/shards/register', async (req, res, next) => {
|
|
578
622
|
try {
|
|
579
623
|
const { shardId, fileId, order, sizeBytes, checksum, nodeIds } = req.body;
|
package/src/user/commands.js
CHANGED
|
@@ -5,7 +5,7 @@ const axios = require('axios');
|
|
|
5
5
|
const { v4: uuidv4 } = require('uuid');
|
|
6
6
|
const { createApiClient, normalizeUrl } = require('./client');
|
|
7
7
|
const { encryptAes256Gcm, decryptAes256Gcm, sha256Hex } = require('../common/crypto');
|
|
8
|
-
const {
|
|
8
|
+
const { retrieveFromFilecoin } = require('../../services/filecoin');
|
|
9
9
|
|
|
10
10
|
function splitBuffer(buffer, shardSizeBytes) {
|
|
11
11
|
if (shardSizeBytes <= 0) {
|
|
@@ -88,27 +88,25 @@ function decryptShardsFromBuffers(orderedShards, shardMetaMap, encryptedShardBuf
|
|
|
88
88
|
return Buffer.concat(plainParts);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
function
|
|
91
|
+
async function requestFilecoinBackup(api, fileBuffer, fileId) {
|
|
92
92
|
if (!fileBuffer || fileBuffer.length === 0) {
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
})();
|
|
96
|
+
try {
|
|
97
|
+
await api.post(
|
|
98
|
+
`/files/${fileId}/filecoin/upload`,
|
|
99
|
+
{
|
|
100
|
+
dataBase64: fileBuffer.toString('base64')
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
timeout: 180000
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
const message = error.response?.data?.error || error.message;
|
|
108
|
+
console.warn(`[filecoin] server upload failed for ${fileId}: ${message}`);
|
|
109
|
+
}
|
|
112
110
|
}
|
|
113
111
|
|
|
114
112
|
function fireAndForgetLayer1Reseed(api, fileId, orderedShards, encryptedShardBuffers, directTimeoutMs) {
|
|
@@ -427,24 +425,10 @@ async function uploadFile(options) {
|
|
|
427
425
|
}
|
|
428
426
|
});
|
|
429
427
|
|
|
430
|
-
// Upload to Filecoin
|
|
428
|
+
// Upload to Filecoin via the central server (uses server-side wallet key)
|
|
431
429
|
const encryptedFileBuffer = Buffer.concat(encryptedShardBuffers);
|
|
432
|
-
console.log(`[filecoin] uploading to Filecoin (this may take a while)...`);
|
|
433
|
-
|
|
434
|
-
if (filecoinCid) {
|
|
435
|
-
try {
|
|
436
|
-
await api.post(`/files/${fileId}/filecoin`, {
|
|
437
|
-
filecoinCid,
|
|
438
|
-
filecoinBackedUp: true
|
|
439
|
-
});
|
|
440
|
-
console.log(`[filecoin] backup complete, cid: ${filecoinCid}`);
|
|
441
|
-
} catch (error) {
|
|
442
|
-
const message = error.response?.data?.error || error.message;
|
|
443
|
-
console.warn(`[filecoin] warning: failed to persist cid: ${message}`);
|
|
444
|
-
}
|
|
445
|
-
} else {
|
|
446
|
-
console.warn(`[filecoin] warning: upload to Filecoin failed, file backed up to Layer 1 only`);
|
|
447
|
-
}
|
|
430
|
+
console.log(`[filecoin] uploading to Filecoin via central server (this may take a while)...`);
|
|
431
|
+
await requestFilecoinBackup(api, encryptedFileBuffer, fileId);
|
|
448
432
|
|
|
449
433
|
console.log(`Upload complete`);
|
|
450
434
|
console.log(`fileId: ${fileId}`);
|