Config stuff, docs
This commit is contained in:
		
							
								
								
									
										33
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								README.md
									
									
									
									
									
								
							@@ -1,11 +1,9 @@
 | 
				
			|||||||
# Mercureact
 | 
					# Mercureact
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This is an implementation of the Mercure realtime protocol on steroids, built using ReactPHP.
 | 
					This is an implementation of the Mercure realtime protocol, built using ReactPHP. It is intended to be used standalone, but it may also be integrated into another ReactPHP application.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Mercureact is under development, and not ready for use in anything important.**
 | 
					**Mercureact is under development, and not ready for use in anything important.**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It is intended to be used standalone, but it may also be integrated into another PHP application.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Installing
 | 
					## Installing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As PHAR:
 | 
					As PHAR:
 | 
				
			||||||
@@ -14,44 +12,37 @@ As PHAR:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
As Composer dependency:
 | 
					As Composer dependency:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `composer require noccylabs/mercureact`
 | 
					* `composer require noccylabs/mercureact:@dev`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Using as PHAR
 | 
					## Using as PHAR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*TODO.*
 | 
					Running `mercureact.phar` without passing a config file with `-c` will spawn an insecure daemon that can be used for testing. Following tradition, the default JWT secret key is `!ChangeThisMercureHubJWTSecretKey!`; this key must be used to publish, but anonymous subscribers are allowed, and will be delivered any non-private updates.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You should probably use a configuration file for just about every case. Mercureact contains a compact dist config that can be written to a file with `-C`, or you can use the `mercureact.conf.dist` file from the repository.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```shell
 | 
					```shell
 | 
				
			||||||
# Make a copy of the dist config and edit it
 | 
					# If you got a mercureact.conf.dist file, make a copy and edit it
 | 
				
			||||||
$ cp mercureact.conf.dist mercureact.conf
 | 
					$ cp mercureact.conf.dist mercureact.conf
 | 
				
			||||||
$ editor mercureact.conf
 | 
					$ editor mercureact.conf
 | 
				
			||||||
# Use the config file when launching
 | 
					
 | 
				
			||||||
 | 
					# Or use the -C (capital C) option to generate and edit one
 | 
				
			||||||
 | 
					$ ./mercureact.phar -C mercureact.conf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Then use the config file when launching
 | 
				
			||||||
$ ./mercureact.phar -c mercureact.conf
 | 
					$ ./mercureact.phar -c mercureact.conf
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Using as dependency
 | 
					## Using as dependency
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*TODO.*
 | 
					Take a look at `src/Daemon.php` and `src/Http/Server.php` depending on how much of Mercureact you want to reuse.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## ToDos
 | 
					## ToDos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* [x] Read config from file
 | 
					 | 
				
			||||||
* [ ] Security Security Security
 | 
					 | 
				
			||||||
  * [x] Check JWTs on connect
 | 
					 | 
				
			||||||
  * [x] Check claims on subscribe and publish
 | 
					 | 
				
			||||||
  * [x] Extract JWT claims to request attributes, instead of JWTToken
 | 
					 | 
				
			||||||
* [x] Subscription/Topic manager
 | 
					 | 
				
			||||||
  * [x] Unify distribution
 | 
					 | 
				
			||||||
  * [x] Enumerate subscriptions and topics
 | 
					 | 
				
			||||||
* [x] Publish events
 | 
					 | 
				
			||||||
* [x] Server-Side Events distributor
 | 
					 | 
				
			||||||
  * [x] Distribute events over SSE
 | 
					 | 
				
			||||||
* [ ] WebSocket distributor
 | 
					* [ ] WebSocket distributor
 | 
				
			||||||
  * [ ] WebSocket authentication
 | 
					  * [ ] WebSocket authentication
 | 
				
			||||||
  * [ ] Setup subscriptions
 | 
					  * [ ] Setup subscriptions
 | 
				
			||||||
  * [ ] Dynamic subscriptions
 | 
					  * [ ] Dynamic subscriptions
 | 
				
			||||||
  * [x] Distribute events over WS
 | 
					  * [x] Distribute events over WS
 | 
				
			||||||
* [x] Break out HTTP middleware into classes
 | 
					 | 
				
			||||||
* [ ] HTTP middleware unittests
 | 
					* [ ] HTTP middleware unittests
 | 
				
			||||||
