diff --git a/lib/tunnelbroker/tunnelbroker-context.js b/lib/tunnelbroker/tunnelbroker-context.js --- a/lib/tunnelbroker/tunnelbroker-context.js +++ b/lib/tunnelbroker/tunnelbroker-context.js @@ -18,7 +18,11 @@ type PeerToPeerMessage, peerToPeerMessageValidator, } from '../types/tunnelbroker/peer-to-peer-message-types.js'; -import type { ConnectionInitializationMessage } from '../types/tunnelbroker/session-types.js'; +import type { + AnonymousInitializationMessage, + TunnelbrokerInitializationMessage, + ConnectionInitializationMessage, +} from '../types/tunnelbroker/session-types.js'; import type { Heartbeat } from '../types/websocket/heartbeat-types.js'; export type ClientMessageToDevice = { @@ -41,6 +45,7 @@ +addListener: (listener: TunnelbrokerSocketListener) => void, +removeListener: (listener: TunnelbrokerSocketListener) => void, +connected: boolean, + +setUnauthorizedDeviceID: (unauthorizedDeviceID: ?string) => void, }; const TunnelbrokerContext: React.Context = @@ -52,16 +57,40 @@ +peerToPeerMessageHandler?: (message: PeerToPeerMessage) => mixed, }; +function createAnonymousInitMessage( + deviceID: string, +): AnonymousInitializationMessage { + return ({ + type: 'AnonymousInitializationMessage', + deviceID, + deviceType: 'mobile', + }: AnonymousInitializationMessage); +} + function TunnelbrokerProvider(props: Props): React.Node { - const { children, initMessage, peerToPeerMessageHandler } = props; + const { + children, + initMessage: initMessageProp, + peerToPeerMessageHandler, + } = props; const [connected, setConnected] = React.useState(false); const listeners = React.useRef>(new Set()); const socket = React.useRef(null); const promises = React.useRef({}); const heartbeatTimeoutID = React.useRef(); + const [unauthorizedDeviceID, setUnauthorizedDeviceID] = + React.useState(null); + const isAuthorized = !unauthorizedDeviceID; + + const initMessage = React.useMemo(() => { + if (!unauthorizedDeviceID) { + return initMessageProp; + } + return createAnonymousInitMessage(unauthorizedDeviceID); + }, [unauthorizedDeviceID, initMessageProp]); const previousInitMessage = - React.useRef(initMessage); + React.useRef(initMessage); const initMessageChanged = initMessage !== previousInitMessage.current; previousInitMessage.current = initMessage; @@ -151,7 +180,10 @@ ) { if (message.status.type === 'Success' && !connected) { setConnected(true); - console.log('session with Tunnelbroker created'); + console.log( + 'session with Tunnelbroker created. isAuthorized:', + isAuthorized, + ); } else if (message.status.type === 'Success' && connected) { console.log( 'received ConnectionInitializationResponse with status: Success for already connected socket', @@ -222,6 +254,7 @@ initMessage, initMessageChanged, isSocketActive, + isAuthorized, resetHeartbeatTimeout, stopHeartbeatTimeout, peerToPeerMessageHandler, @@ -272,6 +305,7 @@ connected, addListener, removeListener, + setUnauthorizedDeviceID, }), [addListener, connected, removeListener, sendMessage], ); diff --git a/lib/types/tunnelbroker/session-types.js b/lib/types/tunnelbroker/session-types.js --- a/lib/types/tunnelbroker/session-types.js +++ b/lib/types/tunnelbroker/session-types.js @@ -5,7 +5,7 @@ import { tShape, tString } from '../../utils/validation-utils.js'; -export type DeviceTypes = 'mobile' | 'web' | 'keyserver'; +export type TunnelbrokerDeviceTypes = 'mobile' | 'web' | 'keyserver'; export type ConnectionInitializationMessage = { +type: 'ConnectionInitializationMessage', @@ -13,11 +13,23 @@ +accessToken: string, +userID: string, +notifyToken?: ?string, - +deviceType: DeviceTypes, + +deviceType: TunnelbrokerDeviceTypes, +deviceAppVersion?: ?string, +deviceOS?: ?string, }; +export type AnonymousInitializationMessage = { + +type: 'AnonymousInitializationMessage', + +deviceID: string, + +deviceType: TunnelbrokerDeviceTypes, + +deviceAppVersion?: ?string, + +deviceOS?: ?string, +}; + +export type TunnelbrokerInitializationMessage = + | ConnectionInitializationMessage + | AnonymousInitializationMessage; + export const connectionInitializationMessageValidator: TInterface = tShape({ type: tString('ConnectionInitializationMessage'), @@ -25,7 +37,16 @@ accessToken: t.String, userID: t.String, notifyToken: t.maybe(t.String), - deviceType: t.enums.of(['Mobile', 'Web', 'Keyserver']), + deviceType: t.enums.of(['mobile', 'web', 'keyserver']), + deviceAppVersion: t.maybe(t.String), + deviceOS: t.maybe(t.String), + }); + +export const anonymousInitializationMessageValidator: TInterface = + tShape({ + type: tString('AnonymousInitializationMessage'), + deviceID: t.String, + deviceType: t.enums.of(['mobile', 'web', 'keyserver']), deviceAppVersion: t.maybe(t.String), deviceOS: t.maybe(t.String), });