Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mschoch committed Jun 7, 2024
0 parents commit d4d2301
Show file tree
Hide file tree
Showing 22 changed files with 1,619 additions and 0 deletions.
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#*
*.sublime-*
*~
.#*
.project
.settings
**/.idea/
**/*.iml
.DS_Store
vendor/**
!vendor/manifest
*.test
tags
/fireplace
/data
/meta
/tsnet
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Fireplace
An experimental mashup of [Fireproof](https://fireproof.storage/) and [Tailscale](https://tailscale.com/).

Fireproof is a next generation database that runs in the browser.
Tailscale's VPN connects the devices I care about most.
Fireplace makes it trivial to deploy apps to your tailnet that automatically sync data between devices.

## Status

This project is an on-going experiment.
You should NOT use it for production data as it likely contains critical bugs and security vulnerabilities.

## How does it work?

Fireplace has two main functions:
- implement the required APIs to function as a sync endpoint for Fireproof
- host applications via TLS over the tailnet, these applications have built-in access to fireproof sync

### Fireproof Sync API
Fireproof databases support sync through the use of pluggable [cloud connectors](https://use-fireproof.com/docs/database-api/sync#configuring-a-cloud-connector).
Fireplace works by using the [AWS/s3 connector](https://www.npmjs.com/package/@fireproof/aws), with the URLs configured to point to it's own endpoints.
Fireplace implements the required data and metadata storage using the local filesystem of the node running fireplace.
Fireplace implements the websocket notification mechanism, meaning clients are automatically notified of changes and need not manually poll.

### Hosting Apps on your Tailnet

Fireplace uses Tailscale's [tsnet](https://tailscale.com/kb/1244/tsnet) to start a web server connected to your tailnet.
This web server will serve independent applications on a specified hostname.
The fireplace-admin app itself is hosted in this way at (`fireplace.<your-tailnet>.ts.net`).
User's can then deploy their own apps, on their own hostnames, and utilize the built-in fireproof storage.
For example, a shared ToDo application could be configured to be hosted on `todo.your-tailnet.ts.net`.

## Prerequisites

- Must have HTTPS Certificates enabled for your Tailnet
- Might need MagicDNS? I have it enabled.

## Quick Start

- clone the repo
- `go build`
- Generate an auth key in your [Tailscale Admin Panel](https://login.tailscale.com/admin/settings/keys)
- `export TS_AUTHKEY=<your auth key>`
- `./fireplace`
- Visit`https://fireplace.<your-tailnet>.ts.net/`

## Screenshots

![](docs/fireplace-admin-home.png)
![](docs/fireplace-admin-databases.png)
![](docs/fireplace-admin-database.png)
![](docs/fireplace-admin-doc.png)

## Fireproof config for Fireplace syncing

This sounds great, but how do I actually configure my app to sync in fireplace?

Use [Fireproof](https://fireproof.storage/) as directed, and simply add the following import:

```javascript
import { connect } from "@fireproof/aws";
```

Then after acquiring your fireproof database add:

```javascript
const s3conf = {
upload: "https://" + window.location.hostname + '/api/upload',
download: "https://" + window.location.hostname + '/api/download/',
websocket: "wss://" + window.location.hostname + '/api/websocket'
}
connect.aws(database, s3conf);
```

## Notes

- Currently Fireplace cannot actually read the database itself. It simply hosts the means by which you can do so in the browser. Over time it would be nice to build out the Go implementation, so that fireplace could more meaningfully interact with the data directly.
7 changes: 7 additions & 0 deletions apps/fireplace-admin/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "fireplace-admin",
"hostname": "fireplace",
"bindAddr": ":443",
"autoStart": true,
"localPath": "apps/fireplace-admin/fireplace-admin.zip"
}
Binary file added apps/fireplace-admin/fireplace-admin.zip
Binary file not shown.
7 changes: 7 additions & 0 deletions apps/todo/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "todo",
"hostname": "todo",
"bindAddr": ":443",
"autoStart": true,
"localPath": "apps/todo/todo.zip"
}
Binary file added apps/todo/todo.zip
Binary file not shown.
Binary file added docs/fireplace-admin-database.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/fireplace-admin-databases.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/fireplace-admin-doc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/fireplace-admin-home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package main

type UploadRequestResponse struct {
UploadURL string `json:"uploadURL"`
Key string `json:"Key"`
}

type MetaResponse struct {
Status int `json:"status"`
Body string `json:"body"`
}

type MetaRequest struct {
CID string `json:"cid"`
Data string `json:"data"`
Parents []string `json:"parents,omitempty"`
}

type MetaItems struct {
Items []*MetaRequest `json:"items"`
}

type UserProfile struct {
LoginName string `json:"loginName"` // "[email protected]"; for display purposes only (provider is not listed)
DisplayName string `json:"displayName"` // "Alice Smith"
ProfilePicURL string `json:"profilePicURL"`
Node string `json:"node"`
}

type Database struct {
Name string `json:"name"`
Version string `json:"version"`
}

type Application struct {
Name string `json:"name"`
Hostname string `json:"hostname"`

BindAddr string `json:"bindAddr"`
AutoStart bool `json:"autoStart"`
LocalPath string `json:"localPath"`

// these are determined at runtime and not persisted
URL string `json:"url"`
}
Loading

0 comments on commit d4d2301

Please sign in to comment.