All files / symbol-qr-library/src/schemas ExportAccountDataSchema.ts

88.89% Statements 24/27
78.95% Branches 15/19
100% Functions 4/4
88.46% Lines 23/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111                                  1x                           1x     11x                   1x 11x   8x 8x         3x                                   1x       7x       7x 7x       7x       7x   7x     6x 2x     4x 4x     4x     3x     1x   1x  
/**
 * Copyright 2019 NEM
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
// internal dependencies
import {
    AccountQR,
    EncryptedPayload,
    EncryptionService,
    QRCodeDataSchema,
    QRCodeType,
} from '../../index';
 
/**
 * Class `ExportAccountDataSchema` describes an export
 * account QR code data schema.
 *
 * @since 0.3.0
 */
class ExportAccountDataSchema extends QRCodeDataSchema {
 
    constructor() {
        super();
    }
 
    /**
     * The `getData()` method returns an object
     * that will be stored in the `data` field of
     * the underlying QR Code JSON content.
     *
     * @return {any}
     */
    public getData(qr: AccountQR): any {
        if (qr.encrypted) {
            // we will store a password encrypted copy of the private key
            const encryptedData = EncryptionService.encrypt(qr.accountPrivateKey, qr.password);
            return {
                "ciphertext": encryptedData.ciphertext,
                "salt": encryptedData.salt,
            };
        } else {
            return {
                "privateKey": qr.accountPrivateKey
            }
        }
    }
 
    /**
     * Parse a JSON QR code content into a AccountQR
     * object.
     *
     * @param   json        {string}
     * @param   password    {string=} Optional password
     * @return  {AccountQR}
     * @throws  {Error}     On empty `json` given.
     * @throws  {Error}     On missing `type` field value.
     * @throws  {Error}     On unrecognized QR code `type` field value.
     * @throws  {Error}     On invalid password.
     */
    public static parse(
        json: string,
        password?: string,
    ): AccountQR {
        Iif (! json.length) {
            throw new Error('JSON argument cannot be empty.');
        }
 
        const jsonObj = JSON.parse(json);
        Iif (!jsonObj.type || jsonObj.type !== QRCodeType.ExportAccount) {
            throw new Error('Invalid type field value for AccountQR.');
        }
 
        Iif (!jsonObj.hasOwnProperty('data')) {
            throw new Error('Missing mandatory property for payload.');
        }
 
        try {
            // decrypt private key
            const privKey = EncryptedPayload.isDataEncrypted(jsonObj.data) ? EncryptionService.decrypt(EncryptedPayload.fromJSON(JSON.stringify(jsonObj.data)), password) : jsonObj.data.privateKey;
 
            // more content validation
            if (!privKey || (privKey.length !== 64 && privKey.length !== 66)) {
                throw new Error('Invalid private key.');
            }
 
            const network = jsonObj.network_id;
            const generationHash = jsonObj.chain_id;
 
            // create account
            return new AccountQR(privKey, network, generationHash, password);
        }
        catch (e) {
            throw new Error('Could not parse account information.');
        }
    }
}
 
export {ExportAccountDataSchema};