Skip to content

Commit

Permalink
feat: support several target registries
Browse files Browse the repository at this point in the history
closes #62
  • Loading branch information
antongolub committed Oct 4, 2022
1 parent f35c2f8 commit aa06883
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ type TCacheFactory = {
}
type TFirewallConfig = {
registry: string
registry: string | string[]
entrypoint?: string
token?: string
base?: string
Expand Down
2 changes: 1 addition & 1 deletion src/main/js/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const populate = (config) => {

return {
rules,
registry: normalizePath(f.registry),
registry: f.registry ? asArray(f.registry).map(normalizePath) : null,
token: f.token,
entrypoint: f.entrypoint ? normalizePath(f.entrypoint) : null,
base: f.base || '/',
Expand Down
15 changes: 9 additions & 6 deletions src/main/js/firewall/packument.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {getDirectives, getPolicy} from './engine.js'
import {request} from '../http/index.js'
import {makeDeferred} from '../util.js'
import {asArray, makeDeferred, tryQueue} from '../util.js'

export const getPackument = async ({boundContext, rules}) => {
const {cache, registry, authorization, entrypoint, name} = boundContext
Expand All @@ -11,12 +11,12 @@ export const getPackument = async ({boundContext, rules}) => {
cache.add(name, promise)

try {
const {body, headers} = await request({
url: `${registry}/${name}`,
const args = asArray(registry).map(r => [{
url: `${r}/${name}`,
authorization,
'accept-encoding': 'gzip'
})

}])
const {body, headers} = await tryQueue(request, ...args)
const packument = JSON.parse(body)
const directives = await getDirectives({ packument, rules, boundContext})
const _packument = patchPackument({ packument, directives, entrypoint, registry })
Expand All @@ -39,7 +39,10 @@ export const patchVersions = ({packument, directives, entrypoint, registry}) =>
if (getPolicy(directives, v.version) === 'deny') {
return m
}
v.dist.tarball = v.dist.tarball.replace(registry, entrypoint)
asArray(registry).forEach(r => {
v.dist.tarball = v.dist.tarball.replace(r, entrypoint)
})

m[v.version] = v
return m
}, {})
Expand Down
9 changes: 8 additions & 1 deletion src/main/js/firewall/plugins/audit.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {semver} from '../../semver.js'
import {request} from '../../http/index.js'
import {getCache} from '../../cache.js'
import {makeDeferred} from '../../util.js'
import {asArray, makeDeferred, tryQueue} from '../../util.js'

const severityOrder = ['critical', 'high', 'moderate', 'low', 'any' ]

Expand All @@ -16,6 +16,13 @@ export const auditPlugin = async ({entry: {name, version}, options = {}, boundCo
}

const getAdvisories = async (name, registry) => {
const registries = asArray(registry || registry)
const args = registries.map(r => [name, r])

return tryQueue(_getAdvisories, ...args)
}

const _getAdvisories = async (name, registry) => {
const cache = getCache({ name: 'audit', ttl: 120_000 })
if (await cache.has(name)) {
return cache.get(name)
Expand Down
2 changes: 1 addition & 1 deletion src/main/js/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type TCacheFactory = {
}

type TFirewallConfig = {
registry: string
registry: string | string[]
entrypoint?: string
token?: string
base?: string
Expand Down
12 changes: 10 additions & 2 deletions src/main/js/mwares/proxy.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import {request} from '../http/client.js'
import {asArray, tryQueue} from '../util.js'

export const proxy = (registry) => async (req, res) => {
const url = `${registry}${req.url}`
await request({ url, method: req.method, pipe: {req, res}, followRedirects: true})
const registries = asArray(registry)
const args = registries.map(r => [{
url: `${r}${req.url}`,
method: req.method,
pipe: {req, res},
followRedirects: true
}])

return tryQueue(request, ...args)
}
12 changes: 12 additions & 0 deletions src/main/js/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,15 @@ export const mergeDeep = (target, ...sources) => {

return mergeDeep(target, ...sources)
}

export const tryQueue = async (fn, ...args) => {
const results = await Promise.allSettled(args.map(a => fn(...a)))
const success = results.find(r => r.status === 'fulfilled')

if (success) {
return success.value
}

const error = results.find(r => r.status === 'rejected')
return Promise.reject(error.reason)
}
2 changes: 1 addition & 1 deletion src/test/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const app = createApp([{
}, {
server: { port: 3003 },
firewall: {
registry: 'https://registry.yarnpkg.com',
registry: ['https://registry.yarnpkg.com', 'https://registry.npmjs.org'],
rules: { policy: 'deny', name: '*' }
}
}])
Expand Down
17 changes: 16 additions & 1 deletion src/test/js/util.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {testFactory, assert} from '../test-utils.js'
import {flatten, expand} from '../../main/js/util.js'
import {flatten, expand, tryQueue} from '../../main/js/util.js'

const test = testFactory('util', import.meta)

Expand Down Expand Up @@ -27,3 +27,18 @@ test('expand', () => {
baz: [{a: 'a'}, {b: {c: 'd'}}, 1]
})
})

test('tryQueue', async() => {
const fn = async (i) => {
if (i === 0) { throw new Error('broken') }
return i
}

assert.equal(await tryQueue(fn, [0], [0], [3]), 3)

try {
await tryQueue(fn, [0])
} catch (err) {
assert.equal(err.message, 'broken')
}
})

0 comments on commit aa06883

Please sign in to comment.