fix(core): proper browser support

not much really, fixed exports for webpack, fixed binary mode for websocket
This commit is contained in:
teidesu 2021-07-16 04:31:04 +03:00
parent 5b9ddc1f7b
commit 8fb099cfeb
11 changed files with 65 additions and 56 deletions

View file

@ -11,6 +11,11 @@
"build": "tsc",
"docs": "npx typedoc"
},
"browser": {
"./utils/platform/crypto.js": "./utils/platform/crypto.web.js",
"./utils/platform/transport.js": "./utils/platform/transport.web.js",
"./storage/json-file.js": false
},
"dependencies": {
"@types/node": "^15.12.1",
"@types/events": "^3.0.0",

View file

@ -8,24 +8,7 @@ export * from './websocket'
export * from './intermediate'
export * from './obfuscated'
import { _defaultTransportFactory } from '../../utils/platform/transport'
/** Platform-defined default transport factory */
export let defaultTransportFactory: TransportFactory
if (typeof process !== 'undefined') {
// we are in node, use tcp transport by default
const { TcpTransport } = require('./tcp')
defaultTransportFactory = () => new TcpTransport()
} else {
// we are in browser (probably), use websocket
// if no websocket, throw an error i guess ¯\_(ツ)_/¯
// (user can still implement something on their own)
if (typeof WebSocket === 'undefined') {
defaultTransportFactory = () => {
throw new Error(
'Neither TCP nor WebSocket are available. Please pass a Transport factory explicitly'
)
}
} else {
const { WebSocketTransport } = require('./websocket')
defaultTransportFactory = () => new WebSocketTransport()
}
}
export const defaultTransportFactory: TransportFactory = _defaultTransportFactory

View file

@ -105,6 +105,8 @@ export abstract class BaseWebSocketTransport
'binary'
)
this._socket.binaryType = 'arraybuffer'
this._socket.addEventListener('message', (evt) =>
this._packetCodec.feed(typedArrayToBuffer(evt.data))
)

View file

