commit
6a7c66711b
8 changed files with 618 additions and 594 deletions
|
|
@ -8,8 +8,6 @@ MS_TO_TOKEN_EXPIRATION=4500000
|
||||||
SHOCK_ENCRYPTION_ECC=true
|
SHOCK_ENCRYPTION_ECC=true
|
||||||
CACHE_HEADERS_MANDATORY=true
|
CACHE_HEADERS_MANDATORY=true
|
||||||
SHOCK_CACHE=true
|
SHOCK_CACHE=true
|
||||||
# Use only if disabling LND encrypt phrase (security risk)
|
|
||||||
TRUSTED_KEYS=true
|
|
||||||
# SSH Tunnel Provider
|
# SSH Tunnel Provider
|
||||||
LOCAL_TUNNEL_SERVER=https://tunnel.rip
|
LOCAL_TUNNEL_SERVER=https://tunnel.rip
|
||||||
# Default content to your own seed server
|
# Default content to your own seed server
|
||||||
|
|
|
||||||
55
.vscode/settings.json
vendored
55
.vscode/settings.json
vendored
|
|
@ -6,25 +6,78 @@
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"acked",
|
"acked",
|
||||||
|
"addinvoice",
|
||||||
"Authing",
|
"Authing",
|
||||||
|
"channelbalance",
|
||||||
"ciphertext",
|
"ciphertext",
|
||||||
|
"closechannel",
|
||||||
|
"closedchannels",
|
||||||
|
"Cltv",
|
||||||
|
"connectpeer",
|
||||||
|
"disconnectpeer",
|
||||||
"eccrypto",
|
"eccrypto",
|
||||||
"endregion",
|
"endregion",
|
||||||
"ephem",
|
"ephem",
|
||||||
"epriv",
|
"epriv",
|
||||||
"Epub",
|
"Epub",
|
||||||
|
"estimatefee",
|
||||||
|
"estimateroutefee",
|
||||||
|
"exportallchanbackups",
|
||||||
|
"exportchanbackup",
|
||||||
"falsey",
|
"falsey",
|
||||||
|
"forwardinghistory",
|
||||||
|
"getchaninfo",
|
||||||
|
"getinfo",
|
||||||
|
"getnetworkinfo",
|
||||||
|
"getnodeinfo",
|
||||||
"GUNRPC",
|
"GUNRPC",
|
||||||
|
"Healthz",
|
||||||
|
"initwall",
|
||||||
"ISEA",
|
"ISEA",
|
||||||
|
"keysend",
|
||||||
|
"kubernetes",
|
||||||
|
"listchannels",
|
||||||
|
"listinvoices",
|
||||||
|
"listpayments",
|
||||||
|
"listpeers",
|
||||||
|
"listunspent",
|
||||||
|
"lndchanbackups",
|
||||||
"LNDRPC",
|
"LNDRPC",
|
||||||
"lndstreaming",
|
"lndstreaming",
|
||||||
|
"lnrpc",
|
||||||
|
"lres",
|
||||||
|
"msgpack",
|
||||||
|
"newaddress",
|
||||||
|
"openchannel",
|
||||||
|
"otheruser",
|
||||||
|
"payreq",
|
||||||
|
"pendingchannels",
|
||||||
|
"preimage",
|
||||||
"PUBKEY",
|
"PUBKEY",
|
||||||
|
"qrcode",
|
||||||
|
"queryroute",
|
||||||
"radata",
|
"radata",
|
||||||
"Reqs",
|
"Reqs",
|
||||||
|
"resave",
|
||||||
|
"satoshis",
|
||||||
|
"sendcoins",
|
||||||
|
"sendmany",
|
||||||
|
"sendpayment",
|
||||||
|
"sendtoroute",
|
||||||
|
"serverhost",
|
||||||
|
"serverport",
|
||||||
"shockping",
|
"shockping",
|
||||||
"SHOCKWALLET",
|
"SHOCKWALLET",
|
||||||
|
"signmessage",
|
||||||
"thenables",
|
"thenables",
|
||||||
|
"trackpayment",
|
||||||
|
"txid",
|
||||||
|
"unfollow",
|
||||||
|
"Unlocker",
|
||||||
"unsubscription",
|
"unsubscription",
|
||||||
"uuidv"
|
"utxos",
|
||||||
|
"uuidv",
|
||||||
|
"verifymessage",
|
||||||
|
"walletbalance"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,5 +13,4 @@ services:
|
||||||
- 9835:9835
|
- 9835:9835
|
||||||
volumes:
|
volumes:
|
||||||
- C:\Users\boufn\.polar\networks\2\volumes\lnd\alice:/root/.lnd
|
- C:\Users\boufn\.polar\networks\2\volumes\lnd\alice:/root/.lnd
|
||||||
environment:
|
|
||||||
TRUSTED_KEYS: 'false'
|
|
||||||
|
|
@ -22,7 +22,7 @@ const Getters = require('./getters')
|
||||||
const Key = require('./key')
|
const Key = require('./key')
|
||||||
const Utils = require('./utils')
|
const Utils = require('./utils')
|
||||||
const SchemaManager = require('../../schema')
|
const SchemaManager = require('../../schema')
|
||||||
const LNDHealthMananger = require('../../../utils/lightningServices/errors')
|
const LNDHealthManager = require('../../../utils/lightningServices/errors')
|
||||||
const { enrollContentTokens, selfContentToken } = require('../../seed')
|
const { enrollContentTokens, selfContentToken } = require('../../seed')
|
||||||
|
|
||||||
/// <reference path="../../../utils/GunSmith/Smith.ts" />
|
/// <reference path="../../../utils/GunSmith/Smith.ts" />
|
||||||
|
|
@ -305,7 +305,7 @@ const setCurrentStreamInfo = (encryptedCurrentStreamInfo, user) =>
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {object} SpontPaymentOptions
|
* @typedef {object} SpontaneousPaymentOptions
|
||||||
* @prop {Common.Schema.OrderTargetType} type
|
* @prop {Common.Schema.OrderTargetType} type
|
||||||
* @prop {string=} ackInfo
|
* @prop {string=} ackInfo
|
||||||
*/
|
*/
|
||||||
|
|
@ -320,7 +320,7 @@ const setCurrentStreamInfo = (encryptedCurrentStreamInfo, user) =>
|
||||||
* @param {number} amount
|
* @param {number} amount
|
||||||
* @param {string} memo
|
* @param {string} memo
|
||||||
* @param {number} feeLimit
|
* @param {number} feeLimit
|
||||||
* @param {SpontPaymentOptions} opts
|
* @param {SpontaneousPaymentOptions} opts
|
||||||
* @throws {Error} If no response in less than 20 seconds from the recipient, or
|
* @throws {Error} If no response in less than 20 seconds from the recipient, or
|
||||||
* lightning cannot find a route for the payment.
|
* lightning cannot find a route for the payment.
|
||||||
* @returns {Promise<OrderRes>} The payment's preimage.
|
* @returns {Promise<OrderRes>} The payment's preimage.
|
||||||
|
|
@ -498,7 +498,7 @@ const sendSpontaneousPayment = async (
|
||||||
feeLimit,
|
feeLimit,
|
||||||
payment_request: orderResponse.response
|
payment_request: orderResponse.response
|
||||||
})
|
})
|
||||||
const myLndPub = LNDHealthMananger.lndPub
|
const myLndPub = LNDHealthManager.lndPub
|
||||||
if (
|
if (
|
||||||
(opts.type !== 'contentReveal' &&
|
(opts.type !== 'contentReveal' &&
|
||||||
opts.type !== 'torrentSeed' &&
|
opts.type !== 'torrentSeed' &&
|
||||||
|
|
|
||||||
723
src/routes.js
723
src/routes.js
File diff suppressed because it is too large
Load diff
106
src/server.js
106
src/server.js
|
|
@ -1,6 +1,21 @@
|
||||||
/**
|
/**
|
||||||
* @prettier
|
* @prettier
|
||||||
*/
|
*/
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const ECCrypto = require('eccrypto')
|
||||||
|
|
||||||
|
const ECC = require('../utils/ECC')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This API run's private key.
|
||||||
|
*/
|
||||||
|
const runPrivateKey = ECCrypto.generatePrivate()
|
||||||
|
/**
|
||||||
|
* This API run's public key.
|
||||||
|
*/
|
||||||
|
const runPublicKey = ECCrypto.getPublic(runPrivateKey)
|
||||||
|
|
||||||
process.on('uncaughtException', e => {
|
process.on('uncaughtException', e => {
|
||||||
console.log('something bad happened!')
|
console.log('something bad happened!')
|
||||||
console.log(e)
|
console.log(e)
|
||||||
|
|
@ -20,7 +35,6 @@ const server = program => {
|
||||||
const { Logger: CommonLogger } = require('shock-common')
|
const { Logger: CommonLogger } = require('shock-common')
|
||||||
const binaryParser = require('socket.io-msgpack-parser')
|
const binaryParser = require('socket.io-msgpack-parser')
|
||||||
|
|
||||||
const ECC = require('../utils/ECC')
|
|
||||||
const LightningServices = require('../utils/lightningServices')
|
const LightningServices = require('../utils/lightningServices')
|
||||||
const app = Express()
|
const app = Express()
|
||||||
|
|
||||||
|
|
@ -31,11 +45,17 @@ const server = program => {
|
||||||
const qrcode = require('qrcode-terminal')
|
const qrcode = require('qrcode-terminal')
|
||||||
const relayClient = require('hybrid-relay-client/build')
|
const relayClient = require('hybrid-relay-client/build')
|
||||||
const {
|
const {
|
||||||
unprotectedRoutes,
|
|
||||||
sensitiveRoutes,
|
sensitiveRoutes,
|
||||||
nonEncryptedRoutes
|
nonEncryptedRoutes
|
||||||
} = require('../utils/protectedRoutes')
|
} = require('../utils/protectedRoutes')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An offline-only private key used for authenticating a client's key
|
||||||
|
* exchange. Neither the tunnel nor the WWW should see this private key, it
|
||||||
|
* should only be served through STDOUT (via QR or else).
|
||||||
|
*/
|
||||||
|
const accessSecret = program.tunnel ? ECCrypto.generatePrivate() : null
|
||||||
|
|
||||||
// load app default configuration data
|
// load app default configuration data
|
||||||
const defaults = require('../config/defaults')(program.mainnet)
|
const defaults = require('../config/defaults')(program.mainnet)
|
||||||
const rootFolder = program.rootPath || process.resourcesPath || __dirname
|
const rootFolder = program.rootPath || process.resourcesPath || __dirname
|
||||||
|
|
@ -82,41 +102,6 @@ const server = program => {
|
||||||
.digest('hex')
|
.digest('hex')
|
||||||
}
|
}
|
||||||
|
|
||||||
const cacheCheck = ({ req, res, args, send }) => {
|
|
||||||
if (
|
|
||||||
(process.env.SHOCK_CACHE === 'true' || !process.env.SHOCK_CACHE) &&
|
|
||||||
req.method === 'GET'
|
|
||||||
) {
|
|
||||||
const dataHash = hashData(args[0]).slice(-8)
|
|
||||||
res.set('shock-cache-hash', dataHash)
|
|
||||||
|
|
||||||
logger.debug('shock-cache-hash:', req.headers['shock-cache-hash'])
|
|
||||||
logger.debug('Data Hash:', dataHash)
|
|
||||||
if (
|
|
||||||
!req.headers['shock-cache-hash'] &&
|
|
||||||
(process.env.CACHE_HEADERS_MANDATORY === 'true' ||
|
|
||||||
!process.env.CACHE_HEADERS_MANDATORY)
|
|
||||||
) {
|
|
||||||
logger.warn(
|
|
||||||
"Request is missing 'shock-cache-hash' header, please make sure to include that in each GET request in order to benefit from reduced data usage"
|
|
||||||
)
|
|
||||||
return { cached: false, hash: dataHash }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.headers['shock-cache-hash'] === dataHash) {
|
|
||||||
logger.debug('Same Hash Detected!')
|
|
||||||
args[0] = null
|
|
||||||
res.status(304)
|
|
||||||
send.apply(res, args)
|
|
||||||
return { cached: true, hash: dataHash }
|
|
||||||
}
|
|
||||||
|
|
||||||
return { cached: false, hash: dataHash }
|
|
||||||
}
|
|
||||||
|
|
||||||
return { cached: false, hash: null }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Express.Request} req
|
* @param {Express.Request} req
|
||||||
* @param {Express.Response} res
|
* @param {Express.Response} res
|
||||||
|
|
@ -140,6 +125,7 @@ const server = program => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
res.send = (...args) => {
|
res.send = (...args) => {
|
||||||
if (args[0] && args[0].ciphertext && args[0].iv) {
|
if (args[0] && args[0].ciphertext && args[0].iv) {
|
||||||
logger.warn('Response loop detected!')
|
logger.warn('Response loop detected!')
|
||||||
|
|
@ -147,20 +133,23 @@ const server = program => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const authorized = ECC.isAuthorizedDevice({
|
if (typeof deviceId !== 'string' || !deviceId) {
|
||||||
deviceId
|
// TODO
|
||||||
})
|
}
|
||||||
|
|
||||||
|
const authorized = ECC.devicePublicKeys.has(deviceId)
|
||||||
|
|
||||||
// Using classic promises syntax to avoid
|
// Using classic promises syntax to avoid
|
||||||
// modifying res.send's return type
|
// modifying res.send's return type
|
||||||
if (authorized && process.env.SHOCK_ENCRYPTION_ECC !== 'false') {
|
if (authorized && process.env.SHOCK_ENCRYPTION_ECC !== 'false') {
|
||||||
ECC.encryptMessage({
|
const devicePub = Buffer.from(ECC.devicePublicKeys.get(deviceId))
|
||||||
deviceId,
|
|
||||||
message: args[0]
|
ECCrypto.encrypt(devicePub, Buffer.from(args[0], 'utf-8')).then(
|
||||||
}).then(encryptedMessage => {
|
encryptedMessage => {
|
||||||
args[0] = JSON.stringify(encryptedMessage)
|
args[0] = JSON.stringify(encryptedMessage)
|
||||||
oldSend.apply(res, args)
|
oldSend.apply(res, args)
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!authorized || process.env.SHOCK_ENCRYPTION_ECC === 'false') {
|
if (!authorized || process.env.SHOCK_ENCRYPTION_ECC === 'false') {
|
||||||
|
|
@ -195,7 +184,7 @@ const server = program => {
|
||||||
await LightningServices.init()
|
await LightningServices.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await /** @type {Promise<void>} */ (new Promise((resolve, reject) => {
|
||||||
LightningServices.services.lightning.getInfo({}, (err, res) => {
|
LightningServices.services.lightning.getInfo({}, (err, res) => {
|
||||||
if (
|
if (
|
||||||
err &&
|
err &&
|
||||||
|
|
@ -207,9 +196,7 @@ const server = program => {
|
||||||
resolve()
|
resolve()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
}))
|
||||||
|
|
||||||
const auth = require('../services/auth/auth')
|
|
||||||
|
|
||||||
app.use(compression())
|
app.use(compression())
|
||||||
|
|
||||||
|
|
@ -320,7 +307,7 @@ const server = program => {
|
||||||
return httpsServer
|
return httpsServer
|
||||||
}
|
}
|
||||||
|
|
||||||
const httpServer = Http.Server(app)
|
const httpServer = new Http.Server(app)
|
||||||
return httpServer
|
return httpServer
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err.message)
|
logger.error(err.message)
|
||||||
|
|
@ -328,7 +315,7 @@ const server = program => {
|
||||||
'An error has occurred while finding an LND cert to use to open an HTTPS server'
|
'An error has occurred while finding an LND cert to use to open an HTTPS server'
|
||||||
)
|
)
|
||||||
logger.warn('Falling back to opening an HTTP server...')
|
logger.warn('Falling back to opening an HTTP server...')
|
||||||
const httpServer = Http.Server(app)
|
const httpServer = new Http.Server(app)
|
||||||
return httpServer
|
return httpServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -366,11 +353,13 @@ const server = program => {
|
||||||
},
|
},
|
||||||
Sockets,
|
Sockets,
|
||||||
{
|
{
|
||||||
serverHost,
|
|
||||||
serverPort,
|
serverPort,
|
||||||
useTLS: program.useTLS,
|
useTLS: program.useTLS,
|
||||||
CA,
|
CA,
|
||||||
CA_KEY
|
CA_KEY,
|
||||||
|
runPrivateKey,
|
||||||
|
runPublicKey,
|
||||||
|
accessSecret
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -408,12 +397,12 @@ const server = program => {
|
||||||
Storage.setItem('relay/url', noProtocolAddress)
|
Storage.setItem('relay/url', noProtocolAddress)
|
||||||
])
|
])
|
||||||
const dataToQr = JSON.stringify({
|
const dataToQr = JSON.stringify({
|
||||||
internalIP: `${params.relayId}@${noProtocolAddress}`,
|
URI: `https://${params.relayId}@${noProtocolAddress}`,
|
||||||
walletPort: 443,
|
// Null-check is just to please typescript
|
||||||
externalIP: `${params.relayId}@${noProtocolAddress}`
|
accessSecret: accessSecret && accessSecret.toString('base64')
|
||||||
})
|
})
|
||||||
qrcode.generate(dataToQr, { small: true })
|
qrcode.generate(dataToQr, { small: false })
|
||||||
logger.info(`connect to ${params.relayId}@${noProtocolAddress}`)
|
logger.info(`connect to ${params.relayId}@${noProtocolAddress}:443`)
|
||||||
} else {
|
} else {
|
||||||
logger.error('!! Relay did not connect to server !!')
|
logger.error('!! Relay did not connect to server !!')
|
||||||
}
|
}
|
||||||
|
|
@ -436,6 +425,7 @@ const server = program => {
|
||||||
}
|
}
|
||||||
serverInstance.listen(serverPort, serverHost)
|
serverInstance.listen(serverPort, serverHost)
|
||||||
logger.info('App listening on ' + serverHost + ' port ' + serverPort)
|
logger.info('App listening on ' + serverHost + ' port ' + serverPort)
|
||||||
|
// @ts-expect-error
|
||||||
module.server = serverInstance
|
module.server = serverInstance
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error({ exception: err, message: err.message, code: err.code })
|
logger.error({ exception: err, message: err.message, code: err.code })
|
||||||
|
|
|
||||||
|
|
@ -1 +1,8 @@
|
||||||
|
/**
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
//@ts-check
|
||||||
|
|
||||||
module.exports = require('./ECC')
|
module.exports = require('./ECC')
|
||||||
|
|
||||||
|
module.exports.convertToEncryptedMessage = require('./crypto').convertToEncryptedMessage
|
||||||
|
|
|
||||||
|
|
@ -134,15 +134,15 @@ export interface Services {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ListChannelsReq {
|
export interface ListChannelsReq {
|
||||||
active_only: boolean
|
active_only?: boolean
|
||||||
inactive_only: boolean
|
inactive_only?: boolean
|
||||||
public_only: boolean
|
public_only?: boolean
|
||||||
private_only: boolean
|
private_only?: boolean
|
||||||
/**
|
/**
|
||||||
* Filters the response for channels with a target peer's pubkey. If peer is
|
* Filters the response for channels with a target peer's pubkey. If peer is
|
||||||
* empty, all channels will be returned.
|
* empty, all channels will be returned.
|
||||||
*/
|
*/
|
||||||
peer: Common.Bytes
|
peer?: Common.Bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -193,4 +193,8 @@ export interface AddInvoiceRes {
|
||||||
* all payments for this invoice as we require it for end to end security.
|
* all payments for this invoice as we require it for end to end security.
|
||||||
*/
|
*/
|
||||||
payment_addr: Common.Bytes
|
payment_addr: Common.Bytes
|
||||||
|
/**
|
||||||
|
* Custom property, by us.
|
||||||
|
*/
|
||||||
|
liquidityCheck?: boolean
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue