2017-08-15 13:54:22 +02:00
//@flow
2019-09-13 13:49:11 +02:00
import o from "ospec"
2019-08-21 15:12:04 +02:00
import {
base64ToUint8Array ,
2021-11-23 16:09:12 +01:00
downcast ,
2019-08-21 15:12:04 +02:00
hexToUint8Array ,
2021-11-23 16:09:12 +01:00
isSameTypeRef ,
neverNull ,
2019-08-21 15:12:04 +02:00
stringToUtf8Uint8Array ,
uint8ArrayToBase64 ,
utf8Uint8ArrayToString
2021-11-04 14:05:23 +01:00
} from "@tutao/tutanota-utils"
2021-12-07 15:30:53 +01:00
import { CryptoFacadeImpl } from "../../../src/api/worker/crypto/CryptoFacade"
2017-08-15 13:54:22 +02:00
import { ProgrammingError } from "../../../src/api/common/error/ProgrammingError"
import { Cardinality , ValueType } from "../../../src/api/common/EntityConstants"
2018-10-23 10:57:55 +02:00
import { BucketPermissionType , PermissionType } from "../../../src/api/common/TutanotaConstants"
2017-08-15 13:54:22 +02:00
import * as Mail from "../../../src/api/entities/tutanota/Mail"
2020-04-29 15:55:56 +02:00
import type { HttpMethodEnum } from "../../../src/api/common/EntityFunctions"
2017-08-15 13:54:22 +02:00
import * as Contact from "../../../src/api/entities/tutanota/Contact"
2020-04-29 15:55:56 +02:00
import { createContact } from "../../../src/api/entities/tutanota/Contact"
2017-08-15 13:54:22 +02:00
import * as UserIdReturn from "../../../src/api/entities/sys/UserIdReturn"
import { createUserIdReturn } from "../../../src/api/entities/sys/UserIdReturn"
import { createPermission } from "../../../src/api/entities/sys/Permission"
import { createBucket } from "../../../src/api/entities/sys/Bucket"
import { createGroup } from "../../../src/api/entities/sys/Group"
import { createKeyPair } from "../../../src/api/entities/sys/KeyPair"
2021-12-15 16:07:07 +01:00
import { BucketPermissionTypeRef , createBucketPermission } from "../../../src/api/entities/sys/BucketPermission"
2017-08-15 13:54:22 +02:00
import { createUser } from "../../../src/api/entities/sys/User"
import { createGroupMembership } from "../../../src/api/entities/sys/GroupMembership"
import { createContactAddress } from "../../../src/api/entities/tutanota/ContactAddress"
import { MailAddressTypeRef } from "../../../src/api/entities/tutanota/MailAddress"
2021-11-04 14:05:23 +01:00
import { mockAttribute , unmockAttribute } from "@tutao/tutanota-test-utils"
2021-10-15 16:50:50 +02:00
import { LoginFacadeImpl } from "../../../src/api/worker/facades/LoginFacade"
2020-04-29 15:55:56 +02:00
import { createBirthday } from "../../../src/api/entities/tutanota/Birthday"
2020-09-02 16:19:30 +02:00
import { RestClient } from "../../../src/api/worker/rest/RestClient"
2020-11-13 10:31:35 +01:00
import { createWebsocketLeaderStatus } from "../../../src/api/entities/sys/WebsocketLeaderStatus"
2021-06-24 11:56:16 +02:00
import type { ModelValue } from "../../../src/api/common/EntityTypes"
2021-12-07 15:30:53 +01:00
import { EntityClient } from "../../../src/api/common/EntityClient"
import { EntityRestClientMock } from "../worker/EntityRestClientMock"
2021-11-19 14:48:33 +01:00
import { hexToPrivateKey , hexToPublicKey } from "@tutao/tutanota-crypto/lib/encryption/Rsa"
import { aes128Decrypt , aes128Encrypt , aes128RandomKey , ENABLE _MAC , IV _BYTE _LENGTH } from "@tutao/tutanota-crypto/lib/encryption/Aes"
import { bitArrayToUint8Array , encryptKey , encryptRsaKey , random } from "@tutao/tutanota-crypto"
2021-11-23 16:09:12 +01:00
import { RsaWeb } from "../../../src/api/worker/crypto/RsaImplementation" ;
2021-12-07 15:30:53 +01:00
import { decryptValue , encryptValue , InstanceMapper } from "../../../src/api/worker/crypto/InstanceMapper"
import { locator } from "../../../src/api/worker/WorkerLocator"
2017-08-15 13:54:22 +02:00
2021-11-23 16:09:12 +01:00
const rsa = new RsaWeb ( )
const rsaEncrypt = rsa . encrypt
2017-08-15 13:54:22 +02:00
o . spec ( "crypto facade" , function ( ) {
let rsaPrivateHexKey = "02008e8bf43e2990a46042da8168aebec699d62e1e1fd068c5582fd1d5433cee8c8b918799e8ee1a22dd9d6e21dd959d7faed8034663225848c21b88c2733c73788875639425a87d54882285e598bf7e8c83861e8b77ab3cf62c53d35e143cee9bb8b3f36850aebd1548c1881dc7485bb51aa13c5a0391b88a8d7afce88ecd4a7e231ca7cfd063216d1d573ad769a6bb557c251ad34beb393a8fff4a886715315ba9eac0bc31541999b92fcb33d15efd2bd50bf77637d3fc5ba1c21082f67281957832ac832fbad6c383779341555993bd945659d7797b9c993396915e6decee9da2d5e060c27c3b5a9bc355ef4a38088af53e5f795ccc837f45d0583052547a736f02002a7622214a3c5dda96cf83f0ececc3381c06ccce69446c54a299fccef49d929c1893ae1326a9fe6cc9727f00048b4ff7833d26806d40a31bbf1bf3e063c779c61c41b765a854fd1338456e691bd1d48571343413479cf72fa920b34b9002fbbbff4ea86a3042fece17683686a055411357a824a01f8e3b277dd54c690d59fd4c8258009707d917ce43d4a337dc58bb55394c4f87b902e7f78fa0abe35e35444bda46bfbc38cf87c60fbe5c4beff49f8e6ddbf50d6caafeb92a6ccef75474879bdb82c9c9c5c35611207dbdb7601c87b254927f4d9fd25ba7694987b5ca70c8184058a91e86cb974a2b7694d6bb08a349b953e4c9a017d9eecada49eb2981dfe10100c7905e44c348447551bea10787da3aa869bbe45f10cff87688e2696474bd18405432f4846dcee886d2a967a61c1adb9a9bc08d75cee678053bf41262f0d9882c230bd5289518569714b961cec3072ed2900f52c9cdc802ee4e63781a3c4acaee4347bd9ab701399a0b96cdf22a75501f7f232069e7f00f5649be5ac3d73edd970100b6dbc3e909e1b69ab3f5dd6a55d7cc68d2b803d3da16941410ab7a5b963e5c50316a52380d4b571633d870ca746b4d6f36e0a9d90cf96a2ddb9c61d5bc9dbe74473f0be99f3642100c1b8ad9d592c6a28fa6570ccbb3f7bb86be8056f76473b978a55d458343dba3d0dcaf152d225f20ccd384706dda9dd2fb0f5f6976e603e901002fd80cc1af8fc3d9dc9f373bf6f5fada257f46610446d7ea9326b4ddc09f1511571e6040df929b6cb754a5e4cd18234e0dc93c20e2599eaca29301557728afdce50a1130898e2c344c63a56f4c928c472f027d76a43f2f74b2966654e3df8a8754d9fe3af964f1ca5cbceae3040adc0ab1105ad5092624872b66d79bdc1ed6410100295bc590e4ea4769f04030e747293b138e6d8e781140c01755b9e33fe9d88afa9c62a6dc04adc0b1c5e23388a71249fe589431f664c7d8eb2c5bcf890f53426b7c5dd72ced14d1965d96b12e19ef4bbc22ef858ae05c01314a05b673751b244d93eb1b1088e3053fa512f50abe1da314811f6a3a1faeadb9b58d419052132e59010032611a3359d91ce3567675726e48aca0601def22111f73a9fea5faeb9a95ec37754d2e52d7ae9444765c39c66264c02b38d096df1cebe6ea9951676663301e577fa5e3aec29a660e0fff36389671f47573d2259396874c33069ddb25dd5b03dcbf803272e68713c320ef7db05765f1088473c9788642e4b80a8eb40968fc0d7c"
let rsaPublicHexKey = "02008e8bf43e2990a46042da8168aebec699d62e1e1fd068c5582fd1d5433cee8c8b918799e8ee1a22dd9d6e21dd959d7faed8034663225848c21b88c2733c73788875639425a87d54882285e598bf7e8c83861e8b77ab3cf62c53d35e143cee9bb8b3f36850aebd1548c1881dc7485bb51aa13c5a0391b88a8d7afce88ecd4a7e231ca7cfd063216d1d573ad769a6bb557c251ad34beb393a8fff4a886715315ba9eac0bc31541999b92fcb33d15efd2bd50bf77637d3fc5ba1c21082f67281957832ac832fbad6c383779341555993bd945659d7797b9c993396915e6decee9da2d5e060c27c3b5a9bc355ef4a38088af53e5f795ccc837f45d0583052547a736f"
2021-12-07 15:30:53 +01:00
let login
let restClient
2021-12-15 16:07:07 +01:00
let instanceMapper = new InstanceMapper ( )
2021-12-07 15:30:53 +01:00
2021-12-15 16:07:07 +01:00
function createCrypto ( entityClient ) {
2021-12-07 15:30:53 +01:00
const crypto = new CryptoFacadeImpl ( login , entityClient
2021-12-15 16:07:07 +01:00
? ? new EntityClient ( new EntityRestClientMock ( ) ) , restClient , rsa )
2021-12-07 15:30:53 +01:00
locator . crypto = crypto
return crypto
}
2017-11-23 13:30:17 +01:00
o . before ( function ( ) {
2021-10-15 16:50:50 +02:00
const suspensionHandler = downcast ( { } )
restClient = new RestClient ( suspensionHandler )
2021-12-15 16:07:07 +01:00
login = new LoginFacadeImpl ( ( null : any ) , restClient , downcast ( { } ) , downcast ( { } ) , instanceMapper )
2021-12-07 15:30:53 +01:00
locator . login = login
2020-09-02 16:19:30 +02:00
locator . restClient = restClient
2021-11-23 16:09:12 +01:00
locator . rsa = rsa
2021-12-15 16:07:07 +01:00
locator . instanceMapper = instanceMapper
2017-11-23 13:30:17 +01:00
} )
2017-08-15 13:54:22 +02:00
o . afterEach ( function ( ) {
2021-12-07 15:30:53 +01:00
login . resetSession ( )
2017-08-15 13:54:22 +02:00
} )
function createValueType ( type , encrypted , cardinality ) : ModelValue {
return {
"name" : "test" ,
"id" : 426 ,
"since" : 6 ,
"type" : type ,
"cardinality" : cardinality ,
"final" : true ,
"encrypted" : encrypted
}
}
o . spec ( "decrypt value" , function ( ) {
2020-11-04 15:52:09 +01:00
o ( "decrypt string / number value without mac" , function ( ) {
2017-09-25 16:22:38 +02:00
let sk = aes128RandomKey ( )
let value = "this is a string value"
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , false ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . One ) , encryptedValue , sk ) ) . equals ( value )
2017-09-25 16:22:38 +02:00
value = "516546"
encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , false ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . One ) , encryptedValue , sk ) ) . equals ( value )
2017-09-25 16:22:38 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt string / number value with mac" , function ( ) {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
let value = "this is a string value"
2017-09-25 16:22:38 +02:00
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . One ) , encryptedValue , sk ) ) . equals ( value )
2017-08-15 13:54:22 +02:00
value = "516546"
2017-09-25 16:22:38 +02:00
encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . One ) , encryptedValue , sk ) ) . equals ( value )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt boolean value without mac" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Boolean , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = "0"
2017-09-25 16:22:38 +02:00
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , false ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( false )
2017-08-15 13:54:22 +02:00
value = "1"
2017-09-25 16:22:38 +02:00
encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , false ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
value = "32498"
2017-09-25 16:22:38 +02:00
encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , false ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt boolean value with mac" , function ( ) {
2017-09-25 16:22:38 +02:00
let valueType : ModelValue = createValueType ( ValueType . Boolean , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = "0"
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( false )
2017-09-25 16:22:38 +02:00
value = "1"
encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-09-25 16:22:38 +02:00
value = "32498"
encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-09-25 16:22:38 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt date value without mac" , function ( ) {
2017-09-25 16:22:38 +02:00
let valueType : ModelValue = createValueType ( ValueType . Date , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = new Date ( ) . getTime ( ) . toString ( )
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , false ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . deepEquals ( new Date ( parseInt ( value ) ) )
2017-09-25 16:22:38 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt date value with mac" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Date , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = new Date ( ) . getTime ( ) . toString ( )
2017-09-25 16:22:38 +02:00
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . deepEquals ( new Date ( parseInt ( value ) ) )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt bytes value without mac" , function ( ) {
2017-09-25 16:22:38 +02:00
let valueType : ModelValue = createValueType ( ValueType . Bytes , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = random . generateRandomData ( 5 )
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , value , random . generateRandomData ( IV _BYTE _LENGTH ) , true , false ) )
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2017-09-25 16:22:38 +02:00
o ( decryptedValue instanceof Uint8Array ) . equals ( true )
o ( Array . from ( decryptedValue ) ) . deepEquals ( Array . from ( value ) )
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt bytes value with mac" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Bytes , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = random . generateRandomData ( 5 )
2017-09-25 16:22:38 +02:00
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , value , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2017-08-15 13:54:22 +02:00
o ( decryptedValue instanceof Uint8Array ) . equals ( true )
o ( Array . from ( decryptedValue ) ) . deepEquals ( Array . from ( value ) )
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt compressedString" , function ( ) {
2019-08-21 15:12:04 +02:00
let valueType : ModelValue = createValueType ( ValueType . CompressedString , true , Cardinality . One )
let sk = aes128RandomKey ( )
2019-09-03 15:09:55 +02:00
let value = base64ToUint8Array ( "QHRlc3Q=" )
2019-08-21 15:12:04 +02:00
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , value , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2019-08-21 15:12:04 +02:00
o ( typeof decryptedValue === "string" ) . equals ( true )
o ( decryptedValue ) . equals ( "test" )
} )
2019-09-03 15:09:55 +02:00
o ( "decrypt compressedString w resize" , function ( ) {
let valueType : ModelValue = createValueType ( ValueType . CompressedString , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = base64ToUint8Array ( "X3RleHQgBQD//1FQdGV4dCA=" )
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , value , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2019-09-03 15:09:55 +02:00
o ( typeof decryptedValue === "string" ) . equals ( true )
o ( decryptedValue )
. equals ( "text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text " )
} )
2020-11-04 15:52:09 +01:00
o ( "decrypt empty compressedString" , function ( ) {
2019-08-21 15:12:04 +02:00
let valueType : ModelValue = createValueType ( ValueType . CompressedString , true , Cardinality . One )
let sk = aes128RandomKey ( )
let encryptedValue = uint8ArrayToBase64 ( aes128Encrypt ( sk , new Uint8Array ( [ ] ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , true ) )
2019-09-13 13:49:11 +02:00
let decryptedValue = decryptValue ( "test" , valueType , encryptedValue , sk )
2019-08-21 15:12:04 +02:00
o ( typeof decryptedValue === "string" ) . equals ( true )
o ( decryptedValue ) . equals ( "" )
} )
2020-11-04 15:52:09 +01:00
o ( "do not decrypt null values" , function ( ) {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
o ( decryptValue ( "test" , createValueType ( ValueType . Date , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
o ( decryptValue ( "test" , createValueType ( ValueType . Bytes , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
o ( decryptValue ( "test" , createValueType ( ValueType . Boolean , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
o ( decryptValue ( "test" , createValueType ( ValueType . Number , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
2017-08-15 13:54:22 +02:00
} )
o ( "throw error on ONE null values (String)" , testErrorOnNull ( ValueType . String ) )
o ( "throw error on ONE null values (Date)" , testErrorOnNull ( ValueType . Date ) )
o ( "throw error on ONE null values (Bytes)" , testErrorOnNull ( ValueType . Bytes ) )
o ( "throw error on ONE null values (Boolean)" , testErrorOnNull ( ValueType . Boolean ) )
o ( "throw error on ONE null values (Number)" , testErrorOnNull ( ValueType . Number ) )
2018-10-30 16:43:45 +01:00
2017-08-15 13:54:22 +02:00
function testErrorOnNull ( type ) {
return ( done ) => {
let sk = aes128RandomKey ( )
try {
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( type , true , Cardinality . One ) , null , sk ) ) . equals ( null )
2017-08-15 13:54:22 +02:00
} catch ( e ) {
o ( e instanceof ProgrammingError ) . equals ( true )
o ( e . message ) . equals ( 'Value test with cardinality ONE can not be null' )
done ( )
}
}
}
o ( "convert unencrypted Date to JS type" , function ( ) {
let value = new Date ( ) . getTime ( ) . toString ( )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Date , false , Cardinality . One ) , value , null ) ) . deepEquals ( new Date ( parseInt ( value ) ) )
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Bytes to JS type" , function ( ) {
let valueBytes = random . generateRandomData ( 15 )
let value = uint8ArrayToBase64 ( valueBytes )
2019-09-13 13:49:11 +02:00
o ( Array . from ( decryptValue ( "test" , createValueType ( ValueType . Bytes , false , Cardinality . One ) , value , null ) ) )
2019-08-21 15:12:04 +02:00
. deepEquals ( Array . from ( valueBytes ) )
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Boolean to JS type" , function ( ) {
let value = "0"
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Boolean , false , Cardinality . One ) , value , null ) ) . equals ( false )
2017-08-15 13:54:22 +02:00
value = "1"
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Boolean , false , Cardinality . One ) , value , null ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Number to JS type" , function ( ) {
let value = ""
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "0" )
2017-08-15 13:54:22 +02:00
value = "0"
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "0" )
2017-08-15 13:54:22 +02:00
value = "1"
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "1" )
2017-08-15 13:54:22 +02:00
} )
2019-08-21 15:12:04 +02:00
o ( "convert unencrypted compressedString to JS type" , function ( ) {
let value = ""
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . CompressedString , false , Cardinality . One ) , value , null ) ) . equals ( "" )
2019-08-21 15:12:04 +02:00
2019-09-03 15:09:55 +02:00
value = "QHRlc3Q="
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , createValueType ( ValueType . CompressedString , false , Cardinality . One ) , value , null ) ) . equals ( "test" )
2019-08-21 15:12:04 +02:00
} )
2017-08-15 13:54:22 +02:00
} )
o . spec ( "encryptValue" , function ( ) {
2020-11-04 15:52:09 +01:00
o ( "encrypt string / number value" , function ( ) {
2017-08-15 13:54:22 +02:00
var valueType = createValueType ( ValueType . String , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = "this is a string value"
2021-07-09 14:38:10 +02:00
let encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2018-10-30 16:43:45 +01:00
let expected = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ) , base64ToUint8Array ( encryptedValue )
. slice ( ENABLE _MAC ? 1 : 0 , ENABLE _MAC ? 17 : 16 ) , true , ENABLE _MAC ) )
2017-08-15 13:54:22 +02:00
o ( encryptedValue ) . deepEquals ( expected )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( value )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "encrypt boolean value" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Boolean , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = false
2021-07-09 14:38:10 +02:00
let encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2018-10-30 16:43:45 +01:00
let expected = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ? "1" : "0" ) , base64ToUint8Array ( encryptedValue )
. slice ( ENABLE _MAC ? 1 : 0 , ENABLE _MAC ? 17 : 16 ) , true , ENABLE _MAC ) )
2017-08-15 13:54:22 +02:00
o ( encryptedValue ) . equals ( expected )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( false )
2017-08-15 13:54:22 +02:00
value = true
2021-07-09 14:38:10 +02:00
encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2018-10-30 16:43:45 +01:00
expected = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value ? "1" : "0" ) , base64ToUint8Array ( encryptedValue )
. slice ( ENABLE _MAC ? 1 : 0 , ENABLE _MAC ? 17 : 16 ) , true , ENABLE _MAC ) )
2017-08-15 13:54:22 +02:00
o ( encryptedValue ) . equals ( expected )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "encrypt date value" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Date , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = new Date ( )
2021-07-09 14:38:10 +02:00
let encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2019-08-21 15:12:04 +02:00
let expected = uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( value . getTime ( )
. toString ( ) ) , base64ToUint8Array ( encryptedValue )
2018-10-30 16:43:45 +01:00
. slice ( ENABLE _MAC ? 1 : 0 , ENABLE _MAC ? 17 : 16 ) , true , ENABLE _MAC ) )
2019-09-13 13:49:11 +02:00
o ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) . deepEquals ( value )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "encrypt bytes value" , function ( ) {
2017-08-15 13:54:22 +02:00
let valueType : ModelValue = createValueType ( ValueType . Bytes , true , Cardinality . One )
let sk = aes128RandomKey ( )
let value = random . generateRandomData ( 5 )
2021-07-09 14:38:10 +02:00
let encryptedValue = neverNull ( encryptValue ( "test" , valueType , value , sk ) )
2018-10-30 16:43:45 +01:00
let expected = uint8ArrayToBase64 ( aes128Encrypt ( sk , value , base64ToUint8Array ( encryptedValue )
. slice ( ENABLE _MAC ? 1 : 0 , ENABLE _MAC ? 17 : 16 ) , true , ENABLE _MAC ) )
2017-08-15 13:54:22 +02:00
o ( encryptedValue ) . equals ( expected )
2019-09-13 13:49:11 +02:00
o ( Array . from ( decryptValue ( "test" , valueType , encryptedValue , sk ) ) ) . deepEquals ( Array . from ( value ) )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "do not encrypt null values" , function ( ) {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . String , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
o ( encryptValue ( "test" , createValueType ( ValueType . Date , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
o ( encryptValue ( "test" , createValueType ( ValueType . Bytes , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
o ( encryptValue ( "test" , createValueType ( ValueType . Boolean , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
o ( encryptValue ( "test" , createValueType ( ValueType . Number , true , Cardinality . ZeroOrOne ) , null , sk ) ) . equals ( null )
2017-08-15 13:54:22 +02:00
} )
2020-11-04 15:52:09 +01:00
o ( "accept null _id and _permissions value during encryption" , function ( ) {
2017-08-15 13:54:22 +02:00
let vt = {
"name" : "_id" ,
"id" : 426 ,
"since" : 6 ,
"type" : ValueType . GeneratedId ,
"cardinality" : Cardinality . One ,
"final" : true ,
"encrypted" : false
}
2019-09-13 13:49:11 +02:00
o ( encryptValue ( vt . name , vt , null , null ) ) . equals ( null )
2017-08-15 13:54:22 +02:00
vt . name = '_permissions'
2019-09-13 13:49:11 +02:00
o ( encryptValue ( vt . name , vt , null , null ) ) . equals ( null )
2017-08-15 13:54:22 +02:00
} )
o ( "throw error on ONE null values (enc String)" , testErrorOnNull ( ValueType . String ) )
o ( "throw error on ONE null values (enc Date)" , testErrorOnNull ( ValueType . Date ) )
o ( "throw error on ONE null values (enc Bytes)" , testErrorOnNull ( ValueType . Bytes ) )
o ( "throw error on ONE null values (enc Boolean)" , testErrorOnNull ( ValueType . Boolean ) )
o ( "throw error on ONE null values (enc Number)" , testErrorOnNull ( ValueType . Number ) )
2018-10-30 16:43:45 +01:00
2017-08-15 13:54:22 +02:00
function testErrorOnNull ( type ) {
return ( done ) => {
let sk = aes128RandomKey ( )
try {
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( type , true , Cardinality . One ) , null , sk ) ) . equals ( null )
2017-08-15 13:54:22 +02:00
} catch ( e ) {
o ( e instanceof ProgrammingError ) . equals ( true )
o ( e . message ) . equals ( 'Value test with cardinality ONE can not be null' )
done ( )
}
}
}
o ( "convert unencrypted Date to DB type" , function ( ) {
let value = new Date ( )
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Date , false , Cardinality . One ) , value , null ) ) . deepEquals ( value . getTime ( ) . toString ( ) )
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Bytes to DB type" , function ( ) {
let valueBytes = random . generateRandomData ( 15 )
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Bytes , false , Cardinality . One ) , valueBytes , null ) )
2019-08-21 15:12:04 +02:00
. deepEquals ( uint8ArrayToBase64 ( valueBytes ) )
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Boolean to DB type" , function ( ) {
let value = false
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Boolean , false , Cardinality . One ) , value , null ) ) . equals ( "0" )
2017-08-15 13:54:22 +02:00
value = true
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Boolean , false , Cardinality . One ) , value , null ) ) . equals ( "1" )
2017-08-15 13:54:22 +02:00
} )
o ( "convert unencrypted Number to DB type" , function ( ) {
let value = "0"
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "0" )
2017-08-15 13:54:22 +02:00
value = "1"
2019-09-13 13:49:11 +02:00
o ( encryptValue ( "test" , createValueType ( ValueType . Number , false , Cardinality . One ) , value , null ) ) . equals ( "1" )
2017-08-15 13:54:22 +02:00
} )
} )
function createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName ) {
let mail = {
_format : "0" ,
_area : "0" ,
_owner : "ownerId" ,
_ownerGroup : "ownerGroupId" ,
_ownerEncSessionKey : encryptKey ( gk , sk ) ,
_id : "mailId" ,
_permissions : "permissionListId" ,
receivedDate : new Date ( 1470039025474 ) . getTime ( ) . toString ( ) ,
sentDate : new Date ( 1470039021474 ) . getTime ( ) . toString ( ) ,
state : "" ,
trashed : false ,
unread : true ,
2017-09-25 16:22:38 +02:00
subject : uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( subject ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , ENABLE _MAC ) ) ,
2017-08-15 13:54:22 +02:00
replyType : "" ,
2017-09-25 16:22:38 +02:00
confidential : uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( confidential ? "1" : "0" ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , ENABLE _MAC ) ) ,
2017-08-15 13:54:22 +02:00
sender : {
_id : "senderId" ,
address : "hello@tutao.de" ,
2017-09-25 16:22:38 +02:00
name : uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( senderName ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , ENABLE _MAC ) )
2017-08-15 13:54:22 +02:00
} ,
bccRecipients : [ ] ,
ccRecipients : [ ] ,
2018-10-30 16:43:45 +01:00
toRecipients : [
{
_id : "recipientId" ,
address : "support@yahoo.com" ,
name : uint8ArrayToBase64 ( aes128Encrypt ( sk , stringToUtf8Uint8Array ( recipientName ) , random . generateRandomData ( IV _BYTE _LENGTH ) , true , ENABLE _MAC ) )
}
] ,
2017-08-15 13:54:22 +02:00
replyTos : [ ]
}
return mail ;
}
2019-09-13 13:49:11 +02:00
o ( "decrypt instance" , function ( done ) {
o . timeout ( 1000 )
2017-08-15 13:54:22 +02:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
let recipientName = "Yahoo"
let gk = aes128RandomKey ( )
let sk = aes128RandomKey ( )
let mail = createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName )
2021-12-15 16:07:07 +01:00
instanceMapper . decryptAndMapToInstance ( Mail . _TypeModel , mail , sk ) . then ( decrypted => {
2017-08-15 13:54:22 +02:00
o ( isSameTypeRef ( decrypted . _type , Mail . MailTypeRef ) ) . equals ( true )
o ( decrypted . receivedDate . getTime ( ) ) . equals ( 1470039025474 )
o ( decrypted . sentDate . getTime ( ) ) . equals ( 1470039021474 )
o ( decrypted . confidential ) . equals ( confidential )
o ( decrypted . subject ) . equals ( subject )
o ( decrypted . replyType ) . equals ( "0" )
// aggregates
2018-10-23 10:57:55 +02:00
o ( isSameTypeRef ( decrypted . sender . _type , MailAddressTypeRef ) ) . equals ( true )
2017-08-15 13:54:22 +02:00
o ( decrypted . sender . name ) . equals ( senderName )
o ( decrypted . sender . address ) . equals ( "hello@tutao.de" )
o ( decrypted . toRecipients [ 0 ] . name ) . equals ( recipientName )
o ( decrypted . toRecipients [ 0 ] . address ) . equals ( "support@yahoo.com" )
done ( )
} )
} )
2021-03-04 17:41:40 +01:00
o ( "encrypt instance" , async function ( ) {
2017-08-15 13:54:22 +02:00
let sk = aes128RandomKey ( )
let address = createContactAddress ( )
address . type = "0"
address . address = "Entenhausen"
address . customTypeName = "0"
let contact = Contact . createContact ( )
contact . _area = "0"
contact . _owner = "123"
contact . title = "Dr."
contact . firstName = "Max"
contact . lastName = "Meier"
contact . comment = "what?"
contact . company = "WIW"
contact . autoTransmitPassword = "stop bugging me!"
contact . addresses = [ address ]
2021-12-15 16:07:07 +01:00
const result : any = await instanceMapper . encryptAndMapToLiteral ( Contact . _TypeModel , contact , sk )
2021-03-04 17:41:40 +01:00
o ( result . _format ) . equals ( "0" )
o ( result . _ownerGroup ) . equals ( null )
o ( result . _ownerEncSessionKey ) . equals ( null )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . addresses [ 0 ] . type ) ) ) ) . equals ( contact . addresses [ 0 ] . type )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . addresses [ 0 ] . address ) ) ) )
. equals ( contact . addresses [ 0 ] . address )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . addresses [ 0 ] . customTypeName ) ) ) )
. equals ( contact . addresses [ 0 ] . customTypeName )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . title ) ) ) ) . equals ( contact . title )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . firstName ) ) ) ) . equals ( contact . firstName )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . lastName ) ) ) ) . equals ( contact . lastName )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . comment ) ) ) ) . equals ( contact . comment )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . company ) ) ) ) . equals ( contact . company )
o ( utf8Uint8ArrayToString ( aes128Decrypt ( sk , base64ToUint8Array ( result . autoTransmitPassword ) ) ) )
. equals ( contact . autoTransmitPassword )
2017-08-15 13:54:22 +02:00
} )
o ( "map unencrypted to instance" , function ( done ) {
let userIdLiteral = { "_format" : "0" , "userId" : "KOBqO7a----0" }
2021-12-15 16:07:07 +01:00
instanceMapper . decryptAndMapToInstance ( UserIdReturn . _TypeModel , userIdLiteral ) . then ( userIdReturn => {
2017-08-15 13:54:22 +02:00
o ( userIdReturn . _format ) . equals ( "0" )
o ( userIdReturn . userId ) . equals ( "KOBqO7a----0" )
done ( )
} )
} )
o ( "map unencrypted to DB literal" , function ( done ) {
let userIdReturn = createUserIdReturn ( )
userIdReturn . _format = "0"
userIdReturn . userId = "KOBqO7a----0"
let userIdLiteral = { "_format" : "0" , "userId" : "KOBqO7a----0" }
2021-12-15 16:07:07 +01:00
instanceMapper . encryptAndMapToLiteral ( UserIdReturn . _TypeModel , userIdReturn , null ) . then ( result => {
2017-08-15 13:54:22 +02:00
o ( result ) . deepEquals ( userIdLiteral )
done ( )
} )
} )
o ( "resolve session key: unencrypted instance" , function ( done ) {
let userIdLiteral = { "_format" : "0" , "userId" : "KOBqO7a----0" }
2021-12-15 16:07:07 +01:00
createCrypto ( null ) . resolveSessionKey ( UserIdReturn . _TypeModel , userIdLiteral ) . then ( sessionKey => {
2017-08-15 13:54:22 +02:00
o ( sessionKey ) . equals ( null )
done ( )
} )
} )
o ( "resolve session key: _ownerEncSessionKey instance" , function ( done ) {
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
let recipientName = "Yahoo"
let gk = aes128RandomKey ( )
let sk = aes128RandomKey ( )
2021-12-07 15:30:53 +01:00
login . groupKeys = { ownerGroupId : gk }
login . _user = createUser ( )
login . _user . userGroup = ( { group : 'ownerGroupId' } : any )
2017-08-15 13:54:22 +02:00
let mail = createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName )
2021-12-15 16:07:07 +01:00
createCrypto ( null ) . resolveSessionKey ( Mail . _TypeModel , mail ) . then ( sessionKey => {
2017-08-15 13:54:22 +02:00
o ( sessionKey ) . deepEquals ( sk )
} ) . then ( done )
} )
2020-11-13 10:31:35 +01:00
o ( "resolve session key: public key decryption of session key" , async function ( ) {
2021-01-25 12:50:28 +01:00
o . timeout ( 500 ) // in CI or with debugging it can take a while
2017-08-15 13:54:22 +02:00
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
let recipientName = "Yahoo"
let gk = aes128RandomKey ( )
let sk = aes128RandomKey ( )
let bk = aes128RandomKey ( )
let privateKey = hexToPrivateKey ( rsaPrivateHexKey )
let publicKey = hexToPublicKey ( rsaPublicHexKey )
let keyPair = createKeyPair ( )
keyPair . _id = "keyPairId"
keyPair . symEncPrivKey = encryptRsaKey ( gk , privateKey )
keyPair . pubKey = hexToUint8Array ( rsaPublicHexKey )
let userGroup = createGroup ( )
userGroup . _id = "userGroupId"
userGroup . keys = [ keyPair ]
let mail = createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName )
mail . _ownerEncSessionKey = null
let bucket = createBucket ( )
bucket . bucketPermissions = "bucketPermissionListId"
let permission = createPermission ( )
permission . bucketEncSessionKey = encryptKey ( bk , sk )
permission . _id = [ "permissionListId" , "permissionId" ]
permission . bucket = bucket
permission . type = PermissionType . Public
permission . _ownerGroup = userGroup . _id
2020-11-13 10:31:35 +01:00
const pubEncBucketKey = await rsaEncrypt ( publicKey , bitArrayToUint8Array ( bk ) )
let bucketPermission = createBucketPermission ( )
bucketPermission . pubEncBucketKey = pubEncBucketKey
bucketPermission . type = BucketPermissionType . Public
bucketPermission . _id = [ "bucketPermissionListId" , "bucketPermissionId" ]
bucketPermission . _ownerGroup = userGroup . _id
bucketPermission . group = userGroup . _id
2017-08-15 13:54:22 +02:00
2020-11-13 10:31:35 +01:00
let mem = createGroupMembership ( )
mem . group = userGroup . _id
2017-08-15 13:54:22 +02:00
2021-12-07 15:30:53 +01:00
login . _user = createUser ( )
login . _user . userGroup = mem
login . groupKeys [ 'userGroupId' ] = gk
login . _leaderStatus = createWebsocketLeaderStatus ( { leaderStatus : true } )
2020-11-13 10:31:35 +01:00
2021-12-15 16:07:07 +01:00
const entityClient = downcast ( {
loadAll : o . spy ( async ( typeRef , ... rest ) => isSameTypeRef ( BucketPermissionTypeRef , typeRef )
? [ bucketPermission ]
: [ permission ] ) ,
load : o . spy ( async ( ) => userGroup )
} )
2017-08-15 13:54:22 +02:00
2020-11-13 10:31:35 +01:00
// mock the invocation of UpdatePermissionKeyService
2021-12-15 16:07:07 +01:00
const updateMock = mockAttribute ( restClient , restClient . request , ( ) => Promise . resolve ( ) )
2020-11-13 10:31:35 +01:00
try {
2021-12-15 16:07:07 +01:00
const sessionKey = await createCrypto ( entityClient ) . resolveSessionKey ( Mail . _TypeModel , mail )
2020-11-13 10:31:35 +01:00
o ( sessionKey ) . deepEquals ( sk )
o ( ( restClient . request : any ) . callCount ) . equals ( 1 )
2021-12-15 16:07:07 +01:00
o ( entityClient . loadAll . callCount ) . equals ( 2 )
o ( entityClient . loadAll . calls . map ( call => call . args [ 1 ] ) ) . deepEquals ( [ permission . _id [ 0 ] , bucketPermission . _id [ 0 ] ] )
o ( entityClient . load . callCount ) . equals ( 1 )
o ( entityClient . load . args [ 1 ] ) . equals ( userGroup . _id )
2020-11-13 10:31:35 +01:00
} finally {
unmockAttribute ( updateMock )
}
2017-08-15 13:54:22 +02:00
} )
o ( "decryption errors should be written to _errors field" , function ( done ) {
let subject = "this is our subject"
let confidential = true
let senderName = "TutanotaTeam"
let recipientName = "Yahoo"
let gk = aes128RandomKey ( )
let sk = aes128RandomKey ( )
let bk = aes128RandomKey ( )
let mail = createMailLiteral ( gk , sk , subject , confidential , senderName , recipientName )
mail . subject = 'asdf'
2021-12-15 16:07:07 +01:00
instanceMapper . decryptAndMapToInstance ( Mail . _TypeModel , mail , sk ) . then ( instance => {
2017-08-15 13:54:22 +02:00
o ( typeof instance . _errors [ "subject" ] ) . equals ( "string" )
done ( )
} )
} )
2020-04-29 15:55:56 +02:00
o . spec ( "instance migrations" , function ( ) {
var mock
2021-12-07 15:30:53 +01:00
let entityClient
2020-04-29 15:55:56 +02:00
o . beforeEach ( function ( ) {
2021-12-07 15:30:53 +01:00
const updateMock = ( typeRef , method : HttpMethodEnum , listId : ? Id , id : ? Id , entity ) => {
2020-04-29 15:55:56 +02:00
return Promise . resolve ( )
}
2021-12-07 15:30:53 +01:00
entityClient = new EntityClient ( new EntityRestClientMock ( ) )
mock = mockAttribute ( entityClient , entityClient . update , updateMock )
2020-04-29 15:55:56 +02:00
} )
o . afterEach ( function ( ) {
unmockAttribute ( mock )
} )
o ( "contact migration without birthday" , function ( ) {
const contact = createContact ( )
2021-12-15 16:07:07 +01:00
return createCrypto ( entityClient ) . applyMigrationsForInstance ( contact ) . then ( migratedContact => {
2020-04-29 15:55:56 +02:00
o ( migratedContact . birthdayIso ) . equals ( null )
2021-12-07 15:30:53 +01:00
o ( entityClient . update . callCount ) . equals ( 0 )
2020-04-29 15:55:56 +02:00
} )
} )
o ( "contact migration without existing birthday" , function ( ) {
const contact = createContact ( )
contact . birthdayIso = "2019-05-01"
2021-12-15 16:07:07 +01:00
return createCrypto ( entityClient ) . applyMigrationsForInstance ( contact ) . then ( migratedContact => {
2020-04-29 15:55:56 +02:00
o ( migratedContact . birthdayIso ) . equals ( "2019-05-01" )
2021-12-07 15:30:53 +01:00
o ( entityClient . update . callCount ) . equals ( 0 )
2020-04-29 15:55:56 +02:00
} )
} )
o ( "contact migration without existing birthday and oldBirthdayDate" , function ( ) {
const contact = createContact ( )
2020-05-22 10:01:19 +02:00
contact . _id = [ "listid" , "id" ]
2020-04-29 15:55:56 +02:00
contact . birthdayIso = "2019-05-01"
contact . oldBirthdayDate = new Date ( 2000 , 4 , 1 )
2021-12-15 16:07:07 +01:00
return createCrypto ( entityClient ) . applyMigrationsForInstance ( contact ) . then ( migratedContact => {
2020-04-29 15:55:56 +02:00
o ( migratedContact . birthdayIso ) . equals ( "2019-05-01" )
2020-05-22 10:01:19 +02:00
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2021-12-07 15:30:53 +01:00
o ( entityClient . update . callCount ) . equals ( 1 )
2020-04-29 15:55:56 +02:00
} )
} )
o ( "contact migration with existing birthday and oldBirthdayAggregate" , function ( ) {
const contact = createContact ( )
2020-05-22 10:01:19 +02:00
contact . _id = [ "listid" , "id" ]
2020-04-29 15:55:56 +02:00
contact . birthdayIso = "2019-05-01"
contact . oldBirthdayAggregate = createBirthday ( )
contact . oldBirthdayAggregate . day = "01"
contact . oldBirthdayAggregate . month = "05"
contact . oldBirthdayAggregate . year = "2000"
2021-12-15 16:07:07 +01:00
return createCrypto ( entityClient ) . applyMigrationsForInstance ( contact ) . then ( migratedContact => {
2020-04-29 15:55:56 +02:00
o ( migratedContact . birthdayIso ) . equals ( "2019-05-01" )
2020-05-22 10:01:19 +02:00
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2021-12-07 15:30:53 +01:00
o ( entityClient . update . callCount ) . equals ( 1 )
2020-04-29 15:55:56 +02:00
} )
} )
o ( "contact migration from oldBirthdayAggregate" , function ( ) {
const contact = createContact ( )
contact . _id = [ "listid" , "id" ]
contact . birthdayIso = null
contact . oldBirthdayAggregate = createBirthday ( )
contact . oldBirthdayAggregate . day = "01"
contact . oldBirthdayAggregate . month = "05"
contact . oldBirthdayAggregate . year = "2000"
contact . oldBirthdayDate = new Date ( 1800 , 4 , 1 )
2021-12-15 16:07:07 +01:00
return createCrypto ( entityClient ) . applyMigrationsForInstance ( contact ) . then ( migratedContact => {
2020-04-29 15:55:56 +02:00
o ( migratedContact . birthdayIso ) . equals ( "2000-05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2021-12-07 15:30:53 +01:00
o ( entityClient . update . callCount ) . equals ( 1 )
2020-04-29 15:55:56 +02:00
} )
} )
o ( "contact migration from oldBirthdayDate" , function ( ) {
const contact = createContact ( )
contact . _id = [ "listid" , "id" ]
contact . birthdayIso = null
contact . oldBirthdayAggregate = null
contact . oldBirthdayDate = new Date ( 1800 , 4 , 1 )
2021-12-15 16:07:07 +01:00
return createCrypto ( entityClient ) . applyMigrationsForInstance ( contact ) . then ( migratedContact => {
2020-04-29 15:55:56 +02:00
o ( migratedContact . birthdayIso ) . equals ( "1800-05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2021-12-07 15:30:53 +01:00
o ( entityClient . update . callCount ) . equals ( 1 )
2020-04-29 15:55:56 +02:00
} )
} )
o ( "contact migration from oldBirthdayAggregate without year" , function ( ) {
const contact = createContact ( )
contact . _id = [ "listid" , "id" ]
contact . birthdayIso = null
contact . oldBirthdayAggregate = createBirthday ( )
contact . oldBirthdayAggregate . day = "01"
contact . oldBirthdayAggregate . month = "05"
contact . oldBirthdayAggregate . year = null
contact . oldBirthdayDate = null
2021-12-15 16:07:07 +01:00
return createCrypto ( entityClient ) . applyMigrationsForInstance ( contact ) . then ( migratedContact => {
2020-04-29 15:55:56 +02:00
o ( migratedContact . birthdayIso ) . equals ( "--05-01" )
o ( migratedContact . oldBirthdayAggregate ) . equals ( null )
o ( migratedContact . oldBirthdayDate ) . equals ( null )
2021-12-07 15:30:53 +01:00
o ( entityClient . update . callCount ) . equals ( 1 )
2020-04-29 15:55:56 +02:00
} )
} )
} )
2019-08-21 15:12:04 +02:00
} )