"use strict";

Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.ScanQRCode = exports.ShowQRCode = undefined;

var _regenerator = require("babel-runtime/regenerator");

var _regenerator2 = _interopRequireDefault(_regenerator);

var _slicedToArray2 = require("babel-runtime/helpers/slicedToArray");

var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);

var _getIterator2 = require("babel-runtime/core-js/get-iterator");

var _getIterator3 = _interopRequireDefault(_getIterator2);

var _keys = require("babel-runtime/core-js/object/keys");

var _keys2 = _interopRequireDefault(_keys);

var _promise = require("babel-runtime/core-js/promise");

var _promise2 = _interopRequireDefault(_promise);

var _bluebird = require("bluebird");

var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of");

var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);

var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require("babel-runtime/helpers/createClass");

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn");

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require("babel-runtime/helpers/inherits");

var _inherits3 = _interopRequireDefault(_inherits2);

var _Base3 = require("./Base");

var _Base4 = _interopRequireDefault(_Base3);

var _Error = require("./Error");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/*
Copyright 2018 New Vector Ltd

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.
*/

/**
 * QR code key verification.
 * @module crypto/verification/QRCode
 */

var MATRIXTO_REGEXP = /^(?:https?:\/\/)?(?:www\.)?matrix\.to\/#\/([#@!+][^?]+)\?(.+)$/;
var KEY_REGEXP = /^key_([^:]+:.+)$/;

var newQRCodeError = (0, _Error.errorFactory)("m.qr_code.invalid", "Invalid QR code");

/**
 * @class crypto/verification/QRCode/ShowQRCode
 * @extends {module:crypto/verification/Base}
 */

var ShowQRCode = exports.ShowQRCode = function (_Base) {
    (0, _inherits3.default)(ShowQRCode, _Base);

    function ShowQRCode() {
        (0, _classCallCheck3.default)(this, ShowQRCode);
        return (0, _possibleConstructorReturn3.default)(this, (ShowQRCode.__proto__ || (0, _getPrototypeOf2.default)(ShowQRCode)).apply(this, arguments));
    }

    (0, _createClass3.default)(ShowQRCode, [{
        key: "_doVerification",
        value: function _doVerification() {
            if (!this._done) {
                var url = "https://matrix.to/#/" + this._baseApis.getUserId() + "?device=" + encodeURIComponent(this._baseApis.deviceId) + "&action=verify&key_ed25519%3A" + encodeURIComponent(this._baseApis.deviceId) + "=" + encodeURIComponent(this._baseApis.getDeviceEd25519Key());
                this.emit("show_qr_code", {
                    url: url
                });
            }
        }
    }]);
    return ShowQRCode;
}(_Base4.default);

ShowQRCode.NAME = "m.qr_code.show.v1";

/**
 * @class crypto/verification/QRCode/ScanQRCode
 * @extends {module:crypto/verification/Base}
 */