* [ ] Replay missed events based on event id
 | 
					* [ ] Replay missed events based on event id
 | 
				
			||||||
* [x] Figure out how to determine last event IDs
 | 
					 | 
				
			||||||
* [ ] Metrics endpoint
 | 
					* [ ] Metrics endpoint
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,60 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use NoccyLabs\Mercureact\Configuration;
 | 
					use NoccyLabs\Mercureact\Configuration;
 | 
				
			||||||
use NoccyLabs\Mercureact\Daemon;
 | 
					use NoccyLabs\Mercureact\Daemon;
 | 
				
			||||||
 | 
					use PHPUnit\TextUI\Help;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require_once __DIR__."/../vendor/autoload.php";
 | 
					require_once __DIR__."/../vendor/autoload.php";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$opts = getopt("c:");
 | 
					$opts = getopt("c:C:h");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (isset($opts['h'])) {
 | 
				
			||||||
 | 
					    fwrite(STDERR, <<<HELP
 | 
				
			||||||
 | 
					    Mercureact Realtime SSE Daemon
 | 
				
			||||||
 | 
					    (c) 2024, NoccyLabs - Distributed under GNU GPL v3 or later.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Options:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -c config     Read configuration from file
 | 
				
			||||||
 | 
					        -C config     Write a new configuration to file and open with editor
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    HELP);
 | 
				
			||||||
 | 
					    exit(0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (isset($opts['C'])) {
 | 
				
			||||||
 | 
					    $file = $opts['C'];
 | 
				
			||||||
 | 
					    if (file_exists($file)) {
 | 
				
			||||||
 | 
					        fwrite(STDERR, "File {$file} already exists. Will not overwrite.\n");
 | 
				
			||||||
 | 
					        exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    file_put_contents($file, <<<DEFAULTS
 | 
				
			||||||
 | 
					    listeners:
 | 
				
			||||||
 | 
					    - address: 0.0.0.0:9000
 | 
				
			||||||
 | 
					      cors:
 | 
				
			||||||
 | 
					        allow_origin: '*'
 | 
				
			||||||
 | 
					        csp: "default-src * 'self' http: 'unsafe-eval' 'unsafe-inline'; connect-src * 'self'"
 | 
				
			||||||
 | 
					      encryption:
 | 
				
			||||||
 | 
					        cert: foo.pem
 | 
				
			||||||
 | 
					        key: foo.key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    websocket:
 | 
				
			||||||
 | 
					      enable: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    publish:
 | 
				
			||||||
 | 
					      overwrite_id: false
 | 
				
			||||||
 | 
					      reject_duplicates: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    subscribe:
 | 
				
			||||||
 | 
					      allow_anonymous: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    security:
 | 
				
			||||||
 | 
					      jwt_secret: "!ChangeThisMercureHubJWTSecretKey!"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DEFAULTS);
 | 
				
			||||||
 | 
					    passthru("editor ".escapeshellarg($file));
 | 
				
			||||||
 | 
					    exit(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (isset($opts['c'])) {
 | 
					if (isset($opts['c'])) {
 | 
				
			||||||
    $config = Configuration::fromFile($opts['c']);
 | 
					    $config = Configuration::fromFile($opts['c']);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,9 +16,9 @@ listeners:
 | 
				
			|||||||
      cert: foo.pem
 | 
					      cert: foo.pem
 | 
				
			||||||
      key: foo.key
 | 
					      key: foo.key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Enable websockets
 | 
					# Enable websockets
 | 
				
			||||||
    websocket:
 | 
					websocket:
 | 
				
			||||||
      enable: true
 | 
					  enable: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
publish:
 | 
					publish:
 | 
				
			||||||
  # Assign a UUID to published messages even if one is already set in the message
 | 
					  # Assign a UUID to published messages even if one is already set in the message
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,9 +93,6 @@ class Configuration
 | 
				
			|||||||
                'allow_origin' => '*',
 | 
					                'allow_origin' => '*',
 | 
				
			||||||
                'csp' => 'default-src * \'self\'',
 | 
					                'csp' => 'default-src * \'self\'',
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            'websocket' => isset($config['websocket'])?[
 | 
					 | 
				
			||||||
                'enable' => $config['websocket']['enable']??false
 | 
					 | 
				
			||||||
            ]:null,
 | 
					 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user