').addClass(`log ${classNames}`).html(message);
- }
-
- this.addMessageElement($el, options);
- }
-
- checkIfUsername(words) {
- let matchedUsernames = [];
- this.darkwire.users.forEach((user) => {
- let usernameMatch = new RegExp('^' + user.username + '$');
- for (let i = 0; i < words.length; i++) {
- let exactMatch = words[i].match(usernameMatch) || false;
- let usernameInMemory = this.usernamesInMemory.indexOf(words[i]) > -1;
-
- if (exactMatch && exactMatch.length > -1 || usernameInMemory) {
- if (!usernameInMemory) {
- this.usernamesInMemory.push(words[i]);
- }
- matchedUsernames.push(words[i]);
- }
- }
- });
- return matchedUsernames;
- }
-
- // Gets the color of a username through our hash function
- getUsernameColor(username) {
- const COLORS = [
- '#e21400', '#ffe400', '#ff8f00',
- '#58dc00', '#dd9cff', '#4ae8c4',
- '#3b88eb', '#f47777', '#EEACB7',
- '#D3FF3E', '#99CC33', '#999933',
- '#996633', '#B8D5B8', '#7FFF38',
- '#FADBBC', '#FAE2B7', '#EBE8AF',
- ];
- // Compute hash code
- let hash = 7;
- for (let i = 0; i < username.length; i++) {
- hash = username.charCodeAt(i) + (hash << 5) - hash;
- }
- // Calculate color
- let index = Math.abs(hash % COLORS.length);
- return COLORS[index];
- }
-
- bindEvents() {
- var _this = this;
- // Select message input when clicking message body, unless selecting text
- this.messages.on('click', () => {
- if (!this.getSelectedText()) {
- this.inputMessage.focus();
- }
- });
-
- this.inputMessage.on('input propertychange paste change', function() {
- _this.updateTyping();
- let message = $(this).val().trim();
- if (message.length) {
- $('#send-message-btn').addClass('active');
- } else {
- $('#send-message-btn').removeClass('active');
- }
- });
- }
-
- // Updates the typing event
- updateTyping() {
- if (this.darkwire.connected) {
- if (!this.typing) {
- this.typing = true;
- this.socket.emit('typing');
- }
- this.lastTypingTime = (new Date()).getTime();
-
- setTimeout(() => {
- let typingTimer = (new Date()).getTime();
- let timeDiff = typingTimer - this.lastTypingTime;
- if (timeDiff >= this.TYPING_TIMER_LENGTH && this.typing) {
- this.socket.emit('stop typing');
- this.typing = false;
- }
- }, this.TYPING_TIMER_LENGTH);
- }
- }
-
- addChatTyping(data) {
- data.typing = true;
- data.message = 'is typing';
- this.addChatMessage(data);
- }
-
- getSelectedText() {
- let text = '';
- if (typeof window.getSelection != 'undefined') {
- text = window.getSelection().toString();
- } else if (typeof document.selection != 'undefined' && document.selection.type == 'Text') {
- text = document.selection.createRange().text;
- }
- return text;
- }
-
- getTypingMessages(data) {
- return $('.typing.message').filter(function(i) {
- return $(this).data('username') === data.username;
- });
- }
-
- removeChatTyping(data) {
- this.getTypingMessages(data).fadeOut(function() {
- $(this).remove();
- });
- }
-
- slashCommands(trigger) {
- let validCommands = [];
- let expectedParams = 0;
- const triggerCommands = [{
- command: 'nick',
- description: 'Changes nickname.',
- paramaters: ['{username}'],
- multiple: false,
- usage: '/nick {username}',
- action: () => {
-
- let newUsername = trigger.params[0] || false;
-
- if (newUsername.toString().length > 16) {
- return this.log('Username cannot be greater than 16 characters.', {error: true});
- }
-
- // Remove things that arent digits or chars
- newUsername = newUsername.replace(/[^A-Za-z0-9]/g, '-');
-
- if (!newUsername.match(/^[A-Z]/i)) {
- return this.log('Username must start with a letter.', {error: true});
- }
-
- if (!warned) {
- warned = true;
- return this.log('Changing your username is currently in beta and your new username will be sent over the wire in plain text, unecrypted. This will be fixed in v2.0. If you really want to do this, type the command again.',
- {
- warning: true,
- classNames: 'change-username-warning'
- });
- }
-
- this.darkwire.updateUsername(newUsername).then((socketData) => {
- let modifiedSocketData = {
- username: window.username,
- newUsername: socketData.username
- };
-
- this.socket.emit('update user', modifiedSocketData);
- window.username = username = socketData.username;
- }).catch((err) => {
- return this.log(err, {error: true});
- });
- }
- }, {
- command: 'help',
- description: 'Shows a list of commands.',
- paramaters: [],
- multiple: false,
- usage: '/help',
- action: () => {
- validCommands = validCommands.map((command) => {
- return '/' + command;
- });
-
- this.log('Valid commands: ' + validCommands.sort().join(', '), {notice: true});
- }
- }, {
- command: 'me',
- description: 'Invoke virtual action',
- paramaters: ['{action}'],
- multiple: true,
- usage: '/me {action}',
- action: () => {
-
- expectedParams = 100;
-
- let actionMessage = trigger.params.join(' ');
-
- this.darkwire.encodeMessage(actionMessage, 'action').then((socketData) => {
- this.addChatMessage({
- username: username,
- message: actionMessage,
- messageType: 'action'
- });
- this.socket.emit('new message', socketData);
- }).catch((err) => {
- console.log(err);
- });
- }
- }, {
- command: 'clear',
- description: 'Clears the chat screen',
- paramaters: [],
- multiple: true,
- usage: '/clear',
- action: () => {
- this.clear();
- }
- }];
-
- const color = () => {
- const hexTex = new RegExp(/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i);
- };
-
- triggerCommands.forEach((command) => {
- validCommands.push(command.command);
- });
-
- let commandToTrigger = _.findWhere(triggerCommands, {command: trigger.command});
-
- if (commandToTrigger) {
- expectedParams = commandToTrigger.paramaters.length;
- if (expectedParams && trigger.params.length > expectedParams || expectedParams && trigger.params.length < expectedParams) {
- if ((!commandToTrigger.multple && trigger.params.length < 1) || (trigger.params.length >= 1 && trigger.params[0] === '')) {
- return this.log('Missing or too many paramater. Usage: ' + commandToTrigger.usage, {error: true});
- }
- }
-
- return commandToTrigger.action.call();
- }
-
- this.log(trigger.command + ' is not a valid command. Type /help for a list of valid commands.', {error: true});
- return false;
- }
-
- executeCommand(trigger) {
- trigger = trigger || false;
- if (trigger) {
- let command = trigger.command;
- this.slashCommands(trigger);
- }
- }
-
- parseCommand(cleanedMessage) {
- let trigger = {
- command: null,
- params: []
- };
-
- if (cleanedMessage.indexOf('/') === 0) {
- this.inputMessage.val('');
- let parsedCommand = cleanedMessage.replace('/', '').split(' ');
- trigger.command = sanitizeHtml(parsedCommand[0]) || null;
- // Get params
- if (parsedCommand.length >= 2) {
- for (let i = 1; i < parsedCommand.length; i++) {
- trigger.params.push(parsedCommand[i]);
- }
- }
-
- return trigger;
- }
-
- return false;
- }
-
- addChatMessage(data, options) {
- if (!data.message.trim().length) {
- return;
- }
-
- let messageType = data.messageType || 'text';
-
- // Don't fade the message in if there is an 'X was typing'
- let $typingMessages = this.getTypingMessages(data);
- options = options || {};
- if ($typingMessages.length !== 0) {
- options.fade = false;
- $typingMessages.remove();
- }
-
- let $usernameDiv = $('')
- .text(data.username)
- .css('color', this.getUsernameColor(data.username));
-
- let $messageBodyDiv = $('');
- let timestamp = this.getTimestamp(data.typing);
-
- if (messageType === 'text' || messageType === 'action') {
- if (messageType === 'action') {
- $usernameDiv.css('color','').prepend('*');
- }
-
- let unescapedMessage = unescape(data.message);
- let lineBreaks = /<br \/>/g;
- unescapedMessage = unescapedMessage.replace(lineBreaks, ' ');
- $messageBodyDiv.html(unescapedMessage);
- } else {
- $messageBodyDiv.html(this.darkwire.addFileToQueue(data));
- }
-
- let typingClass = data.typing ? 'typing' : '';
- let actionClass = data.messageType === 'action' ? 'action' : '';
-
- let $messageDiv = $('')
- .data('username', data.username)
- .addClass(typingClass)
- .addClass(actionClass)
- .append(timestamp, $usernameDiv, $messageBodyDiv);
-
- this.addMessageElement($messageDiv, options);
- }
-
- getTimestamp(isTyping) {
- if (isTyping) {
- return false;
- }
-
- let now = moment(new Date()).format('LT');
-
- if (this.lastMessageTime === now) {
- return false;
- }
-
- this.lastMessageTime = now;
-
- return '' + now + '';
-
- }
-
- addMessageElement(el, options) {
- let $el = $(el);
-
- if (!options) {
- options = {};
- }
-
- $el.hide().fadeIn(this.FADE_TIME);
- this.messages.append($el);
-
- this.messages[0].scrollTop = this.messages[0].scrollHeight; // minus 60 for key
- }
-
- replaceMessage(id, message) {
- let container = $(id);
- if (container) {
- container.html(message);
- }
- }
-
-}
diff --git a/src/js/crypto.js b/src/js/crypto.js
deleted file mode 100644
index 7b1a79c..0000000
--- a/src/js/crypto.js
+++ /dev/null
@@ -1,237 +0,0 @@
-export default class CryptoUtil {
- constructor() {
- this._crypto = window.crypto || false;
-
- if (!this._crypto || (!this._crypto.subtle && !this._crypto.webkitSubtle)) {
- $('#no-crypto').modal({
- backdrop: 'static',
- show: false,
- keyboard: false
- });
-
- $('#no-crypto').modal('show');
- return;
- }
-
- }
-
- get crypto() {
- return this._crypto;
- }
-
- convertStringToArrayBufferView(str) {
- let bytes = new Uint8Array(str.length);
- for (let i = 0; i < str.length; i++) {
- bytes[i] = str.charCodeAt(i);
- }
-
- return bytes;
- }
-
- convertArrayBufferViewToString(buffer) {
- let str = '';
- for (let i = 0; i < buffer.byteLength; i++) {
- str += String.fromCharCode(buffer[i]);
- }
-
- return str;
- }
-
- createSigningKey() {
- return this._crypto.subtle.generateKey(
- {
- name: 'HMAC',
- hash: {name: 'SHA-256'}, //can be 'SHA-1', 'SHA-256', 'SHA-384', or 'SHA-512'
- //length: 256, //optional, if you want your key length to differ from the hash function's block length
- },
- true, //whether the key is extractable (i.e. can be used in exportKey)
- ['sign', 'verify'] //can be any combination of 'sign' and 'verify'
- );
- }
-
- createPrimaryKeys() {
- return this._crypto.subtle.generateKey(
- {
- name: 'RSA-OAEP',
- modulusLength: 2048, //can be 1024, 2048, or 4096
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
- hash: {name: 'SHA-256'}, //can be 'SHA-1', 'SHA-256', 'SHA-384', or 'SHA-512'
- },
- true, //whether the key is extractable (i.e. can be used in exportKey)
- ['encrypt', 'decrypt'] //must be ['encrypt', 'decrypt'] or ['wrapKey', 'unwrapKey']
- );
- }
-
- createSecretKey() {
- return this._crypto.subtle.generateKey(
- {
- name: 'AES-CBC',
- length: 256, //can be 128, 192, or 256
- },
- true, //whether the key is extractable (i.e. can be used in exportKey)
- ['encrypt', 'decrypt'] //can be 'encrypt', 'decrypt', 'wrapKey', or 'unwrapKey'
- );
- }
-
- encryptSecretKey(data, secretKey) {
- // Secret key will be recipient's public key
- return this._crypto.subtle.encrypt(
- {
- name: 'RSA-OAEP',
- modulusLength: 2048,
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
- hash: {name: 'SHA-256'}
- },
- secretKey,
- data //ArrayBuffer of data you want to encrypt
- );
- }
-
- decryptSecretKey(data, key) {
- // key will be my private key
- return this._crypto.subtle.decrypt(
- {
- name: 'RSA-OAEP',
- modulusLength: 2048,
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
- hash: {name: 'SHA-256'}
- //label: Uint8Array([...]) //optional
- },
- key,
- data //ArrayBuffer of the data
- );
- }
-
- encryptSigningKey(data, signingKey) {
- // Secret key will be recipient's public key
- return this._crypto.subtle.encrypt(
- {
- name: 'RSA-OAEP',
- modulusLength: 2048,
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
- hash: {name: 'SHA-256'}
- },
- signingKey,
- data //ArrayBuffer of data you want to encrypt
- );
- }
-
- decryptSigningKey(data, key) {
- // key will be my private key
- return this._crypto.subtle.decrypt(
- {
- name: 'RSA-OAEP',
- modulusLength: 2048,
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
- hash: {name: 'SHA-256'}
- //label: Uint8Array([...]) //optional
- },
- key,
- data //ArrayBuffer of the data
- );
- }
-
- encryptMessage(data, secretKey, iv) {
- return this._crypto.subtle.encrypt(
- {
- name: 'AES-CBC',
- //Don't re-use initialization vectors!
- //Always generate a new iv every time your encrypt!
- iv: iv,
- },
- secretKey, //from generateKey or importKey above
- data //ArrayBuffer of data you want to encrypt
- );
- }
-
- decryptMessage(data, secretKey, iv) {
- return this._crypto.subtle.decrypt(
- {
- name: 'AES-CBC',
- iv: iv, //The initialization vector you used to encrypt
- },
- secretKey, //from generateKey or importKey above
- data //ArrayBuffer of the data
- );
- }
-
- importSecretKey(jwkData, format) {
- return this._crypto.subtle.importKey(
- format || 'jwk', //can be 'jwk' or 'raw'
- //this is an example jwk key, 'raw' would be an ArrayBuffer
- jwkData,
- { //this is the algorithm options
- name: 'AES-CBC',
- },
- true, //whether the key is extractable (i.e. can be used in exportKey)
- ['encrypt', 'decrypt'] //can be 'encrypt', 'decrypt', 'wrapKey', or 'unwrapKey'
- );
- }
-
- importPrimaryKey(jwkData, format) {
- // Will be someone's public key
- let hashObj = {
- name: 'RSA-OAEP'
- };
- if (!this._crypto.webkitSubtle) {
- hashObj.hash = {name: 'SHA-256'};
- }
- return this._crypto.subtle.importKey(
- format || 'jwk', //can be 'jwk' (public or private), 'spki' (public only), or 'pkcs8' (private only)
- jwkData,
- hashObj,
- true, //whether the key is extractable (i.e. can be used in exportKey)
- ['encrypt'] //'encrypt' or 'wrapKey' for public key import or
- //'decrypt' or 'unwrapKey' for private key imports
- );
- }
-
- exportKey(key, format) {
- // Will be public primary key or public signing key
- return this._crypto.subtle.exportKey(
- format || 'jwk', //can be 'jwk' (public or private), 'spki' (public only), or 'pkcs8' (private only)
- key //can be a publicKey or privateKey, as long as extractable was true
- );
- }
-
- importSigningKey(jwkData) {
- return this._crypto.subtle.importKey(
- 'raw', //can be 'jwk' (public or private), 'spki' (public only), or 'pkcs8' (private only)
- //this is an example jwk key, other key types are Uint8Array objects
- jwkData,
- { //these are the algorithm options
- name: 'HMAC',
- hash: {name: 'SHA-256'}, //can be 'SHA-1', 'SHA-256', 'SHA-384', or 'SHA-512'
- //length: 256, //optional, if you want your key length to differ from the hash function's block length
- },
- true, //whether the key is extractable (i.e. can be used in exportKey)
- ['verify'] //'verify' for public key import, 'sign' for private key imports
- );
- }
-
- signKey(data, keyToSignWith) {
- // Will use my private key
- return this._crypto.subtle.sign(
- {
- name: 'HMAC',
- hash: {name: 'SHA-256'}
- },
- keyToSignWith, //from generateKey or importKey above
- data //ArrayBuffer of data you want to sign
- );
- }
-
- verifyKey(signature, data, keyToVerifyWith) {
- // Will verify with sender's public key
- return this._crypto.subtle.verify(
- {
- name: 'HMAC',
- hash: {name: 'SHA-256'}
- },
- keyToVerifyWith, //from generateKey or importKey above
- signature, //ArrayBuffer of the signature
- data //ArrayBuffer of the data
- );
- }
-
-}
diff --git a/src/js/darkwire.js b/src/js/darkwire.js
deleted file mode 100644
index e48af4e..0000000
--- a/src/js/darkwire.js
+++ /dev/null
@@ -1,345 +0,0 @@
-import _ from 'underscore';
-import AudioHandler from './audio';
-import CryptoUtil from './crypto';
-
-export default class Darkwire {
- constructor() {
- this._audio = new AudioHandler();
- this._cryptoUtil = new CryptoUtil();
- this._myUserId = false;
- this._connected = false;
- this._users = [];
- this._fileQueue = [];
- this._keys = {};
- }
-
- getFile(id) {
- let file = _.findWhere(this._fileQueue, {id: id}) || false;
-
- if (file) {
- // TODO: Destroy object from memory when retrieved
- }
-
- return file.data;
- }
-
- get keys() {
- return this._keys;
- }
-
- set keys(keys) {
- this._keys = keys;
- return this._keys;
- }
-
- get connected() {
- return this._connected;
- }
-
- set connected(state) {
- this._connected = state;
- return this._connected;
- }
-
- get audio() {
- return this._audio;
- }
-
- get users() {
- return this._users;
- }
-
- getUserById(id) {
- return _.findWhere(this._users, {id: id});
- }
-
- updateUser(data) {
- return new Promise((resolve, reject) => {
- let user = this.getUserById(data.id);
-
- if (!user) {
- return reject('User cannot be found');
- }
-
- let oldUsername = user.username;
-
- user.username = data.username;
- resolve(oldUsername);
- });
- }
-
- addUser(data) {
- let importKeysPromises = [];
- // Import all user keys if not already there
- _.each(data.users, (user) => {
- if (!_.findWhere(this._users, {id: user.id})) {
- let promise = new Promise((resolve, reject) => {
- let currentUser = user;
- Promise.all([
- this._cryptoUtil.importPrimaryKey(currentUser.publicKey, 'spki')
- ])
- .then((keys) => {
- this._users.push({
- id: currentUser.id,
- username: currentUser.username,
- publicKey: keys[0]
- });
- resolve();
- });
- });
-
- importKeysPromises.push(promise);
- }
- });
-
- if (!this._myUserId) {
- // Set my id if not already set
- let me = _.findWhere(data.users, {username: username});
- this._myUserId = me.id;
- }
-
- return importKeysPromises;
- }
-
- createUser(resolve, reject, username) {
- Promise.all([
- this._cryptoUtil.createPrimaryKeys()
- ])
- .then((data) => {
- this._keys = {
- public: data[0].publicKey,
- private: data[0].privateKey
- };
- return Promise.all([
- this._cryptoUtil.exportKey(data[0].publicKey, 'spki')
- ]);
- })
- .then((exportedKeys) => {
- if (!exportedKeys) {
- return reject('Could not create a user session');
- }
-
- return resolve({
- username: username,
- publicKey: exportedKeys[0]
- });
- });
- }
-
- checkSessionUsernames(username) {
- let matches = _.find(this._users, (users) => {
- return username.toLowerCase() === users.username.toLowerCase();
- });
-
- if (matches && matches.username) {
- return matches;
- }
-
- return false;
- }
-
- removeUser(data) {
- this._users = _.without(this._users, _.findWhere(this._users, {id: data.id}));
- return this._users;
- }
-
- updateUsername(username) {
- let user = null;
-
- return new Promise((resolve, reject) => {
- // Check if user is here
- if (username) {
- user = this.getUserById(this._myUserId);
- }
-
- if (user) {
- // User exists and is attempting to change username
- // Check if anyone else is using the requested username
- let userExists = this.checkSessionUsernames(username);
-
- if (userExists) {
- // Someone else is using the username requested, allow reformatting
- // if it is owned by the user, else reject the promise
- if (userExists.id !== this._myUserId) {
- return reject(username + ' is being used by someone else in this chat session.');
- }
- }
-
- return resolve({
- username: username,
- publicKey: user.publicKey
- });
- }
-
- // User doesn't exist, create the user
- return this.createUser(resolve, reject, username);
- });
- }
-
- encodeMessage(message, messageType, additionalData) {
- // Don't send unless other users exist
- return new Promise((resolve, reject) => {
- additionalData = additionalData || {};
-
- // if there is a non-empty message and a socket connection
- if (message && this._connected) {
- let vector = this._cryptoUtil.crypto.getRandomValues(new Uint8Array(16));
-
- let secretKey = null;
- let secretKeys = null;
- let messageData = null;
- let signature = null;
- let signingKey = null;
- let encryptedMessageData = null;
- let messageToEncode = {
- text: escape(message),
- additionalData: additionalData
- };
-
- messageToEncode = JSON.stringify(messageToEncode);
- // Generate new secret key and vector for each message
- this._cryptoUtil.createSecretKey()
- .then((key) => {
- secretKey = key;
- return this._cryptoUtil.createSigningKey();
- })
- .then((key) => {
- signingKey = key;
- // Generate secretKey and encrypt with each user's public key
- let promises = [];
- _.each(this._users, (user) => {
- // If not me
- if (user.username !== window.username) {
- let promise = new Promise((res, rej) => {
- let thisUser = user;
-
- let secretKeyStr;
-
- // Export secret key
- this._cryptoUtil.exportKey(secretKey, 'raw')
- .then((data) => {
- return this._cryptoUtil.encryptSecretKey(data, thisUser.publicKey);
- })
- .then((encryptedSecretKey) => {
- let encData = new Uint8Array(encryptedSecretKey);
- secretKeyStr = this._cryptoUtil.convertArrayBufferViewToString(encData);
- // Export HMAC signing key
- return this._cryptoUtil.exportKey(signingKey, 'raw');
- })
- .then((data) => {
- // Encrypt signing key with user's public key
- return this._cryptoUtil.encryptSigningKey(data, thisUser.publicKey);
- })
- .then((encryptedSigningKey) => {
- let encData = new Uint8Array(encryptedSigningKey);
- var str = this._cryptoUtil.convertArrayBufferViewToString(encData);
- res({
- id: thisUser.id,
- secretKey: secretKeyStr,
- encryptedSigningKey: str
- });
- });
- });
- promises.push(promise);
- }
- });
- return Promise.all(promises);
- })
- .then((data) => {
- secretKeys = data;
- messageData = this._cryptoUtil.convertStringToArrayBufferView(messageToEncode);
- return this._cryptoUtil.signKey(messageData, signingKey);
- })
- .then((data) => {
- signature = data;
- return this._cryptoUtil.encryptMessage(messageData, secretKey, vector);
- })
- .then((data) => {
- encryptedMessageData = data;
- let vct = this._cryptoUtil.convertArrayBufferViewToString(new Uint8Array(vector));
- let sig = this._cryptoUtil.convertArrayBufferViewToString(new Uint8Array(signature));
- let msg = this._cryptoUtil.convertArrayBufferViewToString(new Uint8Array(encryptedMessageData));
-
- resolve({
- message: msg,
- vector: vct,
- messageType: messageType,
- secretKeys: secretKeys,
- signature: sig
- });
- });
- }
-
- });
- }
-
- decodeMessage(data) {
- return new Promise((resolve, reject) => {
- let message = data.message;
- let messageData = this._cryptoUtil.convertStringToArrayBufferView(message);
- let username = data.username;
- let senderId = data.id;
- let vector = data.vector;
- let vectorData = this._cryptoUtil.convertStringToArrayBufferView(vector);
- let secretKeys = data.secretKeys;
- let decryptedMessageData;
- let decryptedMessage;
-
- let mySecretKey = _.find(secretKeys, (key) => {
- return key.id === this._myUserId;
- });
- let signature = data.signature;
- let signatureData = this._cryptoUtil.convertStringToArrayBufferView(signature);
- let secretKeyArrayBuffer = this._cryptoUtil.convertStringToArrayBufferView(mySecretKey.secretKey);
- let signingKeyArrayBuffer = this._cryptoUtil.convertStringToArrayBufferView(mySecretKey.encryptedSigningKey);
-
- this._cryptoUtil.decryptSecretKey(secretKeyArrayBuffer, this._keys.private)
- .then((data) => {
- return this._cryptoUtil.importSecretKey(new Uint8Array(data), 'raw');
- })
- .then((data) => {
- let secretKey = data;
- return this._cryptoUtil.decryptMessage(messageData, secretKey, vectorData);
- })
- .then((data) => {
- decryptedMessageData = data;
- decryptedMessage = JSON.parse(this._cryptoUtil.convertArrayBufferViewToString(new Uint8Array(data)));
- return this._cryptoUtil.decryptSigningKey(signingKeyArrayBuffer, this._keys.private);
- })
- .then((data) => {
- return this._cryptoUtil.importSigningKey(new Uint8Array(data), 'raw');
- })
- .then((data) => {
- let signingKey = data;
- return this._cryptoUtil.verifyKey(signatureData, decryptedMessageData, signingKey);
- })
- .then((bool) => {
- if (bool) {
- resolve({
- username: username,
- message: decryptedMessage,
- messageType: data.messageType,
- });
- }
- });
- });
- }
-
- generateMessage(fileId, fileName, messageType) {
- let message = '
is attempting to send you ' + fileName + ' (' + messageType + ')';
- message += ' WARNING: We cannot strictly verify the integrity of this file, its recipients or its owners. By accepting this file, you are liable for any risks that may arise from reciving this file.';
- message += ' Accept File
WARNING: Darkwire does not mask IP addresses nor can verify the integrity of parties recieving messages. Proceed with caution and always confirm recipients before starting a chat session.
-
Please also note that ALL CHATROOMS are public. Anyone can guess your room URL. If you need a more-private room, we recommend using a randomly generated room (+New Room button) and stay away from dictionary words.
-
-
Questions/comments? Email us at hello[at]darkwire.io
- Found a bug or want a new feature? Open a ticket on Github.