|
@@ -19,7 +19,7 @@
|
|
/// <reference types="@saltyrtc/task-relayed-data" />
|
|
/// <reference types="@saltyrtc/task-relayed-data" />
|
|
|
|
|
|
import * as msgpack from 'msgpack-lite';
|
|
import * as msgpack from 'msgpack-lite';
|
|
-import {hexToU8a, msgpackVisualizer} from '../helpers';
|
|
|
|
|
|
+import {hasFeature, hexToU8a, msgpackVisualizer} from '../helpers';
|
|
import {isContactReceiver, isDistributionListReceiver, isGroupReceiver} from '../typeguards';
|
|
import {isContactReceiver, isDistributionListReceiver, isGroupReceiver} from '../typeguards';
|
|
import {BatteryStatusService} from './battery';
|
|
import {BatteryStatusService} from './battery';
|
|
import {BrowserService} from './browser';
|
|
import {BrowserService} from './browser';
|
|
@@ -37,6 +37,7 @@ import {VersionService} from './version';
|
|
|
|
|
|
// Aliases
|
|
// Aliases
|
|
import InitializationStep = threema.InitializationStep;
|
|
import InitializationStep = threema.InitializationStep;
|
|
|
|
+import ContactReceiverFeature = threema.ContactReceiverFeature;
|
|
|
|
|
|
/**
|
|
/**
|
|
* This service handles everything related to the communication with the peer.
|
|
* This service handles everything related to the communication with the peer.
|
|
@@ -943,20 +944,20 @@ export class WebClientService {
|
|
return reject(this.$translate.instant('error.FILE_TOO_LARGE'));
|
|
return reject(this.$translate.instant('error.FILE_TOO_LARGE'));
|
|
}
|
|
}
|
|
|
|
|
|
- // Determine required feature level
|
|
|
|
- let requiredFeatureLevel = 3;
|
|
|
|
- let invalidFeatureLevelMessage = 'error.FILE_MESSAGES_NOT_SUPPORTED';
|
|
|
|
|
|
+ // Determine required feature mask
|
|
|
|
+ let requiredFeature: ContactReceiverFeature = ContactReceiverFeature.FILE;
|
|
|
|
+ let invalidFeatureMessage = 'error.FILE_MESSAGES_NOT_SUPPORTED';
|
|
if ((message as threema.FileMessageData).sendAsFile !== true) {
|
|
if ((message as threema.FileMessageData).sendAsFile !== true) {
|
|
// check mime type
|
|
// check mime type
|
|
const mime = (message as threema.FileMessageData).fileType;
|
|
const mime = (message as threema.FileMessageData).fileType;
|
|
|
|
|
|
if (this.mimeService.isAudio(mime)) {
|
|
if (this.mimeService.isAudio(mime)) {
|
|
- requiredFeatureLevel = 1;
|
|
|
|
- invalidFeatureLevelMessage = 'error.AUDIO_MESSAGES_NOT_SUPPORTED';
|
|
|
|
|
|
+ requiredFeature = ContactReceiverFeature.AUDIO;
|
|
|
|
+ invalidFeatureMessage = 'error.AUDIO_MESSAGES_NOT_SUPPORTED';
|
|
} else if (this.mimeService.isImage(mime)
|
|
} else if (this.mimeService.isImage(mime)
|
|
|| this.mimeService.isVideo(mime)) {
|
|
|| this.mimeService.isVideo(mime)) {
|
|
- requiredFeatureLevel = 0;
|
|
|
|
- invalidFeatureLevelMessage = 'error.MESSAGE_NOT_SUPPORTED';
|
|
|
|
|
|
+ requiredFeature = ContactReceiverFeature.AUDIO;
|
|
|
|
+ invalidFeatureMessage = 'error.MESSAGE_NOT_SUPPORTED';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -965,7 +966,7 @@ export class WebClientService {
|
|
// check receiver
|
|
// check receiver
|
|
switch (receiver.type) {
|
|
switch (receiver.type) {
|
|
case 'distributionList':
|
|
case 'distributionList':
|
|
- return reject(this.$translate.instant(invalidFeatureLevelMessage, {
|
|
|
|
|
|
+ return reject(this.$translate.instant(invalidFeatureMessage, {
|
|
receiverName: receiver.displayName}));
|
|
receiverName: receiver.displayName}));
|
|
case 'group':
|
|
case 'group':
|
|
const unsupportedMembers = [];
|
|
const unsupportedMembers = [];
|
|
@@ -978,14 +979,15 @@ export class WebClientService {
|
|
if (identity !== this.me.id) {
|
|
if (identity !== this.me.id) {
|
|
// tslint:disable-next-line: no-shadowed-variable
|
|
// tslint:disable-next-line: no-shadowed-variable
|
|
const contact = this.contacts.get(identity);
|
|
const contact = this.contacts.get(identity);
|
|
- if (contact !== undefined && contact.featureLevel < requiredFeatureLevel) {
|
|
|
|
|
|
+ if (contact === undefined
|
|
|
|
+ || !hasFeature(contact, requiredFeature, this.$log)) {
|
|
unsupportedMembers.push(contact.displayName);
|
|
unsupportedMembers.push(contact.displayName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
if (unsupportedMembers.length > 0) {
|
|
if (unsupportedMembers.length > 0) {
|
|
- return reject(this.$translate.instant(invalidFeatureLevelMessage, {
|
|
|
|
|
|
+ return reject(this.$translate.instant(invalidFeatureMessage, {
|
|
receiverName: unsupportedMembers.join(',')}));
|
|
receiverName: unsupportedMembers.join(',')}));
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -994,10 +996,10 @@ export class WebClientService {
|
|
if (contact === undefined) {
|
|
if (contact === undefined) {
|
|
this.$log.error('Cannot retrieve contact');
|
|
this.$log.error('Cannot retrieve contact');
|
|
return reject(this.$translate.instant('error.ERROR_OCCURRED'));
|
|
return reject(this.$translate.instant('error.ERROR_OCCURRED'));
|
|
- } else if (contact.featureLevel < requiredFeatureLevel) {
|
|
|
|
|
|
+ } else if (!hasFeature(contact, requiredFeature, this.$log)) {
|
|
this.$log.debug('Cannot send message: Feature level mismatch:',
|
|
this.$log.debug('Cannot send message: Feature level mismatch:',
|
|
- contact.featureLevel, '<', requiredFeatureLevel);
|
|
|
|
- return reject(this.$translate.instant(invalidFeatureLevelMessage, {
|
|
|
|
|
|
+ contact.featureMask, 'does not include', requiredFeature);
|
|
|
|
+ return reject(this.$translate.instant(invalidFeatureMessage, {
|
|
receiverName: contact.displayName}));
|
|
receiverName: contact.displayName}));
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -2182,7 +2184,7 @@ export class WebClientService {
|
|
avatar: {
|
|
avatar: {
|
|
high: data.avatar,
|
|
high: data.avatar,
|
|
},
|
|
},
|
|
- featureLevel: 3,
|
|
|
|
|
|
+ featureMask: 0xFF,
|
|
verificationLevel: 3,
|
|
verificationLevel: 3,
|
|
state: 'ACTIVE',
|
|
state: 'ACTIVE',
|
|
access: {
|
|
access: {
|