Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .env-sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
SERVER_API_PATH=/api/v1

# The port on which the HTTP server will listen for incoming requests
HTTP_PORT = 25000

# The port on which the Wormhole will listen for incoming peer connections from OpenSpace
WORMHOLE_PORT = 25001

# Admin SDK file paths
ADMIN_AUTH_SDK_FILEPATH = ""
ADMIN_DB_SDK_FILEPATH = ""

# Realtime database config
DATABASE_FIREBASE_DATABASE_URL = ""

CORS_ORIGIN = ""

# Logs additional debug messages if set to true
DEBUG = "true"
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,10 @@ dist-ssr
*.sln
*.sw?

# Firebase service account keys
*service-account*.json
*adminsdk*.json
*-firebase-*.json

# Build files
*.tsbuildinfo
51 changes: 51 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"MD003": {
"style": "atx"
},
"MD004": {
"style": "dash"
},
"MD007": {
"indent": 2,
"start_indented": true
},
"MD012": false,
"MD013": false,
"MD022": false,
"MD024": {
"siblings_only": true
},
"MD029": {
"style": "one"
},
"MD031": false,
"MD032": false,
"MD033": false,
"MD035": {
"style": "---"
},
"MD041": {
"allow_preamble": true
},
"MD046": {
"style": "fenced"
},
"MD048": {
"style": "backtick"
},
"MD049": {
"style": "asterisk"
},
"MD050": {
"style": "asterisk"
},
"MD051": false,
"MD055": {
"style": "leading_and_trailing"
},
"MD058": false,
"MD059": false,
"MD060": {
"style": "compact"
}
}
79 changes: 47 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,55 @@
# Wormhole - Parallel Connection
# Overview
The web app enhances the usability of Parallel Connection in OpenSpace by enabling users to view available rooms (sessions), create and share rooms with others, and join sessions directly from the website if OpenSpace is running locally.
# Wormhole

