Added API Caching functionality

This commit is contained in:
emad-salah 2020-03-07 15:51:20 +01:00
parent 721a199e7d
commit 00603ed0fa
6 changed files with 69 additions and 15 deletions

1
.gitignore vendored
View file

@ -5,5 +5,6 @@ services/auth/secrets.json
.directory
radata/
radata-*.tmp
*.cert
*.key

View file

@ -5,7 +5,7 @@
"main": "src/server.js",
"scripts": {
"start": "node --experimental-modules src/server.js",
"dev": "node main.js -h 0.0.0.0",
"dev": "node --max-old-space-size=4096 main.js -h 0.0.0.0",
"dev:watch": "nodemon main.js -- -h 0.0.0.0",
"test": "jest --no-cache",
"test:watch": "jest --no-cache --watch",

View file

@ -1,5 +1,20 @@
{
"1582813836485": "b8328f50-596d-11ea-b251-cf923e62abf5",
"1582815195785": "e2674790-5970-11ea-ba5d-4b7fda6488de",
"1582820933939": "3e9c1830-597e-11ea-acaa-2b96f5467d08"
"1582820933939": "3e9c1830-597e-11ea-acaa-2b96f5467d08",
"1582670203354": "4c2e13a0-581f-11ea-ad3d-a73b4b4c0361",
"1583339145556": "cccda140-5e34-11ea-8c4e-17a1f5fd1235",
"1583584195969": "5a3b3f10-606f-11ea-8523-9d59c298ff41",
"1583584284436": "8ef63d40-606f-11ea-ba0f-e74d20a4ef9a",
"1583584328860": "a970cdc0-606f-11ea-ba0f-e74d20a4ef9a",
"1583584658911": "6e2a96f0-6070-11ea-ba0f-e74d20a4ef9a",
"1583585004260": "3c02aa40-6071-11ea-987e-bd3595c9104b",
"1583585179728": "a498f500-6071-11ea-a5f5-1f051c0be7de",
"1583585675201": "cbec2310-6072-11ea-a5f5-1f051c0be7de",
"1583585744767": "f56310f0-6072-11ea-a5f5-1f051c0be7de",
"1583585838554": "2d49d3a0-6073-11ea-b4d0-f9a792ba6160",
"1583586016626": "976d7520-6073-11ea-a6b4-4380ee6b86a1",
"1583588647390": "b77c2fe0-6079-11ea-a0aa-8368c2d33cfe",
"1583590307894": "9538fd60-607d-11ea-92cb-ed88e8db1271",
"1583590742693": "98623460-607e-11ea-bf6c-611b3b0363dc"
}

View file

@ -212,6 +212,7 @@ module.exports = async (
app.use((req, res, next) => {
const deviceId = req.headers["x-shockwallet-device-id"];
console.log("Decrypting route...")
try {
if (nonEncryptedRoutes.includes(req.path)) {
return next();

View file

@ -9,6 +9,7 @@ const server = program => {
const Https = require('https')
const Http = require('http')
const Express = require('express')
const Crypto = require('crypto')
const LightningServices = require('../utils/lightningServices')
const Encryption = require('../utils/encryptionStore')
const app = Express()
@ -41,6 +42,25 @@ const server = program => {
logger.info('Mainnet Mode:', !!program.mainnet)
const stringifyData = data => {
if (typeof data === 'object') {
const stringifiedData = JSON.stringify(data)
return stringifiedData
}
if (data.toString) {
return data.toString()
}
return data
}
const hashData = data => {
return Crypto.createHash('SHA256')
.update(Buffer.from(stringifyData(data)))
.digest('hex')
}
const modifyResponseBody = (req, res, next) => {
const deviceId = req.headers['x-shockwallet-device-id']
const oldSend = res.send
@ -50,18 +70,35 @@ const server = program => {
if (args[0] && args[0].encryptedData && args[0].encryptionKey) {
logger.warn('Response loop detected!')
oldSend.apply(res, args)
} else {
// arguments[0] (or `data`) contains the response body
const authorized = Encryption.isAuthorizedDevice({ deviceId })
const encryptedMessage = authorized
? Encryption.encryptMessage({
message: args[0],
deviceId
})
: args[0]
args[0] = JSON.stringify(encryptedMessage)
oldSend.apply(res, args)
return
}
const dataHash = hashData(args[0])
res.set('ETag', dataHash)
console.log('ETag:', req.headers.etag)
console.log('Data Hash:', dataHash)
if (req.headers.etag === dataHash) {
console.log('Same Hash Detected!')
args[0] = null
res.status(304)
oldSend.apply(res, args)
return
}
// arguments[0] (or `data`) contains the response body
const authorized = Encryption.isAuthorizedDevice({ deviceId })
const encryptedMessage = authorized
? Encryption.encryptMessage({
message: args[0],
deviceId,
metadata: {
hash: dataHash
}
})
: args[0]
args[0] = JSON.stringify(encryptedMessage)
oldSend.apply(res, args)
}
}
next()

View file

@ -49,7 +49,7 @@ const Encryption = {
return encryptedData.toString()
},
encryptMessage: ({ deviceId, message }) => {
encryptMessage: ({ deviceId, message, metadata }) => {
const parsedMessage =
typeof message === 'object' ? JSON.stringify(message) : message
const data = Buffer.from(parsedMessage)
@ -66,7 +66,7 @@ const Encryption = {
Buffer.from(cipher.final())
])
const encryptedData = encryptedBuffer.toString('base64')
return { encryptedData, encryptedKey, iv: iv.toString('hex') }
return { encryptedData, encryptedKey, iv: iv.toString('hex'), metadata }
},
decryptMessage: ({ message, key, iv }) => {
const data = Buffer.from(message, 'base64')