diff --git a/lib/types/tunnelbroker/peer-to-peer-message-types.js b/lib/types/tunnelbroker/peer-to-peer-message-types.js --- a/lib/types/tunnelbroker/peer-to-peer-message-types.js +++ b/lib/types/tunnelbroker/peer-to-peer-message-types.js @@ -18,6 +18,7 @@ OUTBOUND_SESSION_CREATION: 'OutboundSessionCreation', ENCRYPTED_MESSAGE: 'EncryptedMessage', REFRESH_KEY_REQUEST: 'RefreshKeyRequest', + QR_CODE_AUTH_MESSAGE: 'QRCodeAuthMessage', }); export type OutboundSessionCreation = { @@ -56,13 +57,25 @@ numberOfKeys: t.Number, }); +export type QRCodeAuthMessage = { + +type: 'QRCodeAuthMessage', + +encryptedContent: string, +}; +export const qrCodeAuthMessageValidator: TInterface = + tShape({ + type: tString(peerToPeerMessageTypes.QR_CODE_AUTH_MESSAGE), + encryptedContent: t.String, + }); + export type PeerToPeerMessage = | OutboundSessionCreation | EncryptedMessage - | RefreshKeyRequest; + | RefreshKeyRequest + | QRCodeAuthMessage; export const peerToPeerMessageValidator: TUnion = t.union([ outboundSessionCreationValidator, encryptedMessageValidator, refreshKeysRequestValidator, + qrCodeAuthMessageValidator, ]); diff --git a/lib/types/tunnelbroker/qr-code-auth-message-types.js b/lib/types/tunnelbroker/qr-code-auth-message-types.js new file mode 100644 --- /dev/null +++ b/lib/types/tunnelbroker/qr-code-auth-message-types.js @@ -0,0 +1,53 @@ +// @flow + +import type { TInterface, TUnion } from 'tcomb'; +import t from 'tcomb'; +import { tShape, tString } from '../../utils/validation-utils.js'; + +export const qrCodeAuthMessageTypes = Object.freeze({ + DEVICE_LIST_UPDATE_SUCCESS: 'DeviceListUpdateSuccess', + SECONDARY_DEVICE_REGISTRATION_SUCCESS: 'SecondaryDeviceRegistrationSuccess', + BACKUP_DATA_KEY_MESSAGE: 'BackupDataKeyMessage', +}); + +export type DeviceListUpdateSuccess = { + +type: 'DeviceListUpdateSuccess', + +userID: string, + +primaryDeviceID: string, +}; +export const deviceListUpdateSuccessValidator: TInterface = + tShape({ + type: tString(qrCodeAuthMessageTypes.DEVICE_LIST_UPDATE_SUCCESS), + userID: t.String, + primaryDeviceID: t.String, + }); + +export type SecondaryDeviceRegistrationSuccess = { + +type: 'SecondaryDeviceRegistrationSuccess', +}; +export const secondaryDeviceRegistrationSuccessValidator: TInterface = + tShape({ + type: tString(qrCodeAuthMessageTypes.SECONDARY_DEVICE_REGISTRATION_SUCCESS), + }); + +export type BackupDataKeyMessage = { + +type: 'BackupDataKeyMessage', + +backupDataKey: string, +}; +export const backupDataKeyMessageValidator: TInterface = + tShape({ + type: tString(qrCodeAuthMessageTypes.BACKUP_DATA_KEY_MESSAGE), + backupDataKey: t.String, + }); + +export type QRCodeAuthMessagePayload = + | DeviceListUpdateSuccess + | SecondaryDeviceRegistrationSuccess + | BackupDataKeyMessage; + +export const qrCodeAuthMessagePayloadValidator: TUnion = + t.union([ + deviceListUpdateSuccessValidator, + secondaryDeviceRegistrationSuccessValidator, + backupDataKeyMessageValidator, + ]); diff --git a/lib/utils/qr-code-auth.js b/lib/utils/qr-code-auth.js new file mode 100644 --- /dev/null +++ b/lib/utils/qr-code-auth.js @@ -0,0 +1,34 @@ +// @flow + +import { + peerToPeerMessageTypes, + type QRCodeAuthMessage, +} from '../types/tunnelbroker/peer-to-peer-message-types.js'; +import { + qrCodeAuthMessagePayloadValidator, + type QRCodeAuthMessagePayload, +} from '../types/tunnelbroker/qr-code-auth-message-types.js'; + +function createQRAuthTunnelbrokerMessage( + encryptionKey: string, + payload: QRCodeAuthMessagePayload, +): QRCodeAuthMessage { + return { + type: peerToPeerMessageTypes.QR_CODE_AUTH_MESSAGE, + encryptedContent: JSON.stringify(payload), + }; +} + +function parseQRAuthTunnelbrokerMessage( + encryptionKey: string, + message: QRCodeAuthMessage, +): ?QRCodeAuthMessagePayload { + const payload = JSON.parse(message.encryptedContent); + if (!qrCodeAuthMessagePayloadValidator.is(payload)) { + return null; + } + + return payload; +} + +export { createQRAuthTunnelbrokerMessage, parseQRAuthTunnelbrokerMessage };