Space Script

Now that I’m kind of set on the “hacker’s notebook” direction I’m thinking what the next steps are to make SilverBullet more extensible, even without having to write plugs or fork the code.

Here’s something I have working as a prototype, but is a little bit scary in terms of security. The ultimate question here will be: does it matter?

I’d introduce space-script blocks, in which you could write arbitrary JavaScript code that would run in your SB environment (server and/or client).

A few APIs will be offered to hook into various aspects of SilverBullet. The first one is the ability to register custom functions, usable in templates, queries etc.

A basic example:

```space-script
silverbullet.registerFunction("addThree", (a) => {
  return a + 3;
});
```

You could then use it anywhere else in your space as follows:

```template
{{addThree(2)}}
```

Registering functions would just be one thing, it’s easy to come up with others. The ability to implement custom commands this way, the ability to listen to various events. This will give users a LOT of potential power.

The fun thing is that since these space-script blocks will be indexed across your space, we could include them as part of Libraries. This would enable you to create e.g. a “date” library, that adds all those missing date functions (date ranges, date math etc.) that you always wanted, all written in “user land”, e.g.

```space-script
silverbullet.registerFunction("addDays", (d, days) => {
  const later = new Date(d);
  later.setDate(nextWeek.getDate() + days);
  return niceDate(later);
});
```

This is conceptual code, but you get the idea.

The risk

This is all cool, but the way it’s implemented now is that all this code is effectively eval’ed in the server/client’s main thread. This code could do whatever the heck it wants and has access to pretty much everything. You would still get “hot reloading” support though (the ability to reload all scripts with a single command without having to restart your client or server).

I could make some effort to make access to sensitive browser and Deno APIs a little harder, but for sure it will not be secure.

This means that if you have malicious users that have write access to files in your space, you’d be in trouble.

I could sandbox the code in a similar fashion as plug code today, but it’d significantly impact performance, especially when these functions are going to be called a lot (e.g. in a where clause in a query — which would be the case for e.g. date range functions).

The question is:

Does it matter?

The idea is that you self host SilverBullet. You won’t make it editable to strangers (or at least, with this enabled I’d not recommend it). Also, since most people run SB in a docker container, this decreases the blast radius somewhat.

So presuming that you limit access to your space to just you, and assuming authentication etc. just works. Is this risk acceptable?

4 Likes

This sounds awesome! The risk is acceptable for personal use, in my opinion.

1 Like

The sky would be the limit with this level of flexibility. One could even wonder if there’d really be that much need for a separate plug system. In time, that may need reconsideration. But one step at a time.

Honestly, it’s always been my dream to hack on SilverBullet from within SilverBullet. From my phone, from my iPad. This would get really close to that.

2 Likes

:100:

I would definitely vote for this.

I use SB exclusively for me. My markdown files are mine.
If i have the need to share something at work, I share it in a different way.

Thinking about it, even if I would have the need to share it wtihin SB, i could imagine doing something like this:

Main SB instance (for my own use)

  • Space: ~/silverbullet/
    • ./Library
    • ./Journal
    • ./(whatever i may have…)
    • ./ProjectX
    • ./Learning
    • ./Team
  • Port: 3000

Shareable SB instance

  • Space: ~/silverbullet-shared/
    • ./Library
    • ./ProjectX (symlink to ~/silverbullet/ProjectX)
    • ./Team (symlink to ~/silverbullet/Team)
  • Port: 3001

I guess like this, I would work only on my Main SB instance but would know that everything that I add in ProjectX and Team would be shareable with whomever i decide to.
But settings should remain separate so the Shareable instance would not have activated this Space-Scripts, for example

2 Likes

I’d worry that it might make maintability/traceability of what your pages are doing difficult – it wouldn’t be obvious where a function comes from elsewhere in a Space, and as bugs occur in your personal library, debugging that might be kind of messy.

Ok, I did some more work on this and merged it in. It’s now in Edge, docs are here: Space Script

Have a look and let me know what you think. Note: you can disable it by setting SB_SPACE_SCRIPT=off in an environment variable

2 Likes

I just added the ability to create custom commands using space script too, see Space Script

2 Likes