Typify PubKey

pull/1157/head
Vincent 5 years ago
parent 372754e360
commit b8ec9bd995

@ -1,7 +1,7 @@
import { ContentMessage } from '../ContentMessage';
import { SignalService } from '../../../../../protobuf';
export abstract class SyncMessage extends ContentMessage {
export class SyncMessage extends ContentMessage {
public ttl(): number {
return this.getDefaultTTL();
}
@ -12,5 +12,7 @@ export abstract class SyncMessage extends ContentMessage {
});
}
protected abstract syncProto(): SignalService.SyncMessage;
protected syncProto(): SignalService.SyncMessage {
return new SignalService.SyncMessage({});
}
}

@ -58,7 +58,7 @@ export class MessageQueue implements MessageQueueInterface {
// If you see an open group message just call
// MessageSender.sendToOpenGroup directly.
}
public sendSyncMessage(message: ContentMessage) {
// PSEDUOCODE
// if message is undefined

@ -1,12 +1,7 @@
import {
<<<<<<< HEAD
OpenGroupMessage,
ContentMessage,
SyncMessage,
=======
ContentMessage as OutgoingContentMessage,
OpenGroupMessage,
>>>>>>> 935ac8d8f911616731c20aa5b45b79bea6895731
} from '../messages/outgoing';
import { RawMessage } from '../types/RawMessage';
import { TypedEventEmitter } from '../utils';

@ -1,7 +1,8 @@
import * as Data from '../../../js/modules/data';
import { RawMessage } from '../types/RawMessage';
import { ChatMessage, ContentMessage } from '../messages/outgoing';
import { MessageUtils, PubKey } from '../utils';
import * as MessageUtils from '../utils';
import { PubKey } from '../types';
// TODO: We should be able to import functions straight from the db here without going through the window object
@ -80,9 +81,16 @@ export class PendingMessageCache {
public getDevices(): Array<PubKey> {
// Gets all devices with pending messages
const pubkeys = [...new Set(this.cache.map(m => m.device))];
const pubkeyStrings = [...new Set(this.cache.map(m => m.device))];
return pubkeys.map(d => PubKey.from(d));
const pubkeys: Array<PubKey> = [];
pubkeyStrings.forEach(pubkey => {
if (PubKey.validate(pubkey)) {
pubkeys.push(new PubKey(pubkey));
}
});
return pubkeys;
}
public async init() {
@ -90,7 +98,7 @@ export class PendingMessageCache {
this.cache = messages;
}
public async getFromStorage(): Promise<Array<RawMessage>> {
private async getFromStorage(): Promise<Array<RawMessage>> {
// tslint:disable-next-line: no-backbone-get-set-outside-model
const pendingMessagesData = await Data.getItemById('pendingMessages');
const pendingMessagesJSON = pendingMessagesData
@ -109,7 +117,7 @@ export class PendingMessageCache {
return encodedPendingMessages;
}
public async syncCacheWithDB() {
private async syncCacheWithDB() {
// Only call when adding / removing from cache.
const encodedPendingMessages = JSON.stringify(this.cache) || '';
await Data.createOrUpdateItem({

@ -0,0 +1,47 @@
import * as crypto from 'crypto';
export enum PubKeyCategory {
Primary = 'priamry',
Secondary = 'secondary',
Group = 'group',
}
export class PubKey {
private static readonly PUBKEY_LEN = 66;
private static readonly regex: string = `^05[0-9a-fA-F]{${PubKey.PUBKEY_LEN - 2}}$`;
public readonly key: string;
public type?: PubKeyCategory;
constructor(pubkeyString: string, type?: PubKeyCategory) {
PubKey.validate(pubkeyString);
this.key = pubkeyString;
this.type = type;
}
public static from(pubkeyString: string): PubKey | undefined {
// Returns a new instance if the pubkey is valid
if (PubKey.validate(pubkeyString)) {
return new PubKey(pubkeyString);
}
return undefined;
}
public static validate(pubkeyString: string): boolean {
if (pubkeyString.match(PubKey.regex)) {
return true;
}
return false;
}
public static generateFake(): PubKey {
// Generates a mock pubkey for testing
const numBytes = (PubKey.PUBKEY_LEN / 2) - 1;
const hexBuffer = crypto.randomBytes(numBytes).toString('hex');
const pubkeyString = `05${hexBuffer}`;
return new PubKey(pubkeyString);
}
}

@ -0,0 +1,3 @@
export * from './EncryptionType';
export * from './RawMessage';
export * from './PubKey';

@ -1,89 +0,0 @@
import { RawMessage } from '../types/RawMessage';
import { ContentMessage } from '../messages/outgoing';
import { EncryptionType } from '../types/EncryptionType';
import * as crypto from 'crypto';
function toRawMessage(device: PubKey, message: ContentMessage): RawMessage {
const ttl = message.ttl();
const timestamp = message.timestamp;
const plainTextBuffer = message.plainTextBuffer();
// Get EncryptionType depending on message type.
// let encryption: EncryptionType;
// switch (message.constructor.name) {
// case MessageType.Chat:
// encryption = EncryptionType.Signal;
// break;
// case MessageType.SessionReset:
// encryption = EncryptionType
// }
// export enum EncryptionType {
// Signal,
// SessionReset,
// MediumGroup,
// }
// tslint:disable-next-line: no-unnecessary-local-variable
const rawMessage: RawMessage = {
identifier: message.identifier,
plainTextBuffer,
timestamp,
device: device.key,
ttl,
encryption: EncryptionType.Signal,
};
return rawMessage;
}
export enum PubKeyType {
Primary = 'priamry',
Secondary = 'secondary',
Group = 'group',
}
export class PubKey {
private static readonly regex: string = '^0[0-9a-fA-F]{65}$';
public readonly key: string;
public type?: PubKeyType;
constructor(pubkeyString: string, type?: PubKeyType) {
PubKey.validate(pubkeyString);
this.key = pubkeyString;
this.type = type;
}
public static from(pubkeyString: string): PubKey {
// Returns a new instance if the pubkey is valid
if (PubKey.validate(pubkeyString)) {
return new PubKey(pubkeyString);
}
throw new Error('Invalid pubkey format');
}
public static validate(pubkeyString: string): boolean {
if (pubkeyString.match(PubKey.regex)) {
return true;
}
throw new Error('Invalid pubkey format');
}
public static generate(): PubKey {
// Generates a mock pubkey for testing
const PUBKEY_LEN = 66;
const numBytes = PUBKEY_LEN / 2;
const hexBuffer = crypto.randomBytes(numBytes).toString('hex');
const pubkeyString = `0${hexBuffer}`.slice(0, PUBKEY_LEN);
return new PubKey(pubkeyString);
}
}
// Functions / Tools
export const MessageUtils = {
toRawMessage,
};

@ -0,0 +1,55 @@
import * as crypto from 'crypto';
import uuid from 'uuid';
import { RawMessage } from '../types/RawMessage';
import { ChatMessage, ContentMessage } from '../messages/outgoing';
import { EncryptionType } from '../types/EncryptionType';
export function toRawMessage(device: PubKey, message: ContentMessage): RawMessage {
const ttl = message.ttl();
const timestamp = message.timestamp;
const plainTextBuffer = message.plainTextBuffer();
// Get EncryptionType depending on message type.
// let encryption: EncryptionType;
// switch (message.constructor.name) {
// case MessageType.Chat:
// encryption = EncryptionType.Signal;
// break;
// case MessageType.SessionReset:
// encryption = EncryptionType
// }
// export enum EncryptionType {
// Signal,
// SessionReset,
// MediumGroup,
// }
// tslint:disable-next-line: no-unnecessary-local-variable
const rawMessage: RawMessage = {
identifier: message.identifier,
plainTextBuffer,
timestamp,
device: device.key,
ttl,
encryption: EncryptionType.Signal,
};
return rawMessage;
}
export function generateUniqueChatMessage(): ChatMessage {
return new ChatMessage({
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
identifier: uuid(),
timestamp: Date.now(),
attachments: undefined,
quote: undefined,
expireTimer: undefined,
lokiProfile: undefined,
preview: undefined,
});
}

@ -1,3 +1,3 @@
export * from './TypedEmitter';
export * from './JobQueue';
export * from './MessageUtils';
export * from './Messages';

@ -3,9 +3,13 @@ import * as sinon from 'sinon';
import uuid from 'uuid';
import { ChatMessage } from '../../../session/messages/outgoing';
import { MessageUtils, PubKey } from '../../../session/utils';
import * as MessageUtils from '../../../session/utils';
import { TestUtils } from '../../../test/test-utils';
import { PendingMessageCache } from '../../../session/sending/PendingMessageCache';
import { RawMessage } from '../../../session/types/RawMessage';
import { PubKey } from '../../../session/types';
import * as Data from '../../../../js/modules/data';
describe('PendingMessageCache', () => {
const sandbox = sinon.createSandbox();
@ -13,34 +17,26 @@ describe('PendingMessageCache', () => {
// tslint:disable-next-line: promise-function-async
const wrapInPromise = (value: any) =>
new Promise(r => {
r(value);
});
const generateUniqueMessage = (): ChatMessage => {
return new ChatMessage({
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit',
identifier: uuid(),
timestamp: Date.now(),
attachments: undefined,
quote: undefined,
expireTimer: undefined,
lokiProfile: undefined,
preview: undefined,
new Promise(resolve => {
resolve(value);
});
};
beforeEach(async () => {
const mockStorageObject = wrapInPromise([] as Array<RawMessage>);
const voidPromise = wrapInPromise(undefined);
// Stub out methods which touch the database.
sandbox
.stub(PendingMessageCache.prototype, 'getFromStorage')
.returns(mockStorageObject);
sandbox
.stub(PendingMessageCache.prototype, 'syncCacheWithDB')
.returns(voidPromise);
// Stub out methods which touch the database
const storageID = 'pendingMessages';
let data: Data.StorageItem = {
id: storageID,
value: '',
};
TestUtils.stubData('getItemById').withArgs('pendingMessages').callsFake(async () => {
return wrapInPromise(data);
});
TestUtils.stubData('createOrUpdateItem').callsFake((item: Data.StorageItem) => {
data = item;
});
// Initialize new stubbed cache
pendingMessageCacheStub = new PendingMessageCache();
@ -60,8 +56,8 @@ describe('PendingMessageCache', () => {
});
it('can add to cache', async () => {
const device = PubKey.generate();
const message = generateUniqueMessage();
const device = PubKey.generateFake();
const message = MessageUtils.generateUniqueChatMessage();
const rawMessage = MessageUtils.toRawMessage(device, message);
await pendingMessageCacheStub.add(device, message);
@ -77,8 +73,8 @@ describe('PendingMessageCache', () => {
});
it('can remove from cache', async () => {
const device = PubKey.generate();
const message = generateUniqueMessage();
const device = PubKey.generateFake();
const message = MessageUtils.generateUniqueChatMessage();
const rawMessage = MessageUtils.toRawMessage(device, message);
await pendingMessageCacheStub.add(device, message);
@ -98,16 +94,16 @@ describe('PendingMessageCache', () => {
it('can get devices', async () => {
const cacheItems = [
{
device: PubKey.generate(),
message: generateUniqueMessage(),
device: PubKey.generateFake(),
message: MessageUtils.generateUniqueChatMessage(),
},
{
device: PubKey.generate(),
message: generateUniqueMessage(),
device: PubKey.generateFake(),
message: MessageUtils.generateUniqueChatMessage(),
},
{
device: PubKey.generate(),
message: generateUniqueMessage(),
device: PubKey.generateFake(),
message: MessageUtils.generateUniqueChatMessage(),
},
];
@ -130,12 +126,12 @@ describe('PendingMessageCache', () => {
it('can get pending for device', async () => {
const cacheItems = [
{
device: PubKey.generate(),
message: generateUniqueMessage(),
device: PubKey.generateFake(),
message: MessageUtils.generateUniqueChatMessage(),
},
{
device: PubKey.generate(),
message: generateUniqueMessage(),
device: PubKey.generateFake(),
message: MessageUtils.generateUniqueChatMessage(),
},
];
@ -157,8 +153,8 @@ describe('PendingMessageCache', () => {
});
it('can find nothing when empty', async () => {
const device = PubKey.generate();
const message = generateUniqueMessage();
const device = PubKey.generateFake();
const message = MessageUtils.generateUniqueChatMessage();
const rawMessage = MessageUtils.toRawMessage(device, message);
const foundMessage = pendingMessageCacheStub.find(rawMessage);
@ -166,8 +162,8 @@ describe('PendingMessageCache', () => {
});
it('can find message in cache', async () => {
const device = PubKey.generate();
const message = generateUniqueMessage();
const device = PubKey.generateFake();
const message = MessageUtils.generateUniqueChatMessage();
const rawMessage = MessageUtils.toRawMessage(device, message);
await pendingMessageCacheStub.add(device, message);
@ -183,16 +179,16 @@ describe('PendingMessageCache', () => {
it('can clear cache', async () => {
const cacheItems = [
{
device: PubKey.generate(),
message: generateUniqueMessage(),
device: PubKey.generateFake(),
message: MessageUtils.generateUniqueChatMessage(),
},
{
device: PubKey.generate(),
message: generateUniqueMessage(),
device: PubKey.generateFake(),
message: MessageUtils.generateUniqueChatMessage(),
},
{
device: PubKey.generate(),
message: generateUniqueMessage(),
device: PubKey.generateFake(),
message: MessageUtils.generateUniqueChatMessage(),
},
];

Loading…
Cancel
Save