Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add [email protected] to transport-interop #8

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions transport-interop/impl/js/v1.9/.aegir.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* eslint-disable no-console */
import http from 'http'
import { pEvent } from 'p-event'
import { createClient } from 'redis'

const redisAddr = process.env.redis_addr || 'redis:6379'
const transport = process.env.transport
const isDialer = process.env.is_dialer === 'true'

/** @type {import('aegir/types').PartialOptions} */
export default {
test: {
browser: {
config: {
// Ignore self signed certificates
browserContextOptions: { ignoreHTTPSErrors: true }
}
},
async before () {
// import after build is complete
const { createRelay } = await import('./dist/test/fixtures/relay.js')

let relayNode
let relayAddr
if (transport === 'webrtc' && !isDialer) {
relayNode = await createRelay()

const sortByNonLocalIp = (a, b) => {
if (a.toString().includes('127.0.0.1')) {
return 1
}
return -1
}

relayAddr = relayNode.getMultiaddrs().sort(sortByNonLocalIp)[0].toString()
}

const redisClient = createClient({
url: `redis://${redisAddr}`
})
redisClient.on('error', (err) => {
console.error('Redis client error:', err)
})
await redisClient.connect()

const requestListener = async function (req, res) {
const requestJSON = await new Promise(resolve => {
let body = ''
req.on('data', function (data) {
body += data
})

req.on('end', function () {
resolve(JSON.parse(body))
})
})

try {
const redisRes = await redisClient.sendCommand(requestJSON)

if (redisRes == null) {
console.error('Redis failure - sent', requestJSON, 'received', redisRes)

res.writeHead(500, {
'Access-Control-Allow-Origin': '*'
})
res.end(JSON.stringify({
message: 'Redis sent back null'
}))

return
}

res.writeHead(200, {
'Access-Control-Allow-Origin': '*'
})
res.end(JSON.stringify(redisRes))
} catch (err) {
console.error('Error in redis command:', err)
res.writeHead(500, {
'Access-Control-Allow-Origin': '*'
})
res.end(err.toString())

Check warning

Code scanning / CodeQL

Exception text reinterpreted as HTML Medium

Exception text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix AI about 1 month ago

To fix the problem, we need to ensure that any error messages sent back in the HTTP response are properly sanitized to prevent XSS attacks. The best way to achieve this is by using a library that provides HTML escaping functionality. One such library is he, which can encode HTML entities to prevent XSS.

  1. Install the he library to handle HTML escaping.
  2. Import the he library in the file.
  3. Use the he.encode function to escape the error message before sending it in the HTTP response.
Suggested changeset 2
transport-interop/impl/js/v1.9/.aegir.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/transport-interop/impl/js/v1.9/.aegir.js b/transport-interop/impl/js/v1.9/.aegir.js
--- a/transport-interop/impl/js/v1.9/.aegir.js
+++ b/transport-interop/impl/js/v1.9/.aegir.js
@@ -4,2 +4,3 @@
 import { createClient } from 'redis'
+import he from 'he'
 
@@ -82,3 +83,3 @@
           })
-          res.end(err.toString())
+          res.end(he.encode(err.toString()))
         }
EOF
@@ -4,2 +4,3 @@
import { createClient } from 'redis'
import he from 'he'

@@ -82,3 +83,3 @@
})
res.end(err.toString())
res.end(he.encode(err.toString()))
}
transport-interop/impl/js/v1.9/package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/transport-interop/impl/js/v1.9/package.json b/transport-interop/impl/js/v1.9/package.json
--- a/transport-interop/impl/js/v1.9/package.json
+++ b/transport-interop/impl/js/v1.9/package.json
@@ -32,2 +32,5 @@
     "@libp2p/tcp": false
+  },
+  "dependencies": {
+    "he": "^1.2.0"
   }
EOF
@@ -32,2 +32,5 @@
"@libp2p/tcp": false
},
"dependencies": {
"he": "^1.2.0"
}
This fix introduces these dependencies
Package Version Security advisories
he (npm) 1.2.0 None
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
}
}

const proxyServer = http.createServer(requestListener)
proxyServer.listen(0)

await pEvent(proxyServer, 'listening', {
signal: AbortSignal.timeout(5000)
})

return {
redisClient,
relayNode,
proxyServer,
env: {
...process.env,
RELAY_ADDR: relayAddr,
REDIS_PROXY_PORT: proxyServer.address().port
}
}
},
async after (_, { proxyServer, redisClient, relayNode }) {
await new Promise(resolve => {
proxyServer?.close(() => resolve())
})

try {
// We don't care if this fails
await redisClient?.disconnect()
await relayNode?.stop()
} catch { }
}
}
}
24 changes: 24 additions & 0 deletions transport-interop/impl/js/v1.9/BrowserDockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# syntax=docker/dockerfile:1

# Copied since we won't have the repo to use if expanding from cache.

# Workaround: https://github.com/docker/cli/issues/996
ARG BASE_IMAGE=node-js-libp2p-head
FROM ${BASE_IMAGE} as js-libp2p-base

FROM mcr.microsoft.com/playwright

COPY --from=js-libp2p-base /app/ /app/
WORKDIR /app

# We install browsers here instead of the cached version so that we use the latest browsers at run time.
# Ideally this would also be pinned, but playwright controls this, so there isn't much we can do about it.
# By installing here, we avoid installing it at test time.
RUN npx playwright install-deps
RUN npx playwright install

# Options: chromium, firefox, webkit
ARG BROWSER=chromium
ENV BROWSER=${BROWSER}

ENTRYPOINT npm test -- -t browser -- --browser $BROWSER
17 changes: 17 additions & 0 deletions transport-interop/impl/js/v1.9/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Here because we want to fetch the node_modules within docker so that it's
# installed on the same platform the test is run. Otherwise tools like `esbuild` will fail to run
FROM node:lts

WORKDIR /app

COPY package*.json .aegir.js tsconfig.json ./
COPY src ./src
COPY test ./test

# disable colored output and CLI animation from test runners
ENV CI true

RUN npm ci
RUN npm run build

ENTRYPOINT npm test -- -t node
35 changes: 35 additions & 0 deletions transport-interop/impl/js/v1.9/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
image_name := js-v1.x

# TODO Enable webkit once https://github.com/libp2p/js-libp2p/pull/1627 is in
all: image.json chromium-image.json firefox-image.json update-lock-file

# Necessary because multistage builds require a docker image name rather than a digest to be used
load-image-json: image.json
docker image tag $$(jq -r .imageID image.json) ${image_name}

chromium-image.json: load-image-json BrowserDockerfile
docker build -f BrowserDockerfile --build-arg=BASE_IMAGE=${image_name} --build-arg=BROWSER=chromium -t chromium-${image_name} .
docker image inspect chromium-${image_name} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@

firefox-image.json: load-image-json BrowserDockerfile
docker build -f BrowserDockerfile --build-arg=BASE_IMAGE=${image_name} --build-arg=BROWSER=firefox -t firefox-${image_name} .
docker image inspect firefox-${image_name} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@

# We update the lock file here so that we make sure we are always using the correct lock file.
# If this changes, CI will fail since there are unstaged changes.
update-lock-file: image.json
CONTAINER_ID=$$(docker create $$(jq -r .imageID image.json)); \
docker cp $$CONTAINER_ID:/app/package-lock.json ./package-lock.json; \
docker rm $$CONTAINER_ID

image.json:
docker build -t ${image_name} -f ./Dockerfile .
docker image inspect ${image_name} -f "{{.Id}}" | \
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@

clean:
rm -rf image.json *-image.json

.PHONY: all clean browser-images load-image-json
Loading