From 5bc576249b1059d8c7823f050bdacb30741385ce Mon Sep 17 00:00:00 2001 From: Audric Ackermann <audric@loki.network> Date: Wed, 30 Mar 2022 08:50:08 +1100 Subject: [PATCH] move signal.js to TS --- js/modules/.eslintrc | 14 -------------- js/modules/crypto.js | 21 --------------------- js/modules/signal.js | 17 ----------------- libtextsecure/crypto.js | 10 ++++++++-- preload.js | 6 ++---- ts/interactions/conversationInteractions.ts | 3 ++- ts/mains/main_renderer.ts | 14 +++++++------- ts/node/signal.ts | 12 ++++++++++++ ts/receiver/queuedJob.ts | 3 ++- ts/window.d.ts | 2 -- 10 files changed, 33 insertions(+), 69 deletions(-) delete mode 100644 js/modules/.eslintrc delete mode 100644 js/modules/crypto.js delete mode 100644 js/modules/signal.js create mode 100644 ts/node/signal.ts diff --git a/js/modules/.eslintrc b/js/modules/.eslintrc deleted file mode 100644 index 705203794..000000000 --- a/js/modules/.eslintrc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "env": { - "browser": false, - "commonjs": true, - "node": false - }, - "globals": { - "console": true, - "setTimeout": true - }, - "parserOptions": { - "sourceType": "module" - } -} diff --git a/js/modules/crypto.js b/js/modules/crypto.js deleted file mode 100644 index d60d0811e..000000000 --- a/js/modules/crypto.js +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-env browser */ -/* global dcodeIO */ - -/* eslint-disable camelcase, no-bitwise */ - -module.exports = { - bytesFromString, - getRandomBytes, -}; - -// Utility - -function bytesFromString(string) { - return dcodeIO.ByteBuffer.wrap(string, 'utf8').toArrayBuffer(); -} - -function getRandomBytes(n) { - const bytes = new Uint8Array(n); - window.crypto.getRandomValues(bytes); - return bytes; -} diff --git a/js/modules/signal.js b/js/modules/signal.js deleted file mode 100644 index bebade759..000000000 --- a/js/modules/signal.js +++ /dev/null @@ -1,17 +0,0 @@ -// The idea with this file is to make it webpackable for the style guide - -const Crypto = require('./crypto'); -const Data = require('../../ts/data/data'); -const OS = require('../../ts/OS'); -const Util = require('../../ts/util'); - -exports.setup = () => { - Data.init(); - - return { - Crypto, - Data, - OS, - Util, - }; -}; diff --git a/libtextsecure/crypto.js b/libtextsecure/crypto.js index afe1ce752..feeb28be4 100644 --- a/libtextsecure/crypto.js +++ b/libtextsecure/crypto.js @@ -28,6 +28,12 @@ return crypto.subtle.digest({ name: 'SHA-256' }, data); } + function getRandomBytesFromLength(n) { + const bytes = new Uint8Array(n); + crypto.getRandomValues(bytes); + return bytes; + } + window.textsecure = window.textsecure || {}; window.textsecure.crypto = { decryptAttachment(encryptedBin, keys, theirDigest) { @@ -89,7 +95,7 @@ }); }, encryptProfile(data, key) { - const iv = libsignal.crypto.getRandomBytes(PROFILE_IV_LENGTH); + const iv = getRandomBytesFromLength(PROFILE_IV_LENGTH); if (key.byteLength !== PROFILE_KEY_LENGTH) { throw new Error('Got invalid length profile key'); } @@ -166,7 +172,7 @@ }, getRandomBytes(size) { - return libsignal.crypto.getRandomBytes(size); + return getRandomBytesFromLength(size); }, }; })(); diff --git a/preload.js b/preload.js index 89e8a9bbe..109db2fdb 100644 --- a/preload.js +++ b/preload.js @@ -182,10 +182,10 @@ if (config.proxyUrl) { } window.nodeSetImmediate = setImmediate; -const Signal = require('./js/modules/signal'); +const Signal = require('./ts/node/signal'); const i18n = require('./ts/util/i18n'); -window.Signal = Signal.setup(); +window.Signal = Signal.setupSignal(); window.getSwarmPollingInstance = require('./ts/session/apis/snode_api').getSwarmPollingInstance; @@ -226,8 +226,6 @@ window.i18n = i18n.setupi18n(localFromEnv, localeMessages); window.moment = require('moment'); window.libsession = require('./ts/session'); -window.Signal.Data = require('./ts/data/data'); - window.addEventListener('contextmenu', e => { const editable = e.target.closest('textarea, input, [contenteditable="true"]'); const link = e.target.closest('a'); diff --git a/ts/interactions/conversationInteractions.ts b/ts/interactions/conversationInteractions.ts index 2e035b4df..c54089c16 100644 --- a/ts/interactions/conversationInteractions.ts +++ b/ts/interactions/conversationInteractions.ts @@ -46,6 +46,7 @@ import { processNewAttachment } from '../types/MessageAttachment'; import { urlToBlob } from '../types/attachments/VisualAttachment'; import { MIME } from '../types'; import { setLastProfileUpdateTimestamp } from '../util/storage'; +import { getSodium } from '../session/crypto'; export const getCompleteUrlForV2ConvoId = async (convoId: string) => { if (convoId.match(openGroupV2ConversationIdRegex)) { @@ -389,7 +390,7 @@ export async function uploadOurAvatar(newAvatarDecrypted?: ArrayBuffer) { let decryptedAvatarData; if (newAvatarDecrypted) { // Encrypt with a new key every time - profileKey = window.libsignal.crypto.getRandomBytes(32) as Uint8Array; + profileKey = (await getSodium()).randombytes_buf(32); decryptedAvatarData = newAvatarDecrypted; } else { // this is a reupload. no need to generate a new profileKey diff --git a/ts/mains/main_renderer.ts b/ts/mains/main_renderer.ts index e74f252cf..9e53481eb 100644 --- a/ts/mains/main_renderer.ts +++ b/ts/mains/main_renderer.ts @@ -179,24 +179,24 @@ Storage.onready(async () => { } }); -function manageExpiringData() { - window.Signal.Data.cleanSeenMessages(); - window.Signal.Data.cleanLastHashes(); +async function manageExpiringData() { + await Data.cleanSeenMessages(); + await Data.cleanLastHashes(); setTimeout(manageExpiringData, 1000 * 60 * 60); } // tslint:disable-next-line: max-func-body-length async function start() { - manageExpiringData(); + void manageExpiringData(); window.dispatchEvent(new Event('storage_ready')); window.log.info('Cleanup: starting...'); - const results = await Promise.all([window.Signal.Data.getOutgoingWithoutExpiresAt()]); + const results = await Promise.all([Data.getOutgoingWithoutExpiresAt()]); // Combine the models const messagesForCleanup = results.reduce( - (array, current) => array.concat(current.toArray()), + (array, current) => array.concat((current as any).toArray()), [] ); @@ -210,7 +210,7 @@ async function start() { } window.log.info(`Cleanup: Deleting unsent message ${sentAt}`); - await window.Signal.Data.removeMessage(message.id); + await Data.removeMessage(message.id); }) ); window.log.info('Cleanup: complete'); diff --git a/ts/node/signal.ts b/ts/node/signal.ts new file mode 100644 index 000000000..c1aef2a43 --- /dev/null +++ b/ts/node/signal.ts @@ -0,0 +1,12 @@ +// The idea with this file is to make it webpackable for the style guide + +import * as Data from '../../ts/data/data'; +import * as Util from '../../ts/util'; + +export const setupSignal = () => { + Data.init(); + + return { + Util, + }; +}; diff --git a/ts/receiver/queuedJob.ts b/ts/receiver/queuedJob.ts index 7e1ad3268..3ce440558 100644 --- a/ts/receiver/queuedJob.ts +++ b/ts/receiver/queuedJob.ts @@ -14,9 +14,10 @@ import { UserUtils } from '../session/utils'; import { showMessageRequestBanner } from '../state/ducks/userConfig'; import { MessageDirection } from '../models/messageType'; import { LinkPreviews } from '../util/linkPreviews'; +import { GoogleChrome } from '../util'; function contentTypeSupported(type: string): boolean { - const Chrome = window.Signal.Util.GoogleChrome; + const Chrome = GoogleChrome; return Chrome.isImageTypeSupported(type) || Chrome.isVideoTypeSupported(type); } diff --git a/ts/window.d.ts b/ts/window.d.ts index 8c6387576..95f0ab241 100644 --- a/ts/window.d.ts +++ b/ts/window.d.ts @@ -2,7 +2,6 @@ import {} from 'styled-components/cssprop'; import { LocalizerType } from '../ts/types/Util'; import { LibsignalProtocol } from '../../libtextsecure/libsignal-protocol'; -import { SignalInterface } from '../../js/modules/signal'; import { LibTextsecure } from '../libtextsecure'; import { Store } from 'redux'; @@ -22,7 +21,6 @@ declare global { Lodash: any; SessionSnodeAPI: any; Session: any; - Signal: SignalInterface; StubAppDotNetApi: any; StringView: any; StubMessageAPI: any;