Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92467eb28f | ||
|
|
21f21cb312 | ||
|
|
a82b5b0e62 | ||
|
|
355a4641a8 | ||
|
|
50dbf2f36c | ||
|
|
2a602963c2 | ||
|
|
61e04e231d | ||
|
|
93d1217e3f | ||
|
|
17a79a92a6 | ||
|
|
7a0b59f9ab | ||
|
|
a916812f67 | ||
|
|
15f53e00f6 | ||
|
|
911ae9a9d1 | ||
|
|
18c9485047 | ||
|
|
7eb7055d29 | ||
|
|
ebcbcb60ac | ||
|
|
13dac1510b | ||
|
|
960f48270b | ||
|
|
d87677b04d | ||
|
|
bd0f47e27e | ||
|
|
6352983a5d | ||
|
|
be02de5ede | ||
|
|
2b062ec18c | ||
|
|
f4a6c38f2a | ||
|
|
bc8523c04b | ||
|
|
6ecbf76d39 | ||
|
|
2763f7b0b3 | ||
|
|
934acd2a2a | ||
|
|
affe8f4720 | ||
|
|
ad358d4370 |
67
.github/workflows/e2e-tests.yml
vendored
67
.github/workflows/e2e-tests.yml
vendored
@@ -30,6 +30,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
|
max-parallel: 4
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
version: [latest, 2.30.0]
|
version: [latest, 2.30.0]
|
||||||
@@ -42,9 +43,9 @@ jobs:
|
|||||||
ref: ${{ inputs.ref }}
|
ref: ${{ inputs.ref }}
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 24
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -59,6 +60,9 @@ jobs:
|
|||||||
echo "FILE_SECRET=op://${{ secrets.VAULT }}/test-secret/password" > tests/.env.tpl
|
echo "FILE_SECRET=op://${{ secrets.VAULT }}/test-secret/password" > tests/.env.tpl
|
||||||
echo "FILE_SECRET_IN_SECTION=op://${{ secrets.VAULT }}/test-secret/test-section/password" >> tests/.env.tpl
|
echo "FILE_SECRET_IN_SECTION=op://${{ secrets.VAULT }}/test-secret/test-section/password" >> tests/.env.tpl
|
||||||
echo "FILE_MULTILINE_SECRET=op://${{ secrets.VAULT }}/multiline-secret/notesPlain" >> tests/.env.tpl
|
echo "FILE_MULTILINE_SECRET=op://${{ secrets.VAULT }}/multiline-secret/notesPlain" >> tests/.env.tpl
|
||||||
|
echo "FILE_WEBSITE=op://${{ secrets.VAULT }}/test-secret/website" >> tests/.env.tpl
|
||||||
|
echo "FILE_TEST_SSH_KEY=op://${{ secrets.VAULT }}/test-ssh-key/private key" >> tests/.env.tpl
|
||||||
|
echo "FILE_TEST_SSH_KEY_OPENSSH=op://${{ secrets.VAULT }}/test-ssh-key/private key?ssh-format=openssh" >> tests/.env.tpl
|
||||||
|
|
||||||
- name: Configure Service account
|
- name: Configure Service account
|
||||||
uses: ./configure
|
uses: ./configure
|
||||||
@@ -75,25 +79,52 @@ jobs:
|
|||||||
SECRET: op://${{ secrets.VAULT }}/test-secret/password
|
SECRET: op://${{ secrets.VAULT }}/test-secret/password
|
||||||
SECRET_IN_SECTION: op://${{ secrets.VAULT }}/test-secret/test-section/password
|
SECRET_IN_SECTION: op://${{ secrets.VAULT }}/test-secret/test-section/password
|
||||||
MULTILINE_SECRET: op://${{ secrets.VAULT }}/multiline-secret/notesPlain
|
MULTILINE_SECRET: op://${{ secrets.VAULT }}/multiline-secret/notesPlain
|
||||||
|
WEBSITE: op://${{ secrets.VAULT }}/test-secret/website
|
||||||
|
TEST_SSH_KEY: op://${{ secrets.VAULT }}/test-ssh-key/private key
|
||||||
|
TEST_SSH_KEY_OPENSSH: "op://${{ secrets.VAULT }}/test-ssh-key/private key?ssh-format=openssh"
|
||||||
OP_ENV_FILE: ./tests/.env.tpl
|
OP_ENV_FILE: ./tests/.env.tpl
|
||||||
|
|
||||||
- name: Assert test secret values [step output]
|
- name: Assert test secret values [step output]
|
||||||
if: ${{ !matrix.export-env }}
|
if: ${{ !matrix.export-env }}
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
env:
|
||||||
|
ASSERT_WEBSITE: "true"
|
||||||
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
|
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
|
||||||
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
|
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
|
||||||
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
|
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
|
||||||
FILE_SECRET: ${{ steps.load_secrets.outputs.FILE_SECRET }}
|
FILE_SECRET: ${{ steps.load_secrets.outputs.FILE_SECRET }}
|
||||||
FILE_SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.FILE_SECRET_IN_SECTION }}
|
FILE_SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.FILE_SECRET_IN_SECTION }}
|
||||||
FILE_MULTILINE_SECRET: ${{ steps.load_secrets.outputs.FILE_MULTILINE_SECRET }}
|
FILE_MULTILINE_SECRET: ${{ steps.load_secrets.outputs.FILE_MULTILINE_SECRET }}
|
||||||
|
WEBSITE: ${{ steps.load_secrets.outputs.WEBSITE }}
|
||||||
|
FILE_WEBSITE: ${{ steps.load_secrets.outputs.FILE_WEBSITE }}
|
||||||
|
TEST_SSH_KEY: ${{ steps.load_secrets.outputs.TEST_SSH_KEY }}
|
||||||
|
FILE_TEST_SSH_KEY: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY }}
|
||||||
|
TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.TEST_SSH_KEY_OPENSSH }}
|
||||||
|
FILE_TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY_OPENSSH }}
|
||||||
run: ./tests/assert-env-set.sh
|
run: ./tests/assert-env-set.sh
|
||||||
|
|
||||||
|
- name: Assert SSH key env vars [step output]
|
||||||
|
if: ${{ !matrix.export-env }}
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
TEST_SSH_KEY: ${{ steps.load_secrets.outputs.TEST_SSH_KEY }}
|
||||||
|
FILE_TEST_SSH_KEY: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY }}
|
||||||
|
TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.TEST_SSH_KEY_OPENSSH }}
|
||||||
|
FILE_TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY_OPENSSH }}
|
||||||
|
run: ./tests/assert-ssh-keys-set.sh
|
||||||
|
|
||||||
- name: Assert test secret values [exported env]
|
- name: Assert test secret values [exported env]
|
||||||
if: ${{ matrix.export-env }}
|
if: ${{ matrix.export-env }}
|
||||||
shell: bash
|
shell: bash
|
||||||
|
env:
|
||||||
|
ASSERT_WEBSITE: "true"
|
||||||
run: ./tests/assert-env-set.sh
|
run: ./tests/assert-env-set.sh
|
||||||
|
|
||||||
|
- name: Assert SSH key env vars [exported env]
|
||||||
|
if: ${{ matrix.export-env }}
|
||||||
|
shell: bash
|
||||||
|
run: ./tests/assert-ssh-keys-set.sh
|
||||||
|
|
||||||
- name: Remove secrets [exported env]
|
- name: Remove secrets [exported env]
|
||||||
if: ${{ matrix.export-env }}
|
if: ${{ matrix.export-env }}
|
||||||
uses: ./
|
uses: ./
|
||||||
@@ -111,7 +142,6 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
||||||
version: [latest, 2.30.0]
|
version: [latest, 2.30.0]
|
||||||
export-env: [true, false]
|
export-env: [true, false]
|
||||||
steps:
|
steps:
|
||||||
@@ -122,9 +152,9 @@ jobs:
|
|||||||
ref: ${{ inputs.ref }}
|
ref: ${{ inputs.ref }}
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 24
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -139,13 +169,16 @@ jobs:
|
|||||||
echo "FILE_SECRET=op://${{ secrets.VAULT }}/test-secret/password" > tests/.env.tpl
|
echo "FILE_SECRET=op://${{ secrets.VAULT }}/test-secret/password" > tests/.env.tpl
|
||||||
echo "FILE_SECRET_IN_SECTION=op://${{ secrets.VAULT }}/test-secret/test-section/password" >> tests/.env.tpl
|
echo "FILE_SECRET_IN_SECTION=op://${{ secrets.VAULT }}/test-secret/test-section/password" >> tests/.env.tpl
|
||||||
echo "FILE_MULTILINE_SECRET=op://${{ secrets.VAULT }}/multiline-secret/notesPlain" >> tests/.env.tpl
|
echo "FILE_MULTILINE_SECRET=op://${{ secrets.VAULT }}/multiline-secret/notesPlain" >> tests/.env.tpl
|
||||||
|
echo "FILE_TEST_SSH_KEY=op://${{ secrets.VAULT }}/test-ssh-key/private key" >> tests/.env.tpl
|
||||||
|
echo "FILE_TEST_SSH_KEY_OPENSSH=op://${{ secrets.VAULT }}/test-ssh-key/private key?ssh-format=openssh" >> tests/.env.tpl
|
||||||
|
|
||||||
- name: Launch 1Password Connect instance
|
- name: Launch 1Password Connect instance
|
||||||
env:
|
env:
|
||||||
OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }}
|
OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }}
|
||||||
run: |
|
run: |
|
||||||
echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json
|
echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json
|
||||||
docker compose -f tests/fixtures/docker-compose.yml up -d && sleep 10
|
docker compose -f tests/fixtures/docker-compose.yml up -d
|
||||||
|
timeout 60 bash -c 'until curl -sf http://localhost:8080/health >/dev/null 2>&1; do sleep 2; done'
|
||||||
|
|
||||||
- name: Configure 1Password Connect
|
- name: Configure 1Password Connect
|
||||||
uses: ./configure
|
uses: ./configure
|
||||||
@@ -163,23 +196,45 @@ jobs:
|
|||||||
SECRET: op://${{ secrets.VAULT }}/test-secret/password
|
SECRET: op://${{ secrets.VAULT }}/test-secret/password
|
||||||
SECRET_IN_SECTION: op://${{ secrets.VAULT }}/test-secret/test-section/password
|
SECRET_IN_SECTION: op://${{ secrets.VAULT }}/test-secret/test-section/password
|
||||||
MULTILINE_SECRET: op://${{ secrets.VAULT }}/multiline-secret/notesPlain
|
MULTILINE_SECRET: op://${{ secrets.VAULT }}/multiline-secret/notesPlain
|
||||||
|
TEST_SSH_KEY: op://${{ secrets.VAULT }}/test-ssh-key/private key
|
||||||
|
TEST_SSH_KEY_OPENSSH: "op://${{ secrets.VAULT }}/test-ssh-key/private key?ssh-format=openssh"
|
||||||
OP_ENV_FILE: ./tests/.env.tpl
|
OP_ENV_FILE: ./tests/.env.tpl
|
||||||
|
|
||||||
- name: Assert test secret values [step output]
|
- name: Assert test secret values [step output]
|
||||||
if: ${{ !matrix.export-env }}
|
if: ${{ !matrix.export-env }}
|
||||||
env:
|
env:
|
||||||
|
ASSERT_WEBSITE: "false"
|
||||||
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
|
SECRET: ${{ steps.load_secrets.outputs.SECRET }}
|
||||||
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
|
SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.SECRET_IN_SECTION }}
|
||||||
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
|
MULTILINE_SECRET: ${{ steps.load_secrets.outputs.MULTILINE_SECRET }}
|
||||||
FILE_SECRET: ${{ steps.load_secrets.outputs.FILE_SECRET }}
|
FILE_SECRET: ${{ steps.load_secrets.outputs.FILE_SECRET }}
|
||||||
FILE_SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.FILE_SECRET_IN_SECTION }}
|
FILE_SECRET_IN_SECTION: ${{ steps.load_secrets.outputs.FILE_SECRET_IN_SECTION }}
|
||||||
FILE_MULTILINE_SECRET: ${{ steps.load_secrets.outputs.FILE_MULTILINE_SECRET }}
|
FILE_MULTILINE_SECRET: ${{ steps.load_secrets.outputs.FILE_MULTILINE_SECRET }}
|
||||||
|
TEST_SSH_KEY: ${{ steps.load_secrets.outputs.TEST_SSH_KEY }}
|
||||||
|
FILE_TEST_SSH_KEY: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY }}
|
||||||
|
TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.TEST_SSH_KEY_OPENSSH }}
|
||||||
|
FILE_TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY_OPENSSH }}
|
||||||
run: ./tests/assert-env-set.sh
|
run: ./tests/assert-env-set.sh
|
||||||
|
|
||||||
|
- name: Assert SSH key env vars [step output]
|
||||||
|
if: ${{ !matrix.export-env }}
|
||||||
|
env:
|
||||||
|
TEST_SSH_KEY: ${{ steps.load_secrets.outputs.TEST_SSH_KEY }}
|
||||||
|
FILE_TEST_SSH_KEY: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY }}
|
||||||
|
TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.TEST_SSH_KEY_OPENSSH }}
|
||||||
|
FILE_TEST_SSH_KEY_OPENSSH: ${{ steps.load_secrets.outputs.FILE_TEST_SSH_KEY_OPENSSH }}
|
||||||
|
run: ./tests/assert-ssh-keys-set.sh
|
||||||
|
|
||||||
- name: Assert test secret values [exported env]
|
- name: Assert test secret values [exported env]
|
||||||
if: ${{ matrix.export-env }}
|
if: ${{ matrix.export-env }}
|
||||||
|
env:
|
||||||
|
ASSERT_WEBSITE: "false"
|
||||||
run: ./tests/assert-env-set.sh
|
run: ./tests/assert-env-set.sh
|
||||||
|
|
||||||
|
- name: Assert SSH key env vars [exported env]
|
||||||
|
if: ${{ matrix.export-env }}
|
||||||
|
run: ./tests/assert-ssh-keys-set.sh
|
||||||
|
|
||||||
- name: Remove secrets [exported env]
|
- name: Remove secrets [exported env]
|
||||||
if: ${{ matrix.export-env }}
|
if: ${{ matrix.export-env }}
|
||||||
uses: ./
|
uses: ./
|
||||||
|
|||||||
4
.github/workflows/lint-and-test.yml
vendored
4
.github/workflows/lint-and-test.yml
vendored
@@ -18,9 +18,9 @@ jobs:
|
|||||||
.husky
|
.husky
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 24
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Load secret
|
- name: Load secret
|
||||||
id: load_secrets
|
id: load_secrets
|
||||||
uses: 1password/load-secrets-action@v3
|
uses: 1password/load-secrets-action@v4
|
||||||
env:
|
env:
|
||||||
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||||
SECRET: op://app-cicd/hello-world/secret
|
SECRET: op://app-cicd/hello-world/secret
|
||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Load secret
|
- name: Load secret
|
||||||
uses: 1password/load-secrets-action@v3
|
uses: 1password/load-secrets-action@v4
|
||||||
with:
|
with:
|
||||||
# Export loaded secrets as environment variables
|
# Export loaded secrets as environment variables
|
||||||
export-env: true
|
export-env: true
|
||||||
@@ -77,7 +77,7 @@ When loading SSH keys, you can specify the format using the `ssh-format` query p
|
|||||||
|
|
||||||
```yml
|
```yml
|
||||||
- name: Load SSH key
|
- name: Load SSH key
|
||||||
uses: 1password/load-secrets-action@v3
|
uses: 1password/load-secrets-action@v4
|
||||||
env:
|
env:
|
||||||
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
|
||||||
# Load SSH private key in OpenSSH format
|
# Load SSH private key in OpenSSH format
|
||||||
|
|||||||
@@ -15,5 +15,5 @@ inputs:
|
|||||||
description: Specify which 1Password CLI version to install. Defaults to "latest".
|
description: Specify which 1Password CLI version to install. Defaults to "latest".
|
||||||
default: "latest"
|
default: "latest"
|
||||||
runs:
|
runs:
|
||||||
using: "node20"
|
using: "node24"
|
||||||
main: "dist/index.js"
|
main: "dist/index.js"
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ inputs:
|
|||||||
service-account-token:
|
service-account-token:
|
||||||
description: Your 1Password service account token
|
description: Your 1Password service account token
|
||||||
runs:
|
runs:
|
||||||
using: "node20"
|
using: "node24"
|
||||||
main: "dist/index.js"
|
main: "dist/index.js"
|
||||||
|
|||||||
112
configure/dist/index.js
vendored
112
configure/dist/index.js
vendored
@@ -2942,6 +2942,24 @@ class SecureProxyConnectionError extends UndiciError {
|
|||||||
[kSecureProxyConnectionError] = true
|
[kSecureProxyConnectionError] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const kMessageSizeExceededError = Symbol.for('undici.error.UND_ERR_WS_MESSAGE_SIZE_EXCEEDED')
|
||||||
|
class MessageSizeExceededError extends UndiciError {
|
||||||
|
constructor (message) {
|
||||||
|
super(message)
|
||||||
|
this.name = 'MessageSizeExceededError'
|
||||||
|
this.message = message || 'Max decompressed message size exceeded'
|
||||||
|
this.code = 'UND_ERR_WS_MESSAGE_SIZE_EXCEEDED'
|
||||||
|
}
|
||||||
|
|
||||||
|
static [Symbol.hasInstance] (instance) {
|
||||||
|
return instance && instance[kMessageSizeExceededError] === true
|
||||||
|
}
|
||||||
|
|
||||||
|
get [kMessageSizeExceededError] () {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
AbortError,
|
AbortError,
|
||||||
HTTPParserError,
|
HTTPParserError,
|
||||||
@@ -2965,7 +2983,8 @@ module.exports = {
|
|||||||
ResponseExceededMaxSizeError,
|
ResponseExceededMaxSizeError,
|
||||||
RequestRetryError,
|
RequestRetryError,
|
||||||
ResponseError,
|
ResponseError,
|
||||||
SecureProxyConnectionError
|
SecureProxyConnectionError,
|
||||||
|
MessageSizeExceededError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3043,6 +3062,10 @@ class Request {
|
|||||||
throw new InvalidArgumentError('upgrade must be a string')
|
throw new InvalidArgumentError('upgrade must be a string')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (upgrade && !isValidHeaderValue(upgrade)) {
|
||||||
|
throw new InvalidArgumentError('invalid upgrade header')
|
||||||
|
}
|
||||||
|
|
||||||
if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) {
|
if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) {
|
||||||
throw new InvalidArgumentError('invalid headersTimeout')
|
throw new InvalidArgumentError('invalid headersTimeout')
|
||||||
}
|
}
|
||||||
@@ -3337,13 +3360,19 @@ function processHeader (request, key, val) {
|
|||||||
val = `${val}`
|
val = `${val}`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.host === null && headerName === 'host') {
|
if (headerName === 'host') {
|
||||||
|
if (request.host !== null) {
|
||||||
|
throw new InvalidArgumentError('duplicate host header')
|
||||||
|
}
|
||||||
if (typeof val !== 'string') {
|
if (typeof val !== 'string') {
|
||||||
throw new InvalidArgumentError('invalid host header')
|
throw new InvalidArgumentError('invalid host header')
|
||||||
}
|
}
|
||||||
// Consumed by Client
|
// Consumed by Client
|
||||||
request.host = val
|
request.host = val
|
||||||
} else if (request.contentLength === null && headerName === 'content-length') {
|
} else if (headerName === 'content-length') {
|
||||||
|
if (request.contentLength !== null) {
|
||||||
|
throw new InvalidArgumentError('duplicate content-length header')
|
||||||
|
}
|
||||||
request.contentLength = parseInt(val, 10)
|
request.contentLength = parseInt(val, 10)
|
||||||
if (!Number.isFinite(request.contentLength)) {
|
if (!Number.isFinite(request.contentLength)) {
|
||||||
throw new InvalidArgumentError('invalid content-length header')
|
throw new InvalidArgumentError('invalid content-length header')
|
||||||
@@ -26134,17 +26163,30 @@ module.exports = {
|
|||||||
|
|
||||||
const { createInflateRaw, Z_DEFAULT_WINDOWBITS } = __nccwpck_require__(8522)
|
const { createInflateRaw, Z_DEFAULT_WINDOWBITS } = __nccwpck_require__(8522)
|
||||||
const { isValidClientWindowBits } = __nccwpck_require__(8625)
|
const { isValidClientWindowBits } = __nccwpck_require__(8625)
|
||||||
|
const { MessageSizeExceededError } = __nccwpck_require__(8707)
|
||||||
|
|
||||||
const tail = Buffer.from([0x00, 0x00, 0xff, 0xff])
|
const tail = Buffer.from([0x00, 0x00, 0xff, 0xff])
|
||||||
const kBuffer = Symbol('kBuffer')
|
const kBuffer = Symbol('kBuffer')
|
||||||
const kLength = Symbol('kLength')
|
const kLength = Symbol('kLength')
|
||||||
|
|
||||||
|
// Default maximum decompressed message size: 4 MB
|
||||||
|
const kDefaultMaxDecompressedSize = 4 * 1024 * 1024
|
||||||
|
|
||||||
class PerMessageDeflate {
|
class PerMessageDeflate {
|
||||||
/** @type {import('node:zlib').InflateRaw} */
|
/** @type {import('node:zlib').InflateRaw} */
|
||||||
#inflate
|
#inflate
|
||||||
|
|
||||||
#options = {}
|
#options = {}
|
||||||
|
|
||||||
|
/** @type {boolean} */
|
||||||
|
#aborted = false
|
||||||
|
|
||||||
|
/** @type {Function|null} */
|
||||||
|
#currentCallback = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Map<string, string>} extensions
|
||||||
|
*/
|
||||||
constructor (extensions) {
|
constructor (extensions) {
|
||||||
this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover')
|
this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover')
|
||||||
this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits')
|
this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits')
|
||||||
@@ -26156,6 +26198,11 @@ class PerMessageDeflate {
|
|||||||
// payload of the message.
|
// payload of the message.
|
||||||
// 2. Decompress the resulting data using DEFLATE.
|
// 2. Decompress the resulting data using DEFLATE.
|
||||||
|
|
||||||
|
if (this.#aborted) {
|
||||||
|
callback(new MessageSizeExceededError())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.#inflate) {
|
if (!this.#inflate) {
|
||||||
let windowBits = Z_DEFAULT_WINDOWBITS
|
let windowBits = Z_DEFAULT_WINDOWBITS
|
||||||
|
|
||||||
@@ -26168,13 +26215,37 @@ class PerMessageDeflate {
|
|||||||
windowBits = Number.parseInt(this.#options.serverMaxWindowBits)
|
windowBits = Number.parseInt(this.#options.serverMaxWindowBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#inflate = createInflateRaw({ windowBits })
|
try {
|
||||||
|
this.#inflate = createInflateRaw({ windowBits })
|
||||||
|
} catch (err) {
|
||||||
|
callback(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
this.#inflate[kBuffer] = []
|
this.#inflate[kBuffer] = []
|
||||||
this.#inflate[kLength] = 0
|
this.#inflate[kLength] = 0
|
||||||
|
|
||||||
this.#inflate.on('data', (data) => {
|
this.#inflate.on('data', (data) => {
|
||||||
this.#inflate[kBuffer].push(data)
|
if (this.#aborted) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.#inflate[kLength] += data.length
|
this.#inflate[kLength] += data.length
|
||||||
|
|
||||||
|
if (this.#inflate[kLength] > kDefaultMaxDecompressedSize) {
|
||||||
|
this.#aborted = true
|
||||||
|
this.#inflate.removeAllListeners()
|
||||||
|
this.#inflate.destroy()
|
||||||
|
this.#inflate = null
|
||||||
|
|
||||||
|
if (this.#currentCallback) {
|
||||||
|
const cb = this.#currentCallback
|
||||||
|
this.#currentCallback = null
|
||||||
|
cb(new MessageSizeExceededError())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#inflate[kBuffer].push(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.#inflate.on('error', (err) => {
|
this.#inflate.on('error', (err) => {
|
||||||
@@ -26183,16 +26254,22 @@ class PerMessageDeflate {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#currentCallback = callback
|
||||||
this.#inflate.write(chunk)
|
this.#inflate.write(chunk)
|
||||||
if (fin) {
|
if (fin) {
|
||||||
this.#inflate.write(tail)
|
this.#inflate.write(tail)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#inflate.flush(() => {
|
this.#inflate.flush(() => {
|
||||||
|
if (this.#aborted || !this.#inflate) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength])
|
const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength])
|
||||||
|
|
||||||
this.#inflate[kBuffer].length = 0
|
this.#inflate[kBuffer].length = 0
|
||||||
this.#inflate[kLength] = 0
|
this.#inflate[kLength] = 0
|
||||||
|
this.#currentCallback = null
|
||||||
|
|
||||||
callback(null, full)
|
callback(null, full)
|
||||||
})
|
})
|
||||||
@@ -26247,6 +26324,10 @@ class ByteParser extends Writable {
|
|||||||
/** @type {Map<string, PerMessageDeflate>} */
|
/** @type {Map<string, PerMessageDeflate>} */
|
||||||
#extensions
|
#extensions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import('./websocket').WebSocket} ws
|
||||||
|
* @param {Map<string, string>|null} extensions
|
||||||
|
*/
|
||||||
constructor (ws, extensions) {
|
constructor (ws, extensions) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
@@ -26389,6 +26470,7 @@ class ByteParser extends Writable {
|
|||||||
|
|
||||||
const buffer = this.consume(8)
|
const buffer = this.consume(8)
|
||||||
const upper = buffer.readUInt32BE(0)
|
const upper = buffer.readUInt32BE(0)
|
||||||
|
const lower = buffer.readUInt32BE(4)
|
||||||
|
|
||||||
// 2^31 is the maximum bytes an arraybuffer can contain
|
// 2^31 is the maximum bytes an arraybuffer can contain
|
||||||
// on 32-bit systems. Although, on 64-bit systems, this is
|
// on 32-bit systems. Although, on 64-bit systems, this is
|
||||||
@@ -26396,14 +26478,12 @@ class ByteParser extends Writable {
|
|||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length
|
||||||
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275
|
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275
|
||||||
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e
|
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e
|
||||||
if (upper > 2 ** 31 - 1) {
|
if (upper !== 0 || lower > 2 ** 31 - 1) {
|
||||||
failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.')
|
failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const lower = buffer.readUInt32BE(4)
|
this.#info.payloadLength = lower
|
||||||
|
|
||||||
this.#info.payloadLength = (upper << 8) + lower
|
|
||||||
this.#state = parserStates.READ_DATA
|
this.#state = parserStates.READ_DATA
|
||||||
} else if (this.#state === parserStates.READ_DATA) {
|
} else if (this.#state === parserStates.READ_DATA) {
|
||||||
if (this.#byteOffset < this.#info.payloadLength) {
|
if (this.#byteOffset < this.#info.payloadLength) {
|
||||||
@@ -26433,7 +26513,7 @@ class ByteParser extends Writable {
|
|||||||
} else {
|
} else {
|
||||||
this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => {
|
this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
closeWebSocketConnection(this.ws, 1007, error.message, error.message.length)
|
failWebsocketConnection(this.ws, error.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27040,6 +27120,12 @@ function parseExtensions (extensions) {
|
|||||||
* @param {string} value
|
* @param {string} value
|
||||||
*/
|
*/
|
||||||
function isValidClientWindowBits (value) {
|
function isValidClientWindowBits (value) {
|
||||||
|
// Must have at least one character
|
||||||
|
if (value.length === 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check all characters are ASCII digits
|
||||||
for (let i = 0; i < value.length; i++) {
|
for (let i = 0; i < value.length; i++) {
|
||||||
const byte = value.charCodeAt(i)
|
const byte = value.charCodeAt(i)
|
||||||
|
|
||||||
@@ -27048,7 +27134,9 @@ function isValidClientWindowBits (value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
// Check numeric range: zlib requires windowBits in range 8-15
|
||||||
|
const num = Number.parseInt(value, 10)
|
||||||
|
return num >= 8 && num <= 15
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://nodejs.org/api/intl.html#detecting-internationalization-support
|
// https://nodejs.org/api/intl.html#detecting-internationalization-support
|
||||||
@@ -27527,7 +27615,7 @@ class WebSocket extends EventTarget {
|
|||||||
* @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol
|
* @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol
|
||||||
*/
|
*/
|
||||||
#onConnectionEstablished (response, parsedExtensions) {
|
#onConnectionEstablished (response, parsedExtensions) {
|
||||||
// processResponse is called when the "response’s header list has been received and initialized."
|
// processResponse is called when the "response's header list has been received and initialized."
|
||||||
// once this happens, the connection is open
|
// once this happens, the connection is open
|
||||||
this[kResponse] = response
|
this[kResponse] = response
|
||||||
|
|
||||||
|
|||||||
114
dist/index.js
vendored
114
dist/index.js
vendored
@@ -6261,6 +6261,24 @@ class SecureProxyConnectionError extends UndiciError {
|
|||||||
[kSecureProxyConnectionError] = true
|
[kSecureProxyConnectionError] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const kMessageSizeExceededError = Symbol.for('undici.error.UND_ERR_WS_MESSAGE_SIZE_EXCEEDED')
|
||||||
|
class MessageSizeExceededError extends UndiciError {
|
||||||
|
constructor (message) {
|
||||||
|
super(message)
|
||||||
|
this.name = 'MessageSizeExceededError'
|
||||||
|
this.message = message || 'Max decompressed message size exceeded'
|
||||||
|
this.code = 'UND_ERR_WS_MESSAGE_SIZE_EXCEEDED'
|
||||||
|
}
|
||||||
|
|
||||||
|
static [Symbol.hasInstance] (instance) {
|
||||||
|
return instance && instance[kMessageSizeExceededError] === true
|
||||||
|
}
|
||||||
|
|
||||||
|
get [kMessageSizeExceededError] () {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
AbortError,
|
AbortError,
|
||||||
HTTPParserError,
|
HTTPParserError,
|
||||||
@@ -6284,7 +6302,8 @@ module.exports = {
|
|||||||
ResponseExceededMaxSizeError,
|
ResponseExceededMaxSizeError,
|
||||||
RequestRetryError,
|
RequestRetryError,
|
||||||
ResponseError,
|
ResponseError,
|
||||||
SecureProxyConnectionError
|
SecureProxyConnectionError,
|
||||||
|
MessageSizeExceededError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6362,6 +6381,10 @@ class Request {
|
|||||||
throw new InvalidArgumentError('upgrade must be a string')
|
throw new InvalidArgumentError('upgrade must be a string')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (upgrade && !isValidHeaderValue(upgrade)) {
|
||||||
|
throw new InvalidArgumentError('invalid upgrade header')
|
||||||
|
}
|
||||||
|
|
||||||
if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) {
|
if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) {
|
||||||
throw new InvalidArgumentError('invalid headersTimeout')
|
throw new InvalidArgumentError('invalid headersTimeout')
|
||||||
}
|
}
|
||||||
@@ -6656,13 +6679,19 @@ function processHeader (request, key, val) {
|
|||||||
val = `${val}`
|
val = `${val}`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.host === null && headerName === 'host') {
|
if (headerName === 'host') {
|
||||||
|
if (request.host !== null) {
|
||||||
|
throw new InvalidArgumentError('duplicate host header')
|
||||||
|
}
|
||||||
if (typeof val !== 'string') {
|
if (typeof val !== 'string') {
|
||||||
throw new InvalidArgumentError('invalid host header')
|
throw new InvalidArgumentError('invalid host header')
|
||||||
}
|
}
|
||||||
// Consumed by Client
|
// Consumed by Client
|
||||||
request.host = val
|
request.host = val
|
||||||
} else if (request.contentLength === null && headerName === 'content-length') {
|
} else if (headerName === 'content-length') {
|
||||||
|
if (request.contentLength !== null) {
|
||||||
|
throw new InvalidArgumentError('duplicate content-length header')
|
||||||
|
}
|
||||||
request.contentLength = parseInt(val, 10)
|
request.contentLength = parseInt(val, 10)
|
||||||
if (!Number.isFinite(request.contentLength)) {
|
if (!Number.isFinite(request.contentLength)) {
|
||||||
throw new InvalidArgumentError('invalid content-length header')
|
throw new InvalidArgumentError('invalid content-length header')
|
||||||
@@ -29453,17 +29482,30 @@ module.exports = {
|
|||||||
|
|
||||||
const { createInflateRaw, Z_DEFAULT_WINDOWBITS } = __nccwpck_require__(8522)
|
const { createInflateRaw, Z_DEFAULT_WINDOWBITS } = __nccwpck_require__(8522)
|
||||||
const { isValidClientWindowBits } = __nccwpck_require__(8625)
|
const { isValidClientWindowBits } = __nccwpck_require__(8625)
|
||||||
|
const { MessageSizeExceededError } = __nccwpck_require__(8707)
|
||||||
|
|
||||||
const tail = Buffer.from([0x00, 0x00, 0xff, 0xff])
|
const tail = Buffer.from([0x00, 0x00, 0xff, 0xff])
|
||||||
const kBuffer = Symbol('kBuffer')
|
const kBuffer = Symbol('kBuffer')
|
||||||
const kLength = Symbol('kLength')
|
const kLength = Symbol('kLength')
|
||||||
|
|
||||||
|
// Default maximum decompressed message size: 4 MB
|
||||||
|
const kDefaultMaxDecompressedSize = 4 * 1024 * 1024
|
||||||
|
|
||||||
class PerMessageDeflate {
|
class PerMessageDeflate {
|
||||||
/** @type {import('node:zlib').InflateRaw} */
|
/** @type {import('node:zlib').InflateRaw} */
|
||||||
#inflate
|
#inflate
|
||||||
|
|
||||||
#options = {}
|
#options = {}
|
||||||
|
|
||||||
|
/** @type {boolean} */
|
||||||
|
#aborted = false
|
||||||
|
|
||||||
|
/** @type {Function|null} */
|
||||||
|
#currentCallback = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Map<string, string>} extensions
|
||||||
|
*/
|
||||||
constructor (extensions) {
|
constructor (extensions) {
|
||||||
this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover')
|
this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover')
|
||||||
this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits')
|
this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits')
|
||||||
@@ -29475,6 +29517,11 @@ class PerMessageDeflate {
|
|||||||
// payload of the message.
|
// payload of the message.
|
||||||
// 2. Decompress the resulting data using DEFLATE.
|
// 2. Decompress the resulting data using DEFLATE.
|
||||||
|
|
||||||
|
if (this.#aborted) {
|
||||||
|
callback(new MessageSizeExceededError())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.#inflate) {
|
if (!this.#inflate) {
|
||||||
let windowBits = Z_DEFAULT_WINDOWBITS
|
let windowBits = Z_DEFAULT_WINDOWBITS
|
||||||
|
|
||||||
@@ -29487,13 +29534,37 @@ class PerMessageDeflate {
|
|||||||
windowBits = Number.parseInt(this.#options.serverMaxWindowBits)
|
windowBits = Number.parseInt(this.#options.serverMaxWindowBits)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#inflate = createInflateRaw({ windowBits })
|
try {
|
||||||
|
this.#inflate = createInflateRaw({ windowBits })
|
||||||
|
} catch (err) {
|
||||||
|
callback(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
this.#inflate[kBuffer] = []
|
this.#inflate[kBuffer] = []
|
||||||
this.#inflate[kLength] = 0
|
this.#inflate[kLength] = 0
|
||||||
|
|
||||||
this.#inflate.on('data', (data) => {
|
this.#inflate.on('data', (data) => {
|
||||||
this.#inflate[kBuffer].push(data)
|
if (this.#aborted) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.#inflate[kLength] += data.length
|
this.#inflate[kLength] += data.length
|
||||||
|
|
||||||
|
if (this.#inflate[kLength] > kDefaultMaxDecompressedSize) {
|
||||||
|
this.#aborted = true
|
||||||
|
this.#inflate.removeAllListeners()
|
||||||
|
this.#inflate.destroy()
|
||||||
|
this.#inflate = null
|
||||||
|
|
||||||
|
if (this.#currentCallback) {
|
||||||
|
const cb = this.#currentCallback
|
||||||
|
this.#currentCallback = null
|
||||||
|
cb(new MessageSizeExceededError())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#inflate[kBuffer].push(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.#inflate.on('error', (err) => {
|
this.#inflate.on('error', (err) => {
|
||||||
@@ -29502,16 +29573,22 @@ class PerMessageDeflate {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.#currentCallback = callback
|
||||||
this.#inflate.write(chunk)
|
this.#inflate.write(chunk)
|
||||||
if (fin) {
|
if (fin) {
|
||||||
this.#inflate.write(tail)
|
this.#inflate.write(tail)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#inflate.flush(() => {
|
this.#inflate.flush(() => {
|
||||||
|
if (this.#aborted || !this.#inflate) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength])
|
const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength])
|
||||||
|
|
||||||
this.#inflate[kBuffer].length = 0
|
this.#inflate[kBuffer].length = 0
|
||||||
this.#inflate[kLength] = 0
|
this.#inflate[kLength] = 0
|
||||||
|
this.#currentCallback = null
|
||||||
|
|
||||||
callback(null, full)
|
callback(null, full)
|
||||||
})
|
})
|
||||||
@@ -29566,6 +29643,10 @@ class ByteParser extends Writable {
|
|||||||
/** @type {Map<string, PerMessageDeflate>} */
|
/** @type {Map<string, PerMessageDeflate>} */
|
||||||
#extensions
|
#extensions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import('./websocket').WebSocket} ws
|
||||||
|
* @param {Map<string, string>|null} extensions
|
||||||
|
*/
|
||||||
constructor (ws, extensions) {
|
constructor (ws, extensions) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
@@ -29708,6 +29789,7 @@ class ByteParser extends Writable {
|
|||||||
|
|
||||||
const buffer = this.consume(8)
|
const buffer = this.consume(8)
|
||||||
const upper = buffer.readUInt32BE(0)
|
const upper = buffer.readUInt32BE(0)
|
||||||
|
const lower = buffer.readUInt32BE(4)
|
||||||
|
|
||||||
// 2^31 is the maximum bytes an arraybuffer can contain
|
// 2^31 is the maximum bytes an arraybuffer can contain
|
||||||
// on 32-bit systems. Although, on 64-bit systems, this is
|
// on 32-bit systems. Although, on 64-bit systems, this is
|
||||||
@@ -29715,14 +29797,12 @@ class ByteParser extends Writable {
|
|||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length
|
||||||
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275
|
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275
|
||||||
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e
|
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e
|
||||||
if (upper > 2 ** 31 - 1) {
|
if (upper !== 0 || lower > 2 ** 31 - 1) {
|
||||||
failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.')
|
failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const lower = buffer.readUInt32BE(4)
|
this.#info.payloadLength = lower
|
||||||
|
|
||||||
this.#info.payloadLength = (upper << 8) + lower
|
|
||||||
this.#state = parserStates.READ_DATA
|
this.#state = parserStates.READ_DATA
|
||||||
} else if (this.#state === parserStates.READ_DATA) {
|
} else if (this.#state === parserStates.READ_DATA) {
|
||||||
if (this.#byteOffset < this.#info.payloadLength) {
|
if (this.#byteOffset < this.#info.payloadLength) {
|
||||||
@@ -29752,7 +29832,7 @@ class ByteParser extends Writable {
|
|||||||
} else {
|
} else {
|
||||||
this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => {
|
this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
closeWebSocketConnection(this.ws, 1007, error.message, error.message.length)
|
failWebsocketConnection(this.ws, error.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30359,6 +30439,12 @@ function parseExtensions (extensions) {
|
|||||||
* @param {string} value
|
* @param {string} value
|
||||||
*/
|
*/
|
||||||
function isValidClientWindowBits (value) {
|
function isValidClientWindowBits (value) {
|
||||||
|
// Must have at least one character
|
||||||
|
if (value.length === 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check all characters are ASCII digits
|
||||||
for (let i = 0; i < value.length; i++) {
|
for (let i = 0; i < value.length; i++) {
|
||||||
const byte = value.charCodeAt(i)
|
const byte = value.charCodeAt(i)
|
||||||
|
|
||||||
@@ -30367,7 +30453,9 @@ function isValidClientWindowBits (value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
// Check numeric range: zlib requires windowBits in range 8-15
|
||||||
|
const num = Number.parseInt(value, 10)
|
||||||
|
return num >= 8 && num <= 15
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://nodejs.org/api/intl.html#detecting-internationalization-support
|
// https://nodejs.org/api/intl.html#detecting-internationalization-support
|
||||||
@@ -30846,7 +30934,7 @@ class WebSocket extends EventTarget {
|
|||||||
* @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol
|
* @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol
|
||||||
*/
|
*/
|
||||||
#onConnectionEstablished (response, parsedExtensions) {
|
#onConnectionEstablished (response, parsedExtensions) {
|
||||||
// processResponse is called when the "response’s header list has been received and initialized."
|
// processResponse is called when the "response's header list has been received and initialized."
|
||||||
// once this happens, the connection is open
|
// once this happens, the connection is open
|
||||||
this[kResponse] = response
|
this[kResponse] = response
|
||||||
|
|
||||||
@@ -35385,7 +35473,7 @@ const installCliOnGithubActionRunner = async (version) => {
|
|||||||
|
|
||||||
|
|
||||||
;// CONCATENATED MODULE: ./package.json
|
;// CONCATENATED MODULE: ./package.json
|
||||||
const package_namespaceObject = {"rE":"3.2.1"};
|
const package_namespaceObject = {"rE":"4.0.0"};
|
||||||
;// CONCATENATED MODULE: ./src/constants.ts
|
;// CONCATENATED MODULE: ./src/constants.ts
|
||||||
const envConnectHost = "OP_CONNECT_HOST";
|
const envConnectHost = "OP_CONNECT_HOST";
|
||||||
const envConnectToken = "OP_CONNECT_TOKEN";
|
const envConnectToken = "OP_CONNECT_TOKEN";
|
||||||
|
|||||||
103
package-lock.json
generated
103
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "load-secrets-action",
|
"name": "load-secrets-action",
|
||||||
"version": "3.2.1",
|
"version": "4.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "load-secrets-action",
|
"name": "load-secrets-action",
|
||||||
"version": "3.2.1",
|
"version": "4.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@1password/op-js": "^0.1.11",
|
"@1password/op-js": "^0.1.11",
|
||||||
@@ -1556,32 +1556,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
|
||||||
"version": "2.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
|
||||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"balanced-match": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
|
||||||
"version": "9.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
|
||||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16 || 14 >=14.17"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "6.21.0",
|
"version": "6.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
|
||||||
@@ -1670,11 +1644,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ajv": {
|
"node_modules/ajv": {
|
||||||
"version": "6.12.6",
|
"version": "6.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
|
||||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
"integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
@@ -2116,14 +2089,13 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0"
|
||||||
"concat-map": "0.0.1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
@@ -2503,13 +2475,6 @@
|
|||||||
"node": ">= 12.0.0"
|
"node": ">= 12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/concat-map": {
|
|
||||||
"version": "0.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
|
||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/convert-source-map": {
|
"node_modules/convert-source-map": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||||
@@ -3733,29 +3698,6 @@
|
|||||||
"minimatch": "^5.0.1"
|
"minimatch": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/filelist/node_modules/brace-expansion": {
|
|
||||||
"version": "2.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
|
||||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"balanced-match": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/filelist/node_modules/minimatch": {
|
|
||||||
"version": "5.1.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
|
||||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
@@ -3800,11 +3742,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flatted": {
|
"node_modules/flatted": {
|
||||||
"version": "3.3.2",
|
"version": "3.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||||
"integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
|
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/for-each": {
|
"node_modules/for-each": {
|
||||||
@@ -6178,16 +6119,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimatch": {
|
"node_modules/minimatch": {
|
||||||
"version": "3.1.2",
|
"version": "9.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^2.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "*"
|
"node": ">=16 || 14 >=14.17"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/minimist": {
|
"node_modules/minimist": {
|
||||||
@@ -7874,10 +7818,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "6.23.0",
|
"version": "6.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
|
||||||
"integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==",
|
"integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.17"
|
"node": ">=18.17"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "load-secrets-action",
|
"name": "load-secrets-action",
|
||||||
"version": "3.2.1",
|
"version": "4.0.0",
|
||||||
"description": "Load Secrets from 1Password",
|
"description": "Load Secrets from 1Password",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -46,6 +46,9 @@
|
|||||||
"@actions/tool-cache": "^4.0.0",
|
"@actions/tool-cache": "^4.0.0",
|
||||||
"dotenv": "^17.2.2"
|
"dotenv": "^17.2.2"
|
||||||
},
|
},
|
||||||
|
"overrides": {
|
||||||
|
"minimatch": "^9.0.7"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@1password/eslint-config": "^4.3.1",
|
"@1password/eslint-config": "^4.3.1",
|
||||||
"@1password/prettier-config": "^1.2.0",
|
"@1password/prettier-config": "^1.2.0",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ IApTbyBwbGVhc2UgZG9uJ3QgcmVwb3J0IGl0IQo=
|
|||||||
EOF
|
EOF
|
||||||
)"
|
)"
|
||||||
readonly MULTILINE_SECRET
|
readonly MULTILINE_SECRET
|
||||||
|
readonly WEBSITE="www.test.com"
|
||||||
|
|
||||||
assert_env_equals "SECRET" "${SECRET}"
|
assert_env_equals "SECRET" "${SECRET}"
|
||||||
assert_env_equals "FILE_SECRET" "${SECRET}"
|
assert_env_equals "FILE_SECRET" "${SECRET}"
|
||||||
@@ -35,3 +36,9 @@ assert_env_equals "FILE_SECRET_IN_SECTION" "${SECRET}"
|
|||||||
|
|
||||||
assert_env_equals "MULTILINE_SECRET" "${MULTILINE_SECRET}"
|
assert_env_equals "MULTILINE_SECRET" "${MULTILINE_SECRET}"
|
||||||
assert_env_equals "FILE_MULTILINE_SECRET" "${MULTILINE_SECRET}"
|
assert_env_equals "FILE_MULTILINE_SECRET" "${MULTILINE_SECRET}"
|
||||||
|
|
||||||
|
# WEBSITE/FILE_WEBSITE: required when ASSERT_WEBSITE=true (Service Account), skipped when false (Connect)
|
||||||
|
if [ "${ASSERT_WEBSITE:-false}" = "true" ]; then
|
||||||
|
assert_env_equals "WEBSITE" "${WEBSITE}"
|
||||||
|
assert_env_equals "FILE_WEBSITE" "${WEBSITE}"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -17,3 +17,11 @@ assert_env_unset "FILE_SECRET_IN_SECTION"
|
|||||||
|
|
||||||
assert_env_unset "MULTILINE_SECRET"
|
assert_env_unset "MULTILINE_SECRET"
|
||||||
assert_env_unset "FILE_MULTILINE_SECRET"
|
assert_env_unset "FILE_MULTILINE_SECRET"
|
||||||
|
|
||||||
|
assert_env_unset "WEBSITE"
|
||||||
|
assert_env_unset "FILE_WEBSITE"
|
||||||
|
|
||||||
|
assert_env_unset "TEST_SSH_KEY"
|
||||||
|
assert_env_unset "FILE_TEST_SSH_KEY"
|
||||||
|
assert_env_unset "TEST_SSH_KEY_OPENSSH"
|
||||||
|
assert_env_unset "FILE_TEST_SSH_KEY_OPENSSH"
|
||||||
|
|||||||
26
tests/assert-ssh-keys-set.sh
Executable file
26
tests/assert-ssh-keys-set.sh
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
assert_ssh_key_set() {
|
||||||
|
local var="$1"
|
||||||
|
local val
|
||||||
|
val="$(printenv "$var" || true)"
|
||||||
|
if [ -z "$val" ]; then
|
||||||
|
echo "Expected $var to be set"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
[ "$val" = "***" ] && return 0
|
||||||
|
local line
|
||||||
|
line="$(echo "$val" | head -1)"
|
||||||
|
if echo "$var" | grep -q "OPENSSH"; then
|
||||||
|
echo "$line" | grep -q "OPENSSH" || { echo "Expected $var to start with -----BEGIN OPENSSH PRIVATE KEY-----"; exit 1; }
|
||||||
|
else
|
||||||
|
echo "$line" | grep -q "BEGIN.*PRIVATE KEY" || { echo "Expected $var to be a private key"; exit 1; }
|
||||||
|
fi
|
||||||
|
echo "$var OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_ssh_key_set "TEST_SSH_KEY"
|
||||||
|
assert_ssh_key_set "TEST_SSH_KEY_OPENSSH"
|
||||||
|
assert_ssh_key_set "FILE_TEST_SSH_KEY"
|
||||||
|
assert_ssh_key_set "FILE_TEST_SSH_KEY_OPENSSH"
|
||||||
Reference in New Issue
Block a user