@ -43,7 +43,8 @@ export class JsonFileStorage extends JsonMemoryStorage {
}
) {
super()
if (!fs) throw new Error('Node fs module is not available!')
if (!fs || !fs.readFile)
throw new Error('Node fs module is not available!')
this._filename = filename
this._safe = params?.safe ?? true

View file

@ -1,9 +1,4 @@
export let nodeCrypto: any = null
if (typeof process !== 'undefined' && typeof require !== 'undefined') {
try {
nodeCrypto = require('crypto')
} catch (e) {}
}
export { _randomBytes as randomBytes } from './platform/crypto'
// from https://github.com/feross/typedarray-to-buffer
// licensed under MIT
@ -40,14 +35,6 @@ export function xorBufferInPlace(data: Buffer, key: Buffer): void {
}
}
export function randomBytes(size: number): Buffer {
if (nodeCrypto) return nodeCrypto.randomBytes(size)
const ret = new Uint8Array(size)
crypto.getRandomValues(ret)
return typedArrayToBuffer(ret)
}
export function cloneBuffer(buf: Buffer, start = 0, end = buf.length): Buffer {
const ret = Buffer.alloc(end - start)
buf.copy(ret, 0, start, end)

View file

@ -1,5 +1,3 @@
import { CryptoProviderFactory } from './abstract'
import { nodeCrypto } from '../buffer-utils'
import { NodeCryptoProvider } from './node-crypto'
import { ForgeCryptoProvider } from './forge-crypto'
@ -8,9 +6,7 @@ export * from './password'
export { NodeCryptoProvider, ForgeCryptoProvider }
export let defaultCryptoProviderFactory: CryptoProviderFactory
if (nodeCrypto) {
defaultCryptoProviderFactory = () => new NodeCryptoProvider()
} else {
defaultCryptoProviderFactory = () => new ForgeCryptoProvider()
}
import { _defaultCryptoProviderFactory } from '../platform/crypto'
import { CryptoProviderFactory } from './abstract'
export const defaultCryptoProviderFactory: CryptoProviderFactory = _defaultCryptoProviderFactory

View file

@ -1,18 +1,16 @@
import { BaseCryptoProvider, IEncryptionScheme, IHashMethod } from './abstract'
import { MaybeAsync } from '../../types'
import { nodeCrypto } from '../buffer-utils'
import { createCipheriv, createDecipheriv, createHash, createHmac, pbkdf2 } from 'crypto'
export class NodeCryptoProvider extends BaseCryptoProvider {
constructor() {
super()
if (!nodeCrypto)
throw new Error('Cannot use Node crypto functions outside NodeJS!')
}
createAesCtr(key: Buffer, iv: Buffer, encrypt: boolean): IEncryptionScheme {
const cipher = nodeCrypto[
encrypt ? 'createCipheriv' : 'createDecipheriv'
](`aes-${key.length * 8}-ctr`, key, iv)
const cipher = (
encrypt ? createCipheriv : createDecipheriv
)(`aes-${key.length * 8}-ctr`, key, iv)
const update = (data: Buffer) => cipher.update(data)
@ -27,12 +25,12 @@ export class NodeCryptoProvider extends BaseCryptoProvider {
return {
encrypt(data: Buffer) {
const cipher = nodeCrypto.createCipheriv(methodName, key, null)
const cipher = createCipheriv(methodName, key, null)
cipher.setAutoPadding(false)
return Buffer.concat([cipher.update(data), cipher.final()])
},
decrypt(data: Buffer) {
const cipher = nodeCrypto.createDecipheriv(
const cipher = createDecipheriv(
methodName,
key,
null
@ -49,7 +47,7 @@ export class NodeCryptoProvider extends BaseCryptoProvider {
iterations: number
): MaybeAsync<Buffer> {
return new Promise((resolve, reject) =>
nodeCrypto.pbkdf2(
pbkdf2(
password,
salt,
iterations,
@ -62,18 +60,18 @@ export class NodeCryptoProvider extends BaseCryptoProvider {
}
sha1(data: Buffer): Buffer {
return nodeCrypto.createHash('sha1').update(data).digest()
return createHash('sha1').update(data).digest()
}
sha256(data: Buffer): Buffer {
return nodeCrypto.createHash('sha256').update(data).digest()
return createHash('sha256').update(data).digest()
}
createMd5(): IHashMethod {
return nodeCrypto.createHash('md5')
return createHash('md5') as any
}
hmacSha256(data: Buffer, key: Buffer): MaybeAsync<Buffer> {
return nodeCrypto.createHmac('sha256', key).update(data).digest()
return createHmac('sha256', key).update(data).digest()
}
}

View file

@ -0,0 +1,8 @@
import { NodeCryptoProvider } from '../crypto'
import { randomBytes } from 'crypto'
/** @internal */
export const _defaultCryptoProviderFactory = () => new NodeCryptoProvider()
/** @internal */
export const _randomBytes = randomBytes

View file

@ -0,0 +1,12 @@
import { ForgeCryptoProvider } from '../crypto'
import { typedArrayToBuffer } from '../buffer-utils'
/** @internal */
export const _defaultCryptoProviderFactory = () => new ForgeCryptoProvider()
/** @internal */
export function _randomBytes(size: number): Buffer {
const ret = new Uint8Array(size)
crypto.getRandomValues(ret)
return typedArrayToBuffer(ret)
}

View file

@ -0,0 +1,4 @@
import { TcpTransport } from '../../network'
/** @internal */
export const _defaultTransportFactory = () => new TcpTransport()

View file

@ -0,0 +1,13 @@
import { WebSocketTransport } from '../../network'
/** @internal */
export const _defaultTransportFactory =
typeof WebSocket === 'undefined'
// if no websocket, throw an error i guess ¯\_(ツ)_/¯
// (user can still implement something on their own)
? () => {
throw new Error(
'Neither TCP nor WebSocket are available. Please pass a Transport factory explicitly'
)
}
: () => new WebSocketTransport()