diff --git a/briar-headless/README.md b/briar-headless/README.md index 83c067306..7c7301fb6 100644 --- a/briar-headless/README.md +++ b/briar-headless/README.md @@ -161,21 +161,18 @@ The Briar peer uses a websocket to notify a connected API client about new event `WS /v1/ws` -The websocket request must use basic auth, -with the authentication token as the username and a blank password. +Immediately after making the connection, +you must send the authentication token as a message to the websocket. +If you fail to do this, you will not receive messages on that socket. -You can test connecting to the websocket with curl: +In JavaScript, it would look like this: - $ curl --no-buffer \ - --header "Connection: Upgrade" \ - --header "Upgrade: websocket" \ - --header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" \ - --header "Sec-WebSocket-Version: 13" \ - --user "DZbfoUie8sjap7CSDR9y6cgJCojV+xUITTIFbgtAgqk=" - http://127.0.0.1:7000/v1/ws - -The headers are only required when testing with curl. -Your websocket client will most likely add these headers automatically. +```javascript +var token = "DZbfoUie8sjap7CSDR9y6cgJCojV+xUITTIFbgtAgqk="; +var socket = new WebSocket("ws://localhost:7000/v1/ws"); +socket.onopen = function(event) { socket.send(token); }; +socket.onmessage = function(event) { console.log(event.data); } +``` ### Receiving new private messages diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/Router.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/Router.kt index a4b32432f..918da2618 100644 --- a/briar-headless/src/main/java/org/briarproject/briar/headless/Router.kt +++ b/briar-headless/src/main/java/org/briarproject/briar/headless/Router.kt @@ -9,7 +9,6 @@ import io.javalin.JavalinEvent.SERVER_START_FAILED import io.javalin.JavalinEvent.SERVER_STOPPED import io.javalin.NotFoundResponse import io.javalin.apibuilder.ApiBuilder.* -import io.javalin.core.util.ContextUtil import io.javalin.core.util.Header.AUTHORIZATION import org.briarproject.bramble.api.contact.ContactId import org.briarproject.briar.headless.blogs.BlogController @@ -20,6 +19,7 @@ import org.briarproject.briar.headless.messaging.MessagingController import java.lang.Runtime.getRuntime import java.lang.System.exit import java.util.concurrent.atomic.AtomicBoolean +import java.util.logging.Level import java.util.logging.Logger.getLogger import javax.annotation.concurrent.Immutable import javax.inject.Inject @@ -85,13 +85,16 @@ constructor( } } app.ws("/v1/ws") { ws -> - ws.onConnect { session -> - val authHeader = session.header(AUTHORIZATION) - val token = ContextUtil.getBasicAuthCredentials(authHeader)?.username - if (authToken == token) { - logger.info("Adding websocket session with ${session.remoteAddress}") + if (logger.isLoggable(Level.INFO)) ws.onConnect { session -> + logger.info("Received websocket connection from ${session.remoteAddress}") + logger.info("Waiting for authentication") + } + ws.onMessage { session, msg -> + if (msg == authToken && !webSocketController.sessions.contains(session)) { + logger.info("Authenticated websocket session with ${session.remoteAddress}") webSocketController.sessions.add(session) } else { + logger.info("Invalid message received: $msg") logger.info("Closing websocket connection with ${session.remoteAddress}") session.close(1008, "Invalid Authentication Token") }