var ScanQRCode = exports.ScanQRCode = function (_Base2) {
    (0, _inherits3.default)(ScanQRCode, _Base2);

    function ScanQRCode() {
        (0, _classCallCheck3.default)(this, ScanQRCode);
        return (0, _possibleConstructorReturn3.default)(this, (ScanQRCode.__proto__ || (0, _getPrototypeOf2.default)(ScanQRCode)).apply(this, arguments));
    }

    (0, _createClass3.default)(ScanQRCode, [{
        key: "_doVerification",
        value: function () {
            var _ref = (0, _bluebird.coroutine)( /*#__PURE__*/_regenerator2.default.mark(function _callee() {
                var _this3 = this;

                var code, match, deviceId, keys, userId, params, action, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step$value, name, value, keyMatch;

                return _regenerator2.default.wrap(function _callee$(_context) {
                    while (1) {
                        switch (_context.prev = _context.next) {
                            case 0:
                                _context.next = 2;
                                return (0, _bluebird.resolve)(new _promise2.default(function (resolve, reject) {
                                    _this3.emit("scan", {
                                        done: resolve,
                                        cancel: function cancel() {
                                            return reject((0, _Error.newUserCancelledError)());
                                        }
                                    });
                                }));

                            case 2:
                                code = _context.sent;
                                match = code.match(MATRIXTO_REGEXP);
                                deviceId = void 0;
                                keys = {};

                                if (match) {
                                    _context.next = 8;
                                    break;
                                }

                                throw newQRCodeError();

                            case 8:
                                userId = match[1];
                                params = match[2].split("&").map(function (x) {
                                    return x.split("=", 2).map(decodeURIComponent);
                                });
                                action = void 0;
                                _iteratorNormalCompletion = true;
                                _didIteratorError = false;
                                _iteratorError = undefined;
                                _context.prev = 14;

                                for (_iterator = (0, _getIterator3.default)(params); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
                                    _step$value = (0, _slicedToArray3.default)(_step.value, 2), name = _step$value[0], value = _step$value[1];

                                    if (name === "device") {
                                        deviceId = value;
                                    } else if (name === "action") {
                                        action = value;
                                    } else {
                                        keyMatch = name.match(KEY_REGEXP);

                                        if (keyMatch) {
                                            keys[keyMatch[1]] = value;
                                        }
                                    }
                                }
                                _context.next = 22;
                                break;

                            case 18:
                                _context.prev = 18;
                                _context.t0 = _context["catch"](14);
                                _didIteratorError = true;
                                _iteratorError = _context.t0;

                            case 22:
                                _context.prev = 22;
                                _context.prev = 23;

                                if (!_iteratorNormalCompletion && _iterator.return) {
                                    _iterator.return();
                                }

                            case 25:
                                _context.prev = 25;

                                if (!_didIteratorError) {
                                    _context.next = 28;
                                    break;
                                }

                                throw _iteratorError;

                            case 28:
                                return _context.finish(25);

                            case 29:
                                return _context.finish(22);

                            case 30:
                                if (!(!deviceId || action !== "verify" || (0, _keys2.default)(keys).length === 0)) {
                                    _context.next = 32;
                                    break;
                                }

                                throw newQRCodeError();

                            case 32:
                                if (this.userId) {
                                    _context.next = 37;
                                    break;
                                }

                                _context.next = 35;
                                return (0, _bluebird.resolve)(new _promise2.default(function (resolve, reject) {
                                    _this3.emit("confirm_user_id", {
                                        userId: userId,
                                        confirm: resolve,
                                        cancel: function cancel() {
                                            return reject((0, _Error.newUserMismatchError)());
                                        }
                                    });
                                }));

                            case 35:
                                _context.next = 39;
                                break;

                            case 37:
                                if (!(this.userId !== userId)) {
                                    _context.next = 39;
                                    break;
                                }

                                throw (0, _Error.newUserMismatchError)({
                                    expected: this.userId,
                                    actual: userId
                                });

                            case 39:
                                _context.next = 41;
                                return (0, _bluebird.resolve)(this._verifyKeys(userId, keys, function (keyId, device, key) {
                                    if (device.keys[keyId] !== key) {
                                        throw (0, _Error.newKeyMismatchError)();
                                    }
                                }));

                            case 41:
                            case "end":
                                return _context.stop();
                        }
                    }
                }, _callee, this, [[14, 18, 22, 30], [23,, 25, 29]]);
            }));

            function _doVerification() {
                return _ref.apply(this, arguments);
            }

            return _doVerification;
        }()
    }], [{
        key: "factory",
        value: function factory() {
            for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
                args[_key] = arguments[_key];
            }

            return new (Function.prototype.bind.apply(ScanQRCode, [null].concat(args)))();
        }
    }]);
    return ScanQRCode;
}(_Base4.default);

ScanQRCode.NAME = "m.qr_code.scan.v1";
//# sourceMappingURL=QRCode.js.map