# Functionality
### Session Information
View detailed information about each session, including the number of participants, the creator of the room, the current host, and other relevant information.
The Wormhole server is the backend component of [Astrocast](https://github.com/OpenSpace/astrocast.openspaceproject.com). It is responsible for relaying data between [OpenSpace](https://www.openspaceproject.com) instances in a session, and exposing an HTTP API that the Astrocast frontend uses to manage those sessions.

### Join Existing Rooms
Easily connect to an existing room session via the website if you're connected to OpenSpace.
For the frontend, see the [astrocast.openspaceproject.com](https://github.com/OpenSpace/astrocast.openspaceproject.com) repository.

### Share Room
Share room links with others for automatic joining and seamless streaming.
## Getting Started

### Create New Rooms
All sessions occupied? Log in with your Google, Facebook, Twitter, or GitHub account and create a new session.
### Prerequisites
- [Node.js and npm](https://nodejs.org)

# Wormhole
To start the Wormhole server locally, you will need [Node.JS and NPM](https://nodejs.org) installed on your system. With that taken care of

1. Clone this repository and enter the `Wormhole` folder
1. Install all potentially required packages by calling `npm install`
1. Make a copy of `.env_sample`, rename it to `.env` and fill in the information. The projects API keys can be found on [Firebase](https://console.firebase.google.com/u/0/), download the projects admin sdk files as well.
- API
1. In the Firebase console, open `Project Overview` > `1 app` > `Cog wheel`
1. Scroll down to see the values
- Admin SDK
1. In the Firebase console, open `Settings` > `Service Accounts`.
1. Click `Generate New Private Key`, then confirm by clicking `Generate Key`.
1. Securely store the JSON file containing the key.

1. Start the frontend and backend server by executing `npm run dev`. This will set up all the neccesary processes that will transpile the necessary files, enable hot reload, and serve a local express app.
1. To ready the app for deployment execute `npm run build`. This will build both the frontend and backend into `.local/express` and `.local/vite`.
1. Optionally you can run only the frontend by executing `npm run vite:dev` or only the backend by executing `npm run api:dev`.

# Message Structures (version 7)
### Installation

1. Clone this repository
1. Install dependencies:
```sh
npm install
```
1. Copy `.env-sample` to `.env` and fill in the values (see [Environment Variables](#environment-variables) below)

### Running

| Command | Description |
| --------- | ------------- |
| `npm run dev` | Start the server with hot reload (development) |
| `npm run build` | Compile TypeScript to `dist/` |
| `npm run preview` | Run the compiled output from `dist/` |
| `npm run lint` | Check formatting (Prettier) and linting (ESLint) |
| `npm run lint-fix` | Auto-fix formatting and lint issues |

### Environment Variables

| Variable | Required | Default | Description |
| ---------- | ---------- | --------- | ------------- |
| `HTTP_PORT` | | `25000` | Port the HTTP API listens on |
| `WORMHOLE_PORT` | | `25001` | Port the TCP Wormhole server listens on |
| `SERVER_API_PATH` | ✓ | | Base path for all API routes, e.g. `/api` |
| `CORS_ORIGIN` | ✓ | | The origin of the frontend, e.g. `https://astrocast.openspaceproject.com` |
| `DEBUG` | | `false` | Set to `true` to enable verbose debug logging |
| `ADMIN_AUTH_SDK_FILEPATH` | ✓ | | Path to the Firebase Admin SDK JSON file used for authentication |
| `ADMIN_DB_SDK_FILEPATH` | ✓ | | Path to the Firebase Admin SDK JSON file used for the database |
| `DATABASE_FIREBASE_DATABASE_URL` | ✓ | | URL of the Firebase Realtime Database |

### Obtaining Firebase credentials

1. Open the [Firebase console](https://console.firebase.google.com)
1. Go to **Project Settings** > **Service Accounts**
1. Click **Generate New Private Key** and confirm — this downloads a JSON file
1. Set `ADMIN_AUTH_SDK_FILEPATH` and `ADMIN_DB_SDK_FILEPATH` to the path(s) of the downloaded file(s)
1. The `DATABASE_FIREBASE_DATABASE_URL` can be found under **Project Settings** > **General**

## Message Structures (version 7)
This section describes the different message types that are being sent between OpenSpace and the Wormhole application. A message consists of a header and a type-appropriate payload.

```cpp
Expand All @@ -46,7 +62,6 @@ struct {
}
```


## Authentication (Type = 0)
This message is sent from OpenSpace to the Wormhole server to authenticate a new peer to a running session. It consists of a password which has to be provided, and an optional host password, and the optional name. An optional parameter is represented by a length of 0.

Expand Down
61 changes: 61 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import globals from 'globals';
import eslintConfigPrettier from 'eslint-config-prettier';
import simpleImportSort from 'eslint-plugin-simple-import-sort';
import tseslint from 'typescript-eslint';
import js from '@eslint/js';

export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [
js.configs.recommended,
...tseslint.configs.recommended,
eslintConfigPrettier
],
files: ['**/*.{ts,tsx}'],
ignores: ['**/*.d.ts'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.node
},
plugins: {
'simple-import-sort': simpleImportSort
},
linterOptions: {
reportUnusedDisableDirectives: 'error'
},
rules: {
'@typescript-eslint/no-explicit-any': 'warn', // Disallow usage of any
'no-duplicate-imports': 'error', // Imports should be on one line
'no-console': 'warn',
'prefer-destructuring': ['error', { object: true, array: true }],
'simple-import-sort/exports': 'error',
'simple-import-sort/imports': [
'error',
Comment thread
engbergandreas marked this conversation as resolved.
{
groups: [
// Packages `react` related packages come first.
['^react', '^@?\\w'],
// Internal packages.
['^(@|components)(/.*|$)'],
// Side effect imports.
['^\\u0000'],
// Parent imports. Put `..` last.
['^\\.\\.(?!/?$)', '^\\.\\./?$'],
// Other relative imports. Put same-folder imports and `.` last.
['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
// Style imports.
['^.+\\.?(css)$']
]
}
],

// Guards against stupidity
'no-self-compare': 'error',
'no-unreachable-loop': 'error',
'no-template-curly-in-string': 'error', // Catches "${}" template strings
'default-case': ['error', { commentPattern: '^skip\\sdefault' }], // require default switch case
'default-case-last': 'error' // enforce default switch case last
}
}
);
Loading