New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@sbp/sbp

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sbp/sbp - npm Package Compare versions

Comparing version 2.2.0 to 2.3.0

9

docs/language-support.md

@@ -8,4 +8,5 @@ # SBP Language Support

- [sbp-js](https://github.com/okTurtles/sbp-js/) - JavaScript
- [SBP.jl](https://github.com/snowteamer/SBP.jl/) - Julia
## Implementing SBP In Your favorite language
## Implementing SBP In Your Favorite Language

@@ -17,5 +18,9 @@ To implement SBP, you just need to implement the [core SBP API](/docs/sbp-api.md).

- Implementing the core SBP selectors (the `sbp` domain)
- Implementing support for the `_init` domain "constructor" to add domain-specific state. Since most languages do not have the equivalent of a `this` dynamically scoped variable, how you approach implementing the domain-state can be unique and idiomatic to your langauge.
- Making sure that your implementation of the core selectors has the same exact behavior as this one.
- **Exception:** you can ignore all parts of the JS code that have to do with domain-specific state, as that relies on a JS-specific feature. See comment below for more details.
Optional:
- Implementing support for the `_init` domain "constructor" to add domain-specific state. Since most languages do not have the equivalent of a `this` dynamically scoped variable, how you approach implementing the domain-state can be unique and idiomatic to your langauge. **If implementing this feature is awkward, it is best to avoid implementing it at all to avoid unnecessarily exposing state.** Instead, you may encourage users to simply access a variable containing a map/object/dictionary for their state that is scoped in such a way that it is accessible to domain-specific selectors, and inaccessible to other functions.
_Feel free to send us a PR adding your implementation to the list above!_

@@ -19,2 +19,3 @@ # SBP API

- [`'sbp/selectors/lock'`](#sbpselectorslock)
- [`'sbp/domains/lock'`](#sbpdomainslock)
- [`'sbp/filters/global/add'`](#sbpfiltersglobaladd)

@@ -55,3 +56,3 @@ - [`'sbp/filters/domain/add'`](#sbpfiltersdomainadd)

- Function signature: `function (sels: [string])`
- Function signature: `function (sels: string[])`

@@ -96,3 +97,3 @@ Allows you to unregister selectors that were [marked unsafe](#sbpselectorsunsafe).

- Function signature: `function (sels: [string])`
- Function signature: `function (sels: string[])`

@@ -105,14 +106,25 @@ Marks these selectors as overwritable via [`'sbp/selectors/overwrite'`](#sbpselectorsoverwrite).

Remember to call `'sbp/selectors/lock'` after overwriting!
Remember to call `'sbp/selectors/lock'` or `'sbp/domains/lock'` after overwriting!
### `'sbp/selectors/lock'`
- Function signature: `function (sels: [string])`
- Function signature: `function (sels: string[])`
Prevers these selectors from being overwritten again.
Prevents these selectors from being unregistered and overwritten.
Always call this after overwriting selectors unless they're designed to be left unsafe.
Always call either this or `'sbp/domains/lock'` after overwriting selectors unless they're designed to be left unsafe.
Remember that
Once a selector is locked it cannot be unlocked.
### `'sbp/domains/lock'`
- Function signature: `function (domains?: string[])`
If `domains` are passed in, prevents new selectors from being registered on the domains and also prevents existing selectors from being unregistered or overwritten.
If no argument is passed in, locks all currently registered domains.
This selector is ensures that rogue code cannot get access to domain state by registering a new selector on that domain, and therefore is preferred to `'sbp/selectors/lock'`.
Once a domain is locked it cannot be unlocked.
### `'sbp/filters/global/add'`

@@ -119,0 +131,0 @@

# History
#### 2.3.0
- Added `'sbp/domains/lock'`. Stronger protection than `'sbp/selectors/lock'`, prevents rogue code from accessing domain state. h/t **[@snowteamer](https://github.com/okTurtles/sbp-js/pull/4)**
#### 2.2.0

@@ -4,0 +8,0 @@

@@ -5,6 +5,10 @@ // @flow

type Domain = {
locked: boolean;
state: any;
}
type TypeFilter = (domain: string, selector: string, data: any) => ?boolean
const selectors: {[string]: Function} = {}
const domains: {[string]: Object} = {}
const domains: {[string]: Domain} = {}
const globalFilters: Array<TypeFilter> = []

@@ -46,4 +50,8 @@ const domainFilters: {[string]: Array<TypeFilter>} = {}

for (const selector in sels) {
const domain = domainFromSelector(selector)
if (selectors[selector]) {
const domainName = domainFromSelector(selector)
// ensure each domain has a domain state associated with it
const domain = domainName in domains ? domains[domainName] : (domains[domainName] = { state: {}, locked: false })
if (domain.locked) {
(console.warn || console.log)(`[SBP WARN]: not registering selector on locked domain: '${selector}'`)
} else if (selectors[selector]) {
(console.warn || console.log)(`[SBP WARN]: not registering already registered selector: '${selector}'`)

@@ -57,9 +65,5 @@ } else if (typeof sels[selector] === 'function') {

registered.push(selector)
// ensure each domain has a domain state associated with it
if (!domains[domain]) {
domains[domain] = { state: {} }
}
// call the special _init function immediately upon registering
if (selector === `${domain}/_init`) {
fn.call(domains[domain].state)
if (selector === `${domainName}/_init`) {
fn.call(domain.state)
}

@@ -70,3 +74,3 @@ }

},
'sbp/selectors/unregister': function (sels: [string]) {
'sbp/selectors/unregister': function (sels: string[]) {
for (const selector of sels) {

@@ -76,2 +80,5 @@ if (!unsafeSelectors[selector]) {

}
if (domains[domainFromSelector(selector)]?.locked) {
throw new Error(`SBP: can't unregister selector on a locked domain: '${selector}'`)
}
delete selectors[selector]

@@ -84,3 +91,3 @@ }

},
'sbp/selectors/unsafe': function (sels: [string]) {
'sbp/selectors/unsafe': function (sels: string[]) {
for (const selector of sels) {

@@ -93,3 +100,3 @@ if (selectors[selector]) {

},
'sbp/selectors/lock': function (sels: [string]) {
'sbp/selectors/lock': function (sels: string[]) {
for (const selector of sels) {

@@ -112,2 +119,17 @@ delete unsafeSelectors[selector]

selectorFilters[selector].push(filter)
},
'sbp/domains/lock': function (domainNames?: string[]) {
// If no argument was given then locks every known domain.
if (!domainNames) {
for (const name in domains) {
domains[name].locked = true
}
} else {
for (const name of domainNames) {
if (!domains[name]) {
throw new Error(`SBP: cannot lock non-existent domain: ${name}`)
}
domains[name].locked = true
}
}
}

@@ -114,0 +136,0 @@ }

@@ -20,3 +20,3 @@ 'use strict'

'test/safe2': fn,
'test/unsafe' () {}
'test/unsafe' () {},
})

@@ -44,3 +44,38 @@ should(sels).have.length(3)

})
it('should fail to lock a non-existent domain', () => {
should.throws(() => {
sbp('sbp/domains/lock', ['testDomain'])
})
})
it('should lock a given domain', () => {
sbp('sbp/selectors/register', {
'testDomain/s1' () {}
})
sbp('sbp/domains/lock', ['testDomain'])
should(sbp('sbp/selectors/register', { 'testDomain/s2' () {} }).length).equal(0)
})
it('should lock several domains at once', () => {
sbp('sbp/selectors/register', {
'domain1/test' () {},
'domain2/test' () {},
'domain3/test' () {}
})
sbp('sbp/domains/lock', ['domain1', 'domain2'])
should(sbp('sbp/selectors/register', { 'domain1/test2' () {} }).length).equal(0)
should(sbp('sbp/selectors/register', { 'domain2/test2' () {} }).length).equal(0)
// Fo now domain3 should not have been locked.
should(sbp('sbp/selectors/register', { 'domain3/test2' () {} }).length).equal(1)
})
it('should lock all domains at once', () => {
sbp('sbp/domains/lock')
// Now domain3 should also have been locked.
should(sbp('sbp/selectors/register', { 'domain3/test2' () {} }).length).equal(0)
})
it('should not unregister selectors on a locked domain', () => {
sbp('sbp/domains/lock', ['test'])
should.throws(() => {
sbp('sbp/selectors/unregister', 'test/unsafe')
})
})
// TODO: test filters
})
{
"name": "@sbp/sbp",
"version": "2.2.0",
"version": "2.3.0",
"description": "Selector-based Programming: JavaScript Edition",

@@ -5,0 +5,0 @@ "main": "dist/main.cjs",

@@ -67,3 +67,3 @@ # SBP: A Programming Paradigm for Building Secure Software and Operating Systems

// Using SBP:
import sbp from '~/shared/sbp.js'
import sbp from '@sbp/sbp'

@@ -184,2 +184,3 @@ // - call any selector registered

- `'sbp/selectors/lock'`
- `'sbp/domains/lock'`
- `'sbp/filters/global/add'`

@@ -191,2 +192,4 @@ - `'sbp/filters/domain/add'`

- :book: **[SBP Core API](docs/sbp-api.md)**
### SBP Features

@@ -193,0 +196,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc