diff --git a/app/Http/Controllers/Api/Client/Servers/WebsocketController.php b/app/Http/Controllers/Api/Client/Servers/WebsocketController.php index c597ab8a0..7d68b5a31 100644 --- a/app/Http/Controllers/Api/Client/Servers/WebsocketController.php +++ b/app/Http/Controllers/Api/Client/Servers/WebsocketController.php @@ -63,7 +63,11 @@ class WebsocketController extends ClientApiController ->expiresAt($now->addMinutes(15)->getTimestamp()) ->withClaim('user_id', $request->user()->id) ->withClaim('server_uuid', $server->uuid) - ->withClaim('permissions', ['connect', 'send-command', 'send-power']) + ->withClaim('permissions', array_merge([ + 'connect', + 'send-command', + 'send-power', + ], $request->user()->root_admin ? ['receive-errors'] : [])) ->getToken($signer, new Key($server->node->daemonSecret)); $socket = str_replace(['https://', 'http://'], ['wss://', 'ws://'], $server->node->getConnectionAddress()); diff --git a/resources/scripts/components/server/Console.tsx b/resources/scripts/components/server/Console.tsx index f35ded898..a789a2682 100644 --- a/resources/scripts/components/server/Console.tsx +++ b/resources/scripts/components/server/Console.tsx @@ -45,6 +45,10 @@ export default () => { line.replace(/(?:\r\n|\r|\n)$/im, '') + '\u001b[0m', ); + const handleDaemonErrorOutput = (line: string) => terminal.writeln( + '\u001b[1m\u001b[41m[Internal] ' + line.replace(/(?:\r\n|\r|\n)$/im, '') + '\u001b[0m', + ); + const handleCommandKeydown = (e: React.KeyboardEvent) => { if (e.key !== 'Enter' || (e.key === 'Enter' && e.currentTarget.value.length < 1)) { return; @@ -69,11 +73,13 @@ export default () => { terminal.clear(); instance.addListener('console output', handleConsoleOutput); + instance.addListener('daemon error', handleDaemonErrorOutput); instance.send('send logs'); } return () => { - instance && instance.removeListener('console output', handleConsoleOutput); + instance && instance.removeListener('console output', handleConsoleOutput) + .removeListener('daemon error', handleDaemonErrorOutput); }; }, [ connected, instance ]); diff --git a/resources/scripts/components/server/WebsocketHandler.tsx b/resources/scripts/components/server/WebsocketHandler.tsx index a46b3fd1c..d84c39413 100644 --- a/resources/scripts/components/server/WebsocketHandler.tsx +++ b/resources/scripts/components/server/WebsocketHandler.tsx @@ -5,10 +5,16 @@ import getWebsocketToken from '@/api/server/getWebsocketToken'; export default () => { const server = ServerContext.useStoreState(state => state.server.data); - const { instance, connected } = ServerContext.useStoreState(state => state.socket); + const { instance } = ServerContext.useStoreState(state => state.socket); const setServerStatus = ServerContext.useStoreActions(actions => actions.status.setServerStatus); const { setInstance, setConnectionState } = ServerContext.useStoreActions(actions => actions.socket); + const updateToken = (uuid: string, socket: Websocket) => { + getWebsocketToken(uuid) + .then(data => socket.setToken(data.token)) + .catch(error => console.error(error)); + }; + useEffect(() => { // If there is already an instance or there is no server, just exit out of this process // since we don't need to make a new connection. @@ -23,6 +29,13 @@ export default () => { socket.on('SOCKET_ERROR', () => setConnectionState(false)); socket.on('status', (status) => setServerStatus(status)); + socket.on('daemon error', message => { + console.warn('Got error message from daemon socket:', message); + }); + + socket.on('token expiring', () => updateToken(server.uuid, socket)); + socket.on('token expired', () => updateToken(server.uuid, socket)); + getWebsocketToken(server.uuid) .then(data => { socket.setToken(data.token).connect(data.socket); @@ -36,15 +49,5 @@ export default () => { }; }, [ server ]); - // Prevent issues with HMR in development environments. This might need to also - // exist outside of dev? Will need to see how things go. - if (process.env.NODE_ENV === 'development') { - useEffect(() => { - if (!connected && instance && instance.getToken() && instance.getSocketUrl()) { - instance.connect(instance.getSocketUrl()!); - } - }, [ connected ]); - } - return null; }; diff --git a/resources/scripts/plugins/Websocket.ts b/resources/scripts/plugins/Websocket.ts index 09aa2a118..0bf393e87 100644 --- a/resources/scripts/plugins/Websocket.ts +++ b/resources/scripts/plugins/Websocket.ts @@ -51,6 +51,10 @@ export class Websocket extends EventEmitter { setToken (token: string): this { this.token = token; + if (this.url) { + this.send('auth', token); + } + return this; } @@ -60,6 +64,8 @@ export class Websocket extends EventEmitter { } close (code?: number, reason?: string) { + this.url = null; + this.token = ''; this.socket && this.socket.close(code, reason); }