Preview: Variablen verschluesselt
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e358514240
commit
20ca1de694
2 files changed
+152
No files matched your search
@@ -0,0 +1,81 @@
|
||||
import { test } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import crypto from 'node:crypto'
|
||||
import {
|
||||
encryptEnv, decryptEnv, validateEnvChange, envNames, maskLog, envKey,
|
||||
} from '../server/services/previewEnv.js'
|
||||
|
||||
const key = crypto.randomBytes(32)
|
||||
|
||||
test('Round-Trip und Format', () => {
|
||||
const s = encryptEnv({ A: 'x', B: 'ü' }, key)
|
||||
assert.match(s, /^v1:[^:]+:[^:]+:[^:]+$/)
|
||||
assert.deepEqual(decryptEnv(s, key), { A: 'x', B: 'ü' })
|
||||
assert.notEqual(encryptEnv({ A: 'x' }, key), encryptEnv({ A: 'x' }, key))
|
||||
})
|
||||
|
||||
test('leer', () => {
|
||||
assert.deepEqual(decryptEnv(encryptEnv({}, key), key), {})
|
||||
assert.deepEqual(decryptEnv('', key), {})
|
||||
assert.deepEqual(decryptEnv(null, key), {})
|
||||
})
|
||||
|
||||
test('falscher Schluessel und manipulierter Tag => Fehler', () => {
|
||||
const s = encryptEnv({ A: 'geheim' }, key)
|
||||
assert.throws(() => decryptEnv(s, crypto.randomBytes(32)))
|
||||
const p = s.split(':')
|
||||
const tag = Buffer.from(p[2], 'base64')
|
||||
tag[0] ^= 1
|
||||
p[2] = tag.toString('base64')
|
||||
assert.throws(() => decryptEnv(p.join(':'), key))
|
||||
assert.throws(() => decryptEnv('v2:a:b:c', key))
|
||||
})
|
||||
|
||||
test('envNames sortiert', () => {
|
||||
assert.deepEqual(envNames(encryptEnv({ B: '1', A: '2' }, key), key), ['A', 'B'])
|
||||
assert.deepEqual(envNames('', key), [])
|
||||
})
|
||||
|
||||
test('envKey', () => {
|
||||
const old = process.env.PREVIEW_ENV_KEY
|
||||
try {
|
||||
delete process.env.PREVIEW_ENV_KEY
|
||||
assert.equal(envKey(), null)
|
||||
process.env.PREVIEW_ENV_KEY = Buffer.alloc(16).toString('base64')
|
||||
assert.equal(envKey(), null)
|
||||
process.env.PREVIEW_ENV_KEY = key.toString('base64')
|
||||
assert.ok(envKey().equals(key))
|
||||
} finally {
|
||||
if (old === undefined) delete process.env.PREVIEW_ENV_KEY
|
||||
else process.env.PREVIEW_ENV_KEY = old
|
||||
}
|
||||
})
|
||||
|
||||
test('validateEnvChange', () => {
|
||||
let r = validateEnvChange({ A: '1' }, { set: { B: '2' }, remove: ['A', 'NIX'] })
|
||||
assert.deepEqual(r, { ok: true, env: { B: '2' } })
|
||||
assert.equal(validateEnvChange({}, { set: { abc: '1' } }).ok, false)
|
||||
assert.equal(validateEnvChange({}, { set: { '1A': '1' } }).ok, false)
|
||||
assert.equal(validateEnvChange({}, { set: { A: 'x'.repeat(4097) } }).ok, false)
|
||||
assert.equal(validateEnvChange({}, { set: { A: 'x'.repeat(4096) } }).ok, true)
|
||||
assert.equal(validateEnvChange({}, { set: { A: 'ü'.repeat(2049) } }).ok, false)
|
||||
assert.equal(validateEnvChange({}, { set: { A: 1 } }).ok, false)
|
||||
assert.equal(validateEnvChange({}, { set: { A: 'a\nb' } }).ok, false)
|
||||
assert.equal(validateEnvChange({}, { set: { A: 'a\0b' } }).ok, false)
|
||||
const many = Object.fromEntries(Array.from({ length: 31 }, (_, i) => [`V${i}`, '1']))
|
||||
r = validateEnvChange({}, { set: many })
|
||||
assert.equal(r.ok, false)
|
||||
assert.match(r.error, /30/)
|
||||
const thirty = Object.fromEntries(Array.from({ length: 30 }, (_, i) => [`V${i}`, '1']))
|
||||
assert.equal(validateEnvChange(thirty, { set: { V0: '2' } }).ok, true)
|
||||
assert.equal(validateEnvChange(thirty, { set: { NEU: '2' }, remove: ['V1'] }).ok, true)
|
||||
assert.equal(validateEnvChange(thirty, { set: { NEU: '2' } }).ok, false)
|
||||
assert.equal(validateEnvChange({}, {}).ok, true)
|
||||
})
|
||||
|
||||
test('maskLog', () => {
|
||||
const env = { A: 'geheim', B: 'abc', C: 'geheimer' , D: 'a.b+'}
|
||||
assert.equal(maskLog('x geheimer y geheim z abc a.b+ axbb', env), 'x ••• y ••• z abc ••• axbb')
|
||||
assert.equal(maskLog('', env), '')
|
||||
assert.equal(maskLog('text', {}), 'text')
|
||||
})
|
||||
Reference in new issue
Block a user