Skip to content

Commit 8fa5441

Browse files
authored
Merge pull request #133 from lighthouse-web3/v0.4.1
V0.4.1
2 parents a0aa21d + 47ed424 commit 8fa5441

File tree

12 files changed

+345
-194
lines changed

12 files changed

+345
-194
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Lighthouse <img src="https://img.shields.io/badge/v0.4.0-green"/>
1+
# Lighthouse <img src="https://img.shields.io/badge/v0.4.1-green"/>
22

33
Lighthouse is a permanent decentralized file storage protocol that allows the ability to pay once and store forever. While traditionally, users need to repeatedly keep track and pay for their storage after every fixed amount of time, Lighthouse manages this for them and makes sure that user files are stored forever. The aim is to move users from a rent-based cost model where they are renting their own files on cloud storage to a permanent ownership model. It is built on top of IPFS, Filecoin, and Polygon. It uses the existing miner network and storage capacity of the filecoin network.
44

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lighthouse-web3/sdk",
3-
"version": "0.4.0",
3+
"version": "0.4.1",
44
"description": "NPM package and CLI tool to interact with lighthouse protocol",
55
"main": "./dist/Lighthouse/index.js",
66
"types": "./dist/Lighthouse/index.d.ts",

src/Commands/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Command.prototype.helpInformation = function (context: any) {
7171
}
7272

7373
widgets.addHelpText('before', 'Welcome to lighthouse-web3')
74-
widgets.version('0.4.0')
74+
widgets.version('0.4.1')
7575

7676
widgets
7777
.command('wallet')

src/Lighthouse/encryption/applyAccessCondition.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,14 @@ export default async (
2626
chainType
2727
)
2828

29-
if (error) {
30-
throw error
29+
if (!isSuccess || error) {
30+
const errorMessage =
31+
typeof error === 'string'
32+
? error
33+
: error instanceof Error
34+
? error.message
35+
: JSON.stringify(error)
36+
throw new Error(errorMessage)
3137
}
3238
return { data: { cid: cid, status: 'Success' } }
3339
}

src/Lighthouse/tests/encryption.test.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const signAuthMessage = async (privateKey: string) => {
1313
describe('encryption', () => {
1414
describe('getAuthMessage', () => {
1515
it('should get auth message when valid public key is provided', async () => {
16-
console.log('testing getAuthMessage')
1716
const response = await lighthouse.getAuthMessage(
1817
'0x1Ec09D4B3Cb565b7CCe2eEAf71CC90c9b46c5c26'
1918
)
@@ -24,7 +23,6 @@ describe('encryption', () => {
2423

2524
it('should not get auth message when invalid public key is provided', async () => {
2625
try {
27-
console.log('testing getAuthMessage with invalid public key')
2826
const response = await lighthouse.getAuthMessage('invalidPublicKey')
2927
} catch (error) {
3028
expect(error.message).toBe('Invalid public Key')
@@ -38,7 +36,6 @@ describe('encryption', () => {
3836
const cid = 'QmVkHgHnYVUfvTXsaJisHRgc89zsrgVL6ATh9mSiegRYrX'
3937

4038
it('should fetch encryption key when correct public-private key pair is provided', async () => {
41-
console.log('testing fetchEncryptionKey')
4239
const signed_message = await signAuthMessage(privateKey)
4340
const response = await lighthouse.fetchEncryptionKey(
4441
cid,
@@ -50,7 +47,6 @@ describe('encryption', () => {
5047

5148
it('should not fetch encryption key when incorrect public-private key pair is provided', async () => {
5249
try {
53-
console.log('testing fetchEncryptionKey with incorrect key pair')
5450
const randomPublicKey = '0x1ccEF158Dcbe6643F1cC577F236af79993F4D066'
5551
const signed_message = await signAuthMessage(privateKey)
5652
const response = await lighthouse.fetchEncryptionKey(
@@ -122,7 +118,7 @@ describe('encryption', () => {
122118
signed_message
123119
)
124120
} catch (error) {
125-
expect(error.message.message.message).toEqual('access denied')
121+
expect(error.message[0].message.message).toEqual('access denied')
126122
}
127123
}, 10000)
128124
})

src/Lighthouse/tests/upload.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe('uploadFiles', () => {
5353
)
5454
await lighthouse.upload(path, 'random apiKey')
5555
} catch (error) {
56-
expect(error.message).toBe('Error: Authentication failed')
56+
expect(error.message).toBe('Error: Request failed with status code 401')
5757
}
5858
}, 60000)
5959
})

src/Lighthouse/upload/files/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ async function uploadFiles(
1414
// Upload File to IPFS
1515
//@ts-ignore
1616
if (typeof window === 'undefined') {
17-
return await uploadFile(path, apiKey, cidVersion)
17+
return await uploadFile(path, apiKey, cidVersion, uploadProgressCallback)
1818
} else {
1919
return await uploadFileBrowser(
2020
path,

src/Lighthouse/upload/files/node.ts

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import basePathConvert from '../../utils/basePathConvert'
22
import { lighthouseConfig } from '../../../lighthouse.config'
3-
import { fetchWithTimeout } from '../../utils/util'
4-
import { IFileUploadedResponse } from '../../../types'
3+
import { fetchWithDirectStream } from '../../utils/util'
4+
import { IFileUploadedResponse, IUploadProgressCallback } from '../../../types'
55
export async function walk(dir: string) {
66
const { readdir, stat } = eval(`require`)('fs-extra')
77
let results: string[] = []
@@ -24,79 +24,85 @@ export async function walk(dir: string) {
2424
export default async (
2525
sourcePath: string,
2626
apiKey: string,
27-
cidVersion: number
27+
cidVersion: number,
28+
uploadProgressCallback?: (data: IUploadProgressCallback) => void
2829
): Promise<{ data: IFileUploadedResponse }> => {
2930
const { createReadStream, lstatSync } = eval(`require`)('fs-extra')
3031
const path = eval(`require`)('path')
3132

3233
const token = 'Bearer ' + apiKey
3334
const stats = lstatSync(sourcePath)
35+
3436
try {
3537
const endpoint =
3638
lighthouseConfig.lighthouseNode +
3739
`/api/v0/add?wrap-with-directory=false&cid-version=${cidVersion}`
40+
const boundary =
41+
'----WebKitFormBoundary' + Math.random().toString(16).substr(2)
42+
43+
const headers = {
44+
Authorization: token,
45+
}
46+
3847
if (stats.isFile()) {
39-
const data = new FormData()
4048
const stream = createReadStream(sourcePath)
41-
const buffers: Buffer[] = []
42-
for await (const chunk of stream) {
43-
buffers.push(chunk)
49+
const streamData = {
50+
boundary,
51+
files: [
52+
{
53+
stream,
54+
filename: path.basename(sourcePath),
55+
size: stats.size,
56+
},
57+
],
4458
}
45-
const blob = new Blob(buffers)
4659

47-
data.append('file', blob, path.basename(sourcePath))
48-
49-
const response = await fetchWithTimeout(endpoint, {
50-
method: 'POST',
51-
body: data,
52-
timeout: 7200000,
53-
headers: {
54-
Authorization: token
60+
const response = await fetchWithDirectStream(
61+
endpoint,
62+
{
63+
method: 'POST',
64+
headers,
65+
timeout: 7200000,
66+
onProgress: uploadProgressCallback
67+
? (data: { progress: number }) => uploadProgressCallback(data)
68+
: undefined,
5569
},
56-
})
70+
streamData
71+
)
5772

58-
if (!response.ok) {
59-
const res = (await response.json())
60-
throw new Error(res.error)
61-
}
62-
63-
const responseData = (await response.json())
64-
return { data: responseData }
73+
return response
6574
} else {
75+
// Handle directory upload
6676
const files = await walk(sourcePath)
67-
const data = new FormData()
6877

69-
for (const file of files) {
70-
const stream = createReadStream(file)
71-
const buffers: Buffer[] = []
72-
for await (const chunk of stream) {
73-
buffers.push(chunk)
74-
}
75-
const blob = new Blob(buffers)
78+
const createStreamData = () => ({
79+
boundary,
80+
files: files.map((file) => {
81+
const fileStats = lstatSync(file)
82+
return {
83+
stream: createReadStream(file),
84+
filename: basePathConvert(sourcePath, file),
85+
size: fileStats.size,
86+
}
87+
}),
88+
})
7689

77-
data.append(
78-
'file',
79-
blob,
80-
basePathConvert(sourcePath, file)
81-
)
82-
}
90+
const streamData = createStreamData()
8391

84-
const response = await fetchWithTimeout(endpoint, {
85-
method: 'POST',
86-
body: data,
87-
timeout: 7200000,
88-
headers: {
89-
Authorization: token
92+
const response = await fetchWithDirectStream(
93+
endpoint,
94+
{
95+
method: 'POST',
96+
headers,
97+
timeout: 7200000,
98+
onProgress: uploadProgressCallback
99+
? (data: { progress: number }) => uploadProgressCallback(data)
100+
: undefined,
90101
},
91-
})
92-
93-
if (!response.ok) {
94-
const res = (await response.json())
95-
throw new Error(res.error)
96-
}
102+
streamData
103+
)
97104

98-
const responseData = (await response.json())
99-
return { data: responseData }
105+
return response
100106
}
101107
} catch (error: any) {
102108
throw new Error(error)

src/Lighthouse/uploadEncrypted/encryptionBrowser.ts

Lines changed: 45 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -19,72 +19,60 @@ const deriveKey = async (
1919
)
2020

2121
export const encryptFile = async (fileArrayBuffer: any, password: any) => {
22-
try {
23-
const plainTextBytes = new Uint8Array(fileArrayBuffer)
24-
const passwordBytes = new TextEncoder().encode(password)
22+
const plainTextBytes = new Uint8Array(fileArrayBuffer)
23+
const passwordBytes = new TextEncoder().encode(password)
2524

26-
const salt = window.crypto.getRandomValues(new Uint8Array(16))
27-
const iv = window.crypto.getRandomValues(new Uint8Array(12))
25+
const salt = window.crypto.getRandomValues(new Uint8Array(16))
26+
const iv = window.crypto.getRandomValues(new Uint8Array(12))
2827

29-
const passwordKey = await importKeyFromBytes(passwordBytes)
28+
const passwordKey = await importKeyFromBytes(passwordBytes)
3029

31-
const aesKey = await deriveKey(passwordKey, ['encrypt'], {
32-
name: 'PBKDF2',
33-
salt: salt,
34-
iterations: 250000,
35-
hash: 'SHA-256',
36-
})
37-
const cipherBytes = await window.crypto.subtle.encrypt(
38-
{ name: 'AES-GCM', iv: iv },
39-
aesKey,
40-
plainTextBytes
41-
)
30+
const aesKey = await deriveKey(passwordKey, ['encrypt'], {
31+
name: 'PBKDF2',
32+
salt: salt,
33+
iterations: 250000,
34+
hash: 'SHA-256',
35+
})
36+
const cipherBytes = await window.crypto.subtle.encrypt(
37+
{ name: 'AES-GCM', iv: iv },
38+
aesKey,
39+
plainTextBytes
40+
)
4241

43-
const cipherBytesArray = new Uint8Array(cipherBytes)
44-
const resultBytes = new Uint8Array(
45-
cipherBytesArray.byteLength + salt.byteLength + iv.byteLength
46-
)
47-
resultBytes.set(salt, 0)
48-
resultBytes.set(iv, salt.byteLength)
49-
resultBytes.set(cipherBytesArray, salt.byteLength + iv.byteLength)
42+
const cipherBytesArray = new Uint8Array(cipherBytes)
43+
const resultBytes = new Uint8Array(
44+
cipherBytesArray.byteLength + salt.byteLength + iv.byteLength
45+
)
46+
resultBytes.set(salt, 0)
47+
resultBytes.set(iv, salt.byteLength)
48+
resultBytes.set(cipherBytesArray, salt.byteLength + iv.byteLength)
5049

51-
return resultBytes
52-
} catch (error) {
53-
console.error('Error encrypting file')
54-
console.error(error)
55-
throw error
56-
}
50+
return resultBytes
5751
}
5852

5953
export const decryptFile = async (cipher: any, password: any) => {
60-
try {
61-
const cipherBytes = new Uint8Array(cipher)
62-
const passwordBytes = new TextEncoder().encode(password)
54+
const cipherBytes = new Uint8Array(cipher)
55+
const passwordBytes = new TextEncoder().encode(password)
6356

64-
const salt = cipherBytes.slice(0, 16)
65-
const iv = cipherBytes.slice(16, 16 + 12)
66-
const data = cipherBytes.slice(16 + 12)
67-
const passwordKey = await importKeyFromBytes(passwordBytes)
68-
const aesKey = await deriveKey(passwordKey, ['decrypt'], {
69-
name: 'PBKDF2',
70-
salt: salt,
71-
iterations: 250000,
72-
hash: 'SHA-256',
73-
})
57+
const salt = cipherBytes.slice(0, 16)
58+
const iv = cipherBytes.slice(16, 16 + 12)
59+
const data = cipherBytes.slice(16 + 12)
60+
const passwordKey = await importKeyFromBytes(passwordBytes)
61+
const aesKey = await deriveKey(passwordKey, ['decrypt'], {
62+
name: 'PBKDF2',
63+
salt: salt,
64+
iterations: 250000,
65+
hash: 'SHA-256',
66+
})
7467

75-
const decryptedContent = await window.crypto.subtle.decrypt(
76-
{
77-
name: 'AES-GCM',
78-
iv: iv,
79-
},
80-
aesKey,
81-
data
82-
)
68+
const decryptedContent = await window.crypto.subtle.decrypt(
69+
{
70+
name: 'AES-GCM',
71+
iv: iv,
72+
},
73+
aesKey,
74+
data
75+
)
8376

84-
return decryptedContent
85-
} catch (error) {
86-
console.error('Error decrypting file')
87-
console.error(error)
88-
return
89-
}
77+
return decryptedContent
9078
}

0 commit comments

Comments
 (0)