vue-recheck-authorizer
Version:
A set of Vue.js components for authentication and data interaction with ReCheck Platform.
1,860 lines (1,624 loc) • 65.4 kB
JavaScript
import { QrcodeStream } from 'vue-qrcode-reader';
import { decrypt, encrypt } from 'aes256';
import e2e from 'recheck-clientjs-library';
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
var script = {
name: 'card'
};
function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
if (typeof shadowMode !== 'boolean') {
createInjectorSSR = createInjector;
createInjector = shadowMode;
shadowMode = false;
}
// Vue.extend constructor export interop.
const options = typeof script === 'function' ? script.options : script;
// render functions
if (template && template.render) {
options.render = template.render;
options.staticRenderFns = template.staticRenderFns;
options._compiled = true;
// functional template
if (isFunctionalTemplate) {
options.functional = true;
}
}
// scopedId
if (scopeId) {
options._scopeId = scopeId;
}
let hook;
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
// inject component styles
if (style) {
style.call(this, createInjectorSSR(context));
}
// register component module identifier for async chunk inference
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook;
}
else if (style) {
hook = shadowMode
? function (context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
}
: function (context) {
style.call(this, createInjector(context));
};
}
if (hook) {
if (options.functional) {
// register for functional component in vue file
const originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
}
else {
// inject component registration as beforeCreate hook
const existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
}
return script;
}
/* script */
const __vue_script__ = script;
/* template */
var __vue_render__ = function () {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "card"
}, [_c('header', {
staticClass: "card-header"
}, [_c('h3', [_vm._t("header")], 2)]), _vm._v(" "), _c('div', {
staticClass: "card-body"
}, [_vm._t("default")], 2), _vm._v(" "), _c('footer', {
staticClass: "card-footer"
}, [_vm._t("footer")], 2)]);
};
var __vue_staticRenderFns__ = [];
/* style */
const __vue_inject_styles__ = undefined;
/* scoped */
const __vue_scope_id__ = undefined;
/* module identifier */
const __vue_module_identifier__ = undefined;
/* functional template */
const __vue_is_functional_template__ = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__ = /*#__PURE__*/normalizeComponent({
render: __vue_render__,
staticRenderFns: __vue_staticRenderFns__
}, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, false, undefined, undefined, undefined);
//
//
//
//
//
//
//
//
var script$1 = {
name: 'alert',
data() {
return {
visible: false,
message: '',
color: '',
timeout: 2000
};
},
methods: {
hideAlert() {
this.visible = false;
}
},
mounted() {
this.$root.$on('alertOn', (message, color, timeout) => {
this.visible = true;
this.message = message;
this.timeout = timeout ? timeout : 2000;
this.color = color === 'green' ? '#89CA02' : '#ff0000';
setTimeout(() => this.hideAlert(), this.timeout);
});
this.$root.$on('alertOff', () => {
this.visible = false;
});
}
};
/* script */
const __vue_script__$1 = script$1;
/* template */
var __vue_render__$1 = function () {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('transition', [_c('div', {
staticClass: "alert",
class: [_vm.visible ? 'is-visible' : ''],
style: {
backgroundColor: _vm.color
}
}, [_c('p', [_vm._v(_vm._s(_vm.message))])])]);
};
var __vue_staticRenderFns__$1 = [];
/* style */
const __vue_inject_styles__$1 = undefined;
/* scoped */
const __vue_scope_id__$1 = undefined;
/* module identifier */
const __vue_module_identifier__$1 = undefined;
/* functional template */
const __vue_is_functional_template__$1 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$1 = /*#__PURE__*/normalizeComponent({
render: __vue_render__$1,
staticRenderFns: __vue_staticRenderFns__$1
}, __vue_inject_styles__$1, __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, false, undefined, undefined, undefined);
//
//
//
//
var script$2 = {
name: 'loader',
mounted() {
this.$root.$on('loaderOn', () => {
this.loading = true;
});
this.$root.$on('loaderOff', () => {
this.loading = false;
});
},
data() {
return {
loading: false
};
}
};
/* script */
const __vue_script__$2 = script$2;
/* template */
var __vue_render__$2 = function () {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _vm.loading ? _c('div', {
staticClass: "loader"
}) : _vm._e();
};
var __vue_staticRenderFns__$2 = [];
/* style */
const __vue_inject_styles__$2 = undefined;
/* scoped */
const __vue_scope_id__$2 = undefined;
/* module identifier */
const __vue_module_identifier__$2 = undefined;
/* functional template */
const __vue_is_functional_template__$2 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$2 = /*#__PURE__*/normalizeComponent({
render: __vue_render__$2,
staticRenderFns: __vue_staticRenderFns__$2
}, __vue_inject_styles__$2, __vue_script__$2, __vue_scope_id__$2, __vue_is_functional_template__$2, __vue_module_identifier__$2, false, undefined, undefined, undefined);
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
var script$3 = {
name: 'info-card',
props: {
isPinned: {
type: Boolean
},
error: {
type: String
}
},
methods: {
goToIdentity() {
this.$router.push('/identity');
}
}
};
/* script */
const __vue_script__$3 = script$3;
/* template */
var __vue_render__$3 = function () {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
directives: [{
name: "show",
rawName: "v-show",
value: !_vm.isPinned || _vm.error.length > 0,
expression: "!isPinned || error.length > 0"
}],
staticClass: "card"
}, [_c('header', {
staticClass: "card-header"
}, [_vm.error.length > 0 ? _c('h3', [_vm._v("Problem with camera")]) : !_vm.isPinned ? _c('h3', [_vm._v("Identity Required")]) : _vm._e()]), _vm._v(" "), _c('div', {
staticClass: "card-body"
}, [!_vm.isPinned ? _c('p', [_vm._v("\n To start using the camera you have to setup a new digital identity.\n ")]) : _vm.error.length > 0 ? _c('p', [_vm._v("\n The camera could not be initialized. Please make sure you permit usage\n of your phone camera by setting Camera Permission to state \"Allowed\".\n You can do so by selecting \"Site Settings\" from the browser settings\n menu or by clicking the site security icon located left of the address\n bar.\n ")]) : _vm._e()]), _vm._v(" "), !_vm.isPinned ? _c('footer', {
staticClass: "card-footer"
}, [_c('button', {
staticClass: "btn link",
attrs: {
"type": "button"
},
on: {
"click": _vm.goToIdentity
}
}, [_vm._v("\n Identity Settings\n ")])]) : _vm._e()]);
};
var __vue_staticRenderFns__$3 = [];
/* style */
const __vue_inject_styles__$3 = undefined;
/* scoped */
const __vue_scope_id__$3 = undefined;
/* module identifier */
const __vue_module_identifier__$3 = undefined;
/* functional template */
const __vue_is_functional_template__$3 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$3 = /*#__PURE__*/normalizeComponent({
render: __vue_render__$3,
staticRenderFns: __vue_staticRenderFns__$3
}, __vue_inject_styles__$3, __vue_script__$3, __vue_scope_id__$3, __vue_is_functional_template__$3, __vue_module_identifier__$3, false, undefined, undefined, undefined);
const loggerConfig = {
mode: process.env.VUE_APP_LOGGER_MODE || 'production'
};
function logger() {
if (loggerConfig.mode === 'debug') {
let args = Array.from(arguments);
args.unshift('[DEBUG][' + new Date().toUTCString() + ']' + ': ');
console.log.apply(console, args);
}
}
function saveAppLogs(...data) {
let logs = localStorage.getItem('app-logs');
let date = new Date().toUTCString();
if (logs === null) {
const lastLog = JSON.stringify([{
date: date,
log: data
}], null, 2);
localStorage.setItem('app-logs', lastLog);
return;
}
logs = JSON.parse(logs);
logs.push({
date: date,
log: data.flat(Infinity)
});
logs = JSON.stringify(logs, null, 2);
localStorage.setItem('app-logs', logs);
return;
}
//
var script$4 = {
name: 'input-modal',
props: {
isVisible: {
type: Boolean,
default: false
},
inputLabel: {
type: String,
default: 'Please enter your Passcode'
},
inputType: {
type: String,
default: 'password',
validator: value => ['hidden', 'text', 'password'].indexOf(value) !== -1
},
inputValue: {
type: String
},
pinConfirmValue: {
type: String
},
rememberPin: {
type: Boolean,
default: false
},
checkboxValue: {
type: Boolean,
default: false
},
inputPlaceholder: {
type: String,
default: ''
},
inputPlaceholder2: {
type: String,
default: ''
},
showPinConfirmInput: {
type: Boolean,
default: false
},
modalFormId: {
type: String,
default: ''
}
},
methods: {
updateInput1(value) {
this.$emit('update:inputValue', value);
},
updateInput2(value) {
this.$emit('update:confirmPinCode', value);
},
updateCheckbox(newValue) {
this.$emit('update:checkboxValue', newValue);
}
},
// Watch when modal is active focus on first input
watch: {
isVisible(isActive) {
this.$root.$emit("pinmodal-status", isActive);
if (isActive) {
setTimeout(() => {
const modal = document.querySelector(".modal.input.active");
if (modal.classList.contains("active")) {
modal.querySelector("input").focus();
}
}, 100);
}
}
}
};
/* script */
const __vue_script__$4 = script$4;
/* template */
var __vue_render__$4 = function () {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.isVisible,
expression: "isVisible"
}],
staticClass: "modal input",
class: [_vm.isVisible ? 'active' : ''],
attrs: {
"role": "dialog",
"tabindex": "-1",
"aria-modal": "true"
}
}, [_c('div', {
staticClass: "modal-content"
}, [_c('header', {
staticClass: "modal-header"
}, [_c('h3', [_vm._t("header")], 2)]), _vm._v(" "), _c('div', {
staticClass: "modal-body"
}, [_c('form', {
attrs: {
"id": _vm.modalFormId
},
on: {
"submit": function ($event) {
$event.preventDefault();
}
}
}, [_c('div', {
staticClass: "form-group"
}, [_c('label', {
directives: [{
name: "show",
rawName: "v-show",
value: !!_vm.inputLabel,
expression: "!!inputLabel"
}],
staticClass: "inputLabel"
}, [_vm._v("\n " + _vm._s(_vm.inputLabel) + "\n "), _c('input', {
attrs: {
"type": _vm.inputType,
"placeholder": _vm.inputPlaceholder
},
domProps: {
"value": _vm.inputValue
},
on: {
"input": function ($event) {
return _vm.updateInput1($event.target.value);
}
}
})]), _vm._v(" "), _vm.showPinConfirmInput ? _c('label', {
staticClass: "inputLabel"
}, [_c('input', {
attrs: {
"type": _vm.inputType,
"placeholder": _vm.inputPlaceholder2
},
domProps: {
"value": _vm.pinConfirmValue
},
on: {
"input": function ($event) {
return _vm.updateInput2($event.target.value);
}
}
})]) : _vm._e(), _vm._v(" "), (_vm.inputType === 'password' && _vm.rememberPin === true ? true : false) ? _c('div', {
staticClass: "savePin"
}, [_c('label', {
staticClass: "checkboxLabel"
}, [_vm._v("\n Remember your Passcode\n "), _c('input', {
attrs: {
"type": "checkbox"
},
domProps: {
"value": _vm.checkboxValue
},
on: {
"change": function ($event) {
return _vm.updateCheckbox($event.target.checked);
}
}
})])]) : _vm._e()])])]), _vm._v(" "), _c('footer', {
staticClass: "modal-footer"
}, [_vm._t("footer")], 2)])]);
};
var __vue_staticRenderFns__$4 = [];
/* style */
const __vue_inject_styles__$4 = undefined;
/* scoped */
const __vue_scope_id__$4 = undefined;
/* module identifier */
const __vue_module_identifier__$4 = undefined;
/* functional template */
const __vue_is_functional_template__$4 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$4 = /*#__PURE__*/normalizeComponent({
render: __vue_render__$4,
staticRenderFns: __vue_staticRenderFns__$4
}, __vue_inject_styles__$4, __vue_script__$4, __vue_scope_id__$4, __vue_is_functional_template__$4, __vue_module_identifier__$4, false, undefined, undefined, undefined);
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
var script$5 = {
name: 'confirm-modal',
props: {
isVisible: {
type: Boolean,
default: false
},
isButtonVisible: {
type: Boolean,
default: false
},
title: {
type: String,
default: ''
},
message: {
type: String,
default: ''
},
agreementText: {
type: String,
default: ''
},
resolve: null,
reject: null
},
methods: {
cancelModal() {
this.resolve(false);
this.$emit('update:isVisible', false);
},
confirmModal() {
this.resolve(true);
this.$emit('update:isVisible', false);
}
}
};
/* script */
const __vue_script__$5 = script$5;
/* template */
var __vue_render__$5 = function () {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
directives: [{
name: "show",
rawName: "v-show",
value: _vm.isVisible,
expression: "isVisible"
}],
staticClass: "modal confirm",
attrs: {
"role": "dialog",
"tabindex": "-1",
"aria-modal": "true"
}
}, [_c('div', {
staticClass: "modal-content"
}, [_c('header', {
staticClass: "modal-header"
}, [_c('h3', [_vm._t("header", [_vm._v(_vm._s(_vm.title))])], 2)]), _vm._v(" "), _c('div', {
staticClass: "modal-body"
}, [_vm._t("body", [_c('p', {
directives: [{
name: "show",
rawName: "v-show",
value: !!_vm.message,
expression: "!!message"
}],
domProps: {
"innerHTML": _vm._s(_vm.message)
}
}), _vm._v(" "), _vm.agreementText ? _c('p', {
staticClass: "terms",
domProps: {
"innerHTML": _vm._s(_vm.agreementText)
}
}) : _vm._e()])], 2), _vm._v(" "), _c('footer', {
staticClass: "modal-footer"
}, [_vm._t("footer", [_c('button', {
staticClass: "btn",
attrs: {
"type": "button"
},
on: {
"click": _vm.cancelModal
}
}, [_vm._v("\n " + _vm._s(!_vm.isButtonVisible ? 'Close' : 'Cancel') + "\n ")]), _vm._v(" "), _vm.isButtonVisible ? _c('button', {
staticClass: "btn primary",
attrs: {
"type": "button"
},
on: {
"click": _vm.confirmModal
}
}, [_vm._v("\n Confirm\n ")]) : _vm._e()])], 2)])]);
};
var __vue_staticRenderFns__$5 = [];
/* style */
const __vue_inject_styles__$5 = undefined;
/* scoped */
const __vue_scope_id__$5 = undefined;
/* module identifier */
const __vue_module_identifier__$5 = undefined;
/* functional template */
const __vue_is_functional_template__$5 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$5 = /*#__PURE__*/normalizeComponent({
render: __vue_render__$5,
staticRenderFns: __vue_staticRenderFns__$5
}, __vue_inject_styles__$5, __vue_script__$5, __vue_scope_id__$5, __vue_is_functional_template__$5, __vue_module_identifier__$5, false, undefined, undefined, undefined);
var wallet = null;
var keyPair = null;
let apiUrl = process.env.VUE_APP_API_URL && process.env.VUE_APP_API_URL !== "" ? process.env.VUE_APP_API_URL : "";
let network = process.env.VUE_APP_NETWORK && process.env.VUE_APP_NETWORK !== "" ? process.env.VUE_APP_NETWORK : "ae";
logger(process.env);
const chain = {
setInstance: function (newInstance = "ReCheckAPP") {
e2e.setDefaultRequestId(newInstance);
},
setURLandNetwork: function (apiURL, apiNetwork) {
if (apiURL !== "") {
apiUrl = apiURL;
}
if (apiNetwork !== "") {
network = apiNetwork;
}
const token = localStorage.getItem('lastRtnToken');
if (token) {
return e2e.init(apiUrl, network, token);
}
e2e.init(apiUrl, network);
},
init: async function (password) {
logger('init');
e2e.init(apiUrl, network);
if (!localStorage.walletAe1) {
logger('Wallet does not exist yet. Will create one.');
keyPair = await e2e.newKeyPair(null);
wallet = JSON.stringify(keyPair);
logger('Wallet created with account', keyPair);
this.saveWallet(keyPair, password);
logger('Wallet saved.');
} else {
logger('wallet account exists');
}
return wallet;
},
pinned: function () {
var privateKey = localStorage.walletAe1;
if (typeof privateKey === 'undefined') return false;
logger('pinned: privateKey =', privateKey);
var storedSha3 = localStorage.walletSha3Ae;
logger('pinned: storedSha3 =', storedSha3);
logger('pinned: typeof storedSha3 === undefined =', typeof storedSha3 === 'undefined');
var computedSha3 = e2e.getHash(privateKey);
logger('pinned: computedSha3 =', computedSha3);
logger('pinned: (computedSha3 !== storedSha3) =', computedSha3 !== storedSha3);
if (typeof storedSha3 === 'undefined') return false;
return computedSha3 !== storedSha3;
},
checkPassword: function (password) {
logger('checkPassword password: ', password);
return e2e.getHash(decrypt(password, localStorage.walletAe1)) === localStorage.walletSha3Ae;
},
saveWallet: function (keyPair, password) {
let keyPairStr = JSON.stringify(keyPair);
logger('saveWallet with password', password);
localStorage.walletSha3Ae = e2e.getHash(keyPairStr);
var encrypted = encrypt(password, keyPairStr);
logger('encrypted private key', encrypted);
localStorage.walletAe1 = encrypted; // web3.eth.accounts.wallet.accounts[0].privateKey // encrypt wallet
localStorage.publicAddress = keyPair.address;
this.resetWallet();
},
resetWallet: function () {
wallet = null;
keyPair = null;
},
loadWallet: function (password) {
if (!this.checkPassword(password)) {
return 'authError';
}
var encrypted = localStorage.walletAe1;
if (typeof encrypted === 'undefined') return encrypted;
var account = decrypt(password, encrypted); // decrypt encrypted
this.resetWallet();
logger('loaded private key: ' + encrypted);
logger("decrypted", account);
wallet = account;
keyPair = JSON.parse(account); // TODO: Remove after a time when all users updated their ID's
if (keyPair.address.startsWith("ak_") || keyPair.publicKey.startsWith("ak_")) {
keyPair.address = keyPair.address.replace('ak_', 're_');
keyPair.publicKey = keyPair.publicKey.replace('ak_', 're_');
const keyPairStr = JSON.stringify(keyPair);
wallet = keyPairStr;
let newKeyPairEncrypted = encrypt(password, keyPairStr);
localStorage.walletSha3Ae = e2e.getHash(keyPairStr);
localStorage.walletAe1 = newKeyPairEncrypted;
} else {
localStorage.walletSha3Ae = e2e.getHash(account);
}
localStorage.publicAddress = keyPair.address;
return true;
},
resetPIN(oldPass, newPass) {
if (!this.checkPassword(oldPass)) {
return false;
}
let encrypted = localStorage.walletAe1;
if (typeof encrypted === 'undefined') return encrypted;
let account = decrypt(oldPass, encrypted); // decrypt encrypted
logger('loaded private key: ' + encrypted);
wallet = account;
keyPair = JSON.parse(account);
let keyPairStr = JSON.stringify(keyPair);
logger('saveWallet with password', newPass);
localStorage.walletSha3Ae = e2e.getHash(keyPairStr);
encrypted = encrypt(newPass, keyPairStr);
logger('encrypted private key', encrypted);
localStorage.walletAe1 = encrypted; // web3.eth.accounts.wallet.accounts[0].privateKey // encrypt wallet
localStorage.publicAddress = keyPair.address;
this.resetWallet();
return true;
},
restoreIdentityAtStart: async function (password, phrase) {
this.resetWallet();
keyPair = await e2e.newKeyPair(phrase);
wallet = JSON.stringify(keyPair);
this.saveWallet(keyPair, password);
return true;
},
importPrivateKey: async function (password, phrase) {
if (!this.checkPassword(password)) {
return 'authError';
}
await this.restoreIdentityAtStart(password, phrase);
},
doLogin: async function (password, _challenge, callback) {
logger('doLogin password: ', password);
if (!this.checkPassword(password)) {
callback('authError');
return 'authError';
} else {
this.loadWallet(password);
}
let challenge = _challenge.substring(_challenge.lastIndexOf('/') + 1, _challenge.length);
logger('doLogin challenge: ', challenge);
try {
let firebaseToken = localStorage.getItem("firebaseToken") || 'notoken';
logger("Firebase Device Token", firebaseToken);
let deviceInfo = localStorage.getItem("deviceInfo") || 'unknown';
logger("Login Device Version", deviceInfo);
let token = await e2e.loginWithChallenge(challenge, keyPair, firebaseToken, deviceInfo);
localStorage.lastRtnToken = token;
logger(token);
callback(false);
} catch (error) {
saveAppLogs(error);
console.error(error);
callback(error);
}
this.resetWallet();
return true;
},
doExecSelection: async function (password, _selection, callback) {
logger('pass', password);
if (!this.checkPassword(password)) {
callback('authError');
return 'authError';
} else {
this.loadWallet(password);
}
try {
// let firebaseToken = localStorage.getItem("firebaseToken") || 'notoken';
// logger("Firebase Device Token", firebaseToken);
// let deviceInfo = localStorage.getItem("deviceInfo") || 'unknown';
// logger("Login Device Version", deviceInfo)
// const loginRes = await e2e.login(keyPair, firebaseToken, deviceInfo);
let execResultObj = await e2e.execSelection(_selection, keyPair);
logger(execResultObj);
callback(false);
} catch (error) {
saveAppLogs(error);
console.error(error);
callback(error);
}
this.resetWallet();
return true;
},
getChainLog: function () {
if (localStorage.getItem('app-logs')) {
return localStorage.getItem('app-logs');
}
return false;
},
privateKey: function () {
return wallet;
},
wallet() {
return keyPair;
}
};
function getOrigin(string) {
let url = new URL(string);
if (url.pathname.includes('/chain/')) {
return url.origin + '/chain';
}
return url.origin;
}
function isValidURL(str) {
var pattern = new RegExp('^(https?:\\/\\/)?' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator
return !!pattern.test(str);
}
//
var script$6 = {
name: 'RecheckScanner',
components: {
QrcodeStream,
Card: __vue_component__,
Alert: __vue_component__$1,
Loader: __vue_component__$2,
InfoCard: __vue_component__$3,
InputModal: __vue_component__$4,
ConfirmModal: __vue_component__$5
},
props: {
handledByComponent: {
type: Boolean,
default: true,
required: true
},
useIntegratedCamera: {
type: Boolean,
default: true
},
classes: {
type: String,
default: ''
},
appRequestId: {
type: String,
default: 'ReCheckAPP'
},
isCameraOmitted: {
type: Boolean,
default: false
},
scanLink: {
type: String,
default: ''
},
agreementText: ''
},
data() {
return {
error: '',
pinned: false,
initialized: false,
decodedString: '',
componentHandled: this.handledByComponent,
omitCamera: this.isCameraOmitted,
scanUrl: this.scanLink,
apiEnv: process.env.VUE_APP_API_URL && process.env.VUE_APP_API_URL !== '' ? process.env.VUE_APP_API_URL : '',
apiNetwork: process.env.VUE_APP_NETWORK && process.env.VUE_APP_NETWORK !== '' ? process.env.VUE_APP_NETWORK : 'ae',
publicAddress: '',
automation: false,
showPinModal: false,
pinCase: 'login',
pinCode: '',
isButtonVisible: true,
agreementTexts: this.agreementText,
showConfirmModal: false,
title: '',
message: '',
resolve: null,
reject: null
};
},
mounted() {
this.pinned = chain.pinned();
chain.setInstance(this.appRequestId);
if (this.pinned) {
this.publicAddress = localStorage.publicAddress;
}
if (!this.$router) {
alert("Hey you don't have Vue Router!");
}
if (this.apiEnv !== '' && this.apiNetwork !== '') {
chain.setURLandNetwork(this.apiEnv, this.apiNetwork);
} else {
let savedApiUrl = localStorage.getItem('apiUrl');
if (savedApiUrl && savedApiUrl !== null) {
chain.setURLandNetwork(savedApiUrl, this.apiNetwork);
}
}
if (this.pinned && !this.omitCamera) {
this.setupCamera();
}
if (this.pinned && this.omitCamera && this.scanUrl !== '') {
this.onDecode(this.scanUrl);
setTimeout(() => {
this.setupCamera();
}, 1500);
}
},
methods: {
async onInit(promise) {
this.$root.$emit('loaderOn');
try {
await promise;
this.initialized = true;
} catch (error) {
if (error.name === 'NotAllowedError') {
this.error = 'ERROR: you need to grant camera access permisson';
} else if (error.name === 'NotFoundError') {
this.error = 'ERROR: no camera on this device';
} else if (error.name === 'NotSupportedError') {
this.error = 'ERROR: secure context required (HTTPS, localhost)';
} else if (error.name === 'NotReadableError') {
this.error = 'ERROR: is the camera already in use?';
} else if (error.name === 'OverconstrainedError') {
this.error = 'ERROR: installed cameras are not suitable';
} else if (error.name === 'StreamApiNotSupportedError') {
this.error = 'ERROR: Stream API is not supported in this browser';
}
} finally {
this.$root.$emit('loaderOff');
}
},
onDecode(decodedString) {
this.$emit('is-scanned', true);
this.decodedString = decodedString;
if (decodedString) {
const origin = getOrigin(decodedString);
logger('hasOrigin: ', origin);
if (origin && !origin.includes('verify')) {
localStorage.setItem('apiUrl', origin);
chain.setURLandNetwork(origin, this.apiNetwork);
}
}
if (decodedString.indexOf('/login') > 0) {
this.pinCase = 'login';
if (!this.componentHandled) {
this.$emit('qr-decode', this.pinCase);
} else {
this.handleDecode(this.pinCase, 'Login Request', 'You are about to login. Are you sure?');
}
} else if (decodedString.indexOf('sh:') > 0) {
this.decodedString = decodedString.substring(decodedString.length - 69);
this.pinCase = 'share';
if (!this.componentHandled) {
this.$emit('qr-decode', this.pinCase);
} else {
this.handleDecode(this.pinCase, 'Document Share Request', 'You are about to share a document. Are you sure?');
}
} else if (decodedString.indexOf('se:') > 0) {
this.decodedString = decodedString.substring(decodedString.length - 69);
this.pinCase = 'share';
if (!this.componentHandled) {
this.$emit('qr-decode', this.pinCase);
} else {
this.handleDecode(this.pinCase, 'Document Email Share Request', 'You are about to share a document by email. Are you sure?');
}
} else if (decodedString.indexOf('sg:') > 0) {
this.decodedString = decodedString.substring(decodedString.length - 69);
this.pinCase = 'sign';
if (!this.componentHandled) {
this.$emit('qr-decode', this.pinCase);
} else {
this.handleDecode(this.pinCase, 'File Sign Request', 'You are about to sign a file. Are you sure?');
}
} else if (decodedString.indexOf('re:') > 0) {
this.decodedString = decodedString.substring(decodedString.length - 69);
this.pinCase = 'decrypt';
if (!this.componentHandled) {
this.$emit('qr-decode', this.pinCase);
} else {
this.handleDecode(this.pinCase, 'Document Decrypt Request', 'You are about to decrypt a document. Are you sure?');
}
} else if (decodedString.indexOf('verify') > 0) {
this.isButtonVisible = false;
let verifyMessage = `
Please click the link to verify certificate content. <br />
<a href="${decodedString}" target="_blank" rel="noopener noreferrer">${decodedString.slice(0, 56) + '...'}</a>
`;
this.open('ReCheck Verifier URL', verifyMessage);
} else if (decodedString) {
this.isButtonVisible = false;
let messageContent = isValidURL(decodedString) ? `Unrecognized QR Code content: <br /> <a href="${decodedString}" target="_blank" rel="noopener noreferrer">${decodedString.slice(0, 56) + '...'}</a>` : `Unrecognized QR Code content: <br /> ${decodedString}`;
this.open('Unrecognized QR Code', messageContent);
}
},
doLogin() {
this.$root.$emit('loaderOn');
chain.doLogin(this.pinCode, this.decodedString, err => {
this.$root.$emit('loaderOff');
if (!err) {
this.$root.$emit('alertOn', 'Login data sent successfully.', 'green');
} else {
if (err === 'authError') {
this.$root.$emit('alertOn', 'Passcode mismatch!', 'red');
} else {
this.$root.$emit('alertOn', 'Unable to send login data', 'red');
}
}
this.$emit('scan-result', err);
setTimeout(() => this.setupCamera(), 2000);
});
this.pinCode = '';
this.pinCase = '';
},
doExecSelection() {
this.$root.$emit('loaderOn');
chain.doExecSelection(this.pinCode, this.decodedString, err => {
this.$root.$emit('loaderOff');
if (!err) {
if (this.pinCase === 'sign') {
this.$root.$emit('alertOn', 'Signed data successfully.', 'green');
} else if (this.pinCase === 'share') {
this.$root.$emit('alertOn', 'Shared data successfully.', 'green');
} else if (this.pinCase === 'decrypt') {
this.$root.$emit('alertOn', 'Decrypted data successfully.', 'green');
}
} else {
if (err === 'authError') {
this.$root.$emit('alertOn', 'Passcode mismatch!', 'red');
} else {
if (this.pinCase === 'sign') {
this.$root.$emit('alertOn', 'Failed to sign data.', 'red');
} else if (this.pinCase === 'share') {
this.$root.$emit('alertOn', 'Failed to share data.', 'red');
} else if (this.pinCase === 'decrypt') {
this.$root.$emit('alertOn', 'Failed to decrypt data.', 'red');
}
}
}
this.$emit('scan-result', err);
setTimeout(() => this.setupCamera(), 2000);
});
this.pinCase = '';
this.pinCode = '';
},
open(title, message) {
this.showConfirmModal = true;
this.title = title;
this.message = message;
return new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
},
confirmPin() {
if (this.checkPin(this.pinCode)) {
if (chain.checkPassword(this.pinCode)) {
if (this.pinCase === 'login') {
this.doLogin();
} else if (['share', 'decrypt', 'sign'].includes(this.pinCase)) {
this.doExecSelection();
}
this.showPinModal = false;
} else {
this.$root.$emit('alertOn', 'Passcode is incorrect!', 'red');
this.pinCode = '';
}
} else {
this.$root.$emit('alertOn', 'Passcode is incorrect!', 'red');
this.pinCode = '';
}
this.isButtonVisible = true;
},
cancelPin() {
this.pinCode = '';
this.showPinModal = false;
this.isButtonVisible = true;
setTimeout(() => this.setupCamera(), 300);
},
handleDecode(pinCase, title, message) {
this.open(title, message).then(resolved => {
if (resolved) {
if (chain.pinned()) {
this.showPinModal = true;
} else {
if (pinCase === 'login') {
this.doLogin();
} else {
this.confirmPin();
}
}
} else {
setTimeout(() => this.setupCamera(), 300);
}
}).catch(() => this.$root.$emit('loaderOff'));
},
setupCamera() {
if (!this.useIntegratedCamera && window && window.QRScanner) {
window.QRScanner.show();
window.QRScanner.scan((err, contents) => {
if (err) {
logger('scan error: ', err);
} else {
logger('scan result: ', contents);
this.onDecode(contents);
}
});
}
},
checkPin(pin) {
if (pin === '') {
return false;
} else {
if (pin === undefined) {
return false;
} else {
if (pin.length < 4) {
return false;
} else {
return true;
}
}
}
}
}
};
/* script */
const __vue_script__$6 = script$6;
/* template */
var __vue_render__$6 = function () {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "scanner",
class: _vm.classes
}, [_c('alert'), _vm._v(" "), _c('loader'), _vm._v(" "), _vm.useIntegratedCamera && _vm.pinned && !_vm.error.length > 0 ? _c('div', {
staticClass: "camera"
}, [_c('qrcode-stream', {
on: {
"init": _vm.onInit,
"decode": _vm.onDecode
}
})], 1) : _vm._e(), _vm._v(" "), _c('info-card', {
attrs: {
"isPinned": _vm.pinned,
"error": _vm.error
}
}), _vm._v(" "), _c('confirm-modal', {
attrs: {
"isVisible": _vm.showConfirmModal,
"title": _vm.title,
"message": _vm.message,
"resolve": _vm.resolve,
"reject": _vm.reject,
"isButtonVisible": _vm.isButtonVisible,
"agreementText": _vm.agreementTexts
},
on: {
"update:isVisible": function ($event) {
_vm.showConfirmModal = $event;
},
"update:is-visible": function ($event) {
_vm.showConfirmModal = $event;
}
}
}), _vm._v(" "), _c('input-modal', {
attrs: {
"isVisible": _vm.showPinModal,
"rememberPin": false,
"modalFormId": "pinModalForm",
"inputValue": _vm.pinCode,
"checkboxValue": _vm.automation
},
on: {
"update:inputValue": function ($event) {
_vm.pinCode = $event;
},
"update:input-value": function ($event) {
_vm.pinCode = $event;
},
"update:checkboxValue": function ($event) {
_vm.automation = $event;
},
"update:checkbox-value": function ($event) {
_vm.automation = $event;
}
},
scopedSlots: _vm._u([{
key: "header",
fn: function () {
return [_vm._v("\n Passcode\n "), _c('span', [_vm._v("\n " + _vm._s(_vm.publicAddress !== '' ? 'for ' + _vm.publicAddress.replace(_vm.publicAddress.substring(7, _vm.publicAddress.length - 4), '...') : '') + "\n ")])];
},
proxy: true
}, {
key: "footer",
fn: function () {
return [_c('button', {
staticClass: "btn",
attrs: {
"type": "button"
},
on: {
"click": _vm.cancelPin
}
}, [_vm._v("Cancel")]), _vm._v(" "), _c('button', {
staticClass: "btn",
attrs: {
"type": "submit",
"form": "pinModalForm"
},
on: {
"click": _vm.confirmPin,
"keyup": function ($event) {
if (!$event.type.indexOf('key') && _vm._k($event.keyCode, "enter", 13, $event.key, "Enter")) {
return null;
}
return _vm.confirmPin($event);
}
}
}, [_vm._v("\n Confirm\n ")])];
},
proxy: true
}])
})], 1);
};
var __vue_staticRenderFns__$6 = [];
/* style */
const __vue_inject_styles__$6 = undefined;
/* scoped */
const __vue_scope_id__$6 = undefined;
/* module identifier */
const __vue_module_identifier__$6 = undefined;
/* functional template */
const __vue_is_functional_template__$6 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$6 = /*#__PURE__*/normalizeComponent({
render: __vue_render__$6,
staticRenderFns: __vue_staticRenderFns__$6
}, __vue_inject_styles__$6, __vue_script__$6, __vue_scope_id__$6, __vue_is_functional_template__$6, __vue_module_identifier__$6, false, undefined, undefined, undefined);
var script$7 = {
methods: {
copyToClipboard() {
const valueToCopy = document.querySelector('#mnemonicKey');
const range = document.createRange();
range.selectNode(valueToCopy);
window.getSelection().addRange(range);
try {
const successful = document.execCommand('copy');
if (successful) {
this.$root.$emit('alertOn', 'Recovery phrase copied to clipboard.', 'green');
} else {
this.$root.$emit('alertOn', 'Could not copy to clipboard!', 'red');
}
} catch (err) {
this.$root.$emit('alertOn', 'Could not copy to clipboard!', 'red');
}
window.getSelection().removeAllRanges();
},
copyStringToClipboard(str) {
// Create new element
let el = document.createElement('textarea'); // Set value (string to be copied)
el.value = str; // Set non-editable to avoid focus and move outside of view
el.setAttribute('readonly', '');
el.style = {
position: 'absolute',
left: '-9999px'
};
document.body.appendChild(el); // Select text inside element
el.select(); // Copy text to clipboard
try {
var successful = document.execCommand('copy');
if (successful) {
this.$root.$emit('alertOn', 'Address copied to clipboard.', 'green');
} else {
this.$root.$emit('alertOn', 'Could not copy to clipboard!', 'red');
}
} catch (err) {
this.$root.$emit('alertOn', 'Could not copy to clipboard!', 'red');
} // Remove temporary element
document.body.removeChild(el);
}
}
};
/* script */
const __vue_script__$7 = script$7;
/* template */
/* style */
const __vue_inject_styles__$7 = undefined;
/* scoped */
const __vue_scope_id__$7 = undefined;
/* module identifier */
const __vue_module_identifier__$7 = undefined;
/* functional template */
const __vue_is_functional_template__$7 = undefined;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$7 = /*#__PURE__*/normalizeComponent({}, __vue_inject_styles__$7, __vue_script__$7, __vue_scope_id__$7, __vue_is_functional_template__$7, __vue_module_identifier__$7, false, undefined, undefined, undefined);
//
var script$8 = {
name: 'RecheckIdentity',
mixins: [__vue_component__$7],
components: {
Card: __vue_component__,
Alert: __vue_component__$1,
Loader: __vue_component__$2,
InputModal: __vue_component__$4,
ConfirmModal: __vue_component__$5
},
props: {
classes: {
type: String,
default: ''
},
appName: {
type: String,
default: 'ReCheck'
},
mobileBackup: {
type: Boolean,
default: false
}
},
data() {
return {
pinned: false,
privateKey: '',
publicAddress: '',
inputMessage: '',
pinMessage: '',
pin: '',
pin1: '',
check: false,
pinDialog: 0,
automation: false,
importDialog: false,
showPinDialog: false,
privateKeyDialog: false,
showPinConfirmInput: false,
pinMessage2: 'Please repeat your Passcode',
isButtonVisible: false,
showConfirmModal: false,
title: '',
message: '',
resolve: null,
reject: null,
apiNetwork: process.env.VUE_APP_NETWORK && process.env.VUE_APP_NETWORK !== '' ? process.env.VUE_APP_NETWORK : 'ae',
backupDone: false,
backupMode: false
};
},
mounted() {
this.pinned = chain.pinned();
this.$root.$on('walletEvent', () => {
this.publicAddress = localStorage.publicAddress;
});
if (this.pinned) {
this.publicAddress = localStorage.publicAddress;
}
if (!this.$store) {
alert('Hey you need Vuex in order to use this component!');
}
this.backupDone = localStorage.getItem('backupDone') ? JSON.parse(localStorage.getItem('backupDone')) : false;
},
methods: {
seedCheck(seedPhrase) {
if (seedPhrase.split(' ').length == 12) {
return true;
} else {
return false;
}
},
checkPin(pin) {
if (pin === '') {
return false;
} else {
if (pin === undefined) {
return false;
} else {
if (pin.length < 3) {
return false;
} else {
return true;
}
}
}
},
resetIdentity() {
this.isButtonVisible = true;
this.open('Reset Identity', 'Are you really sure you want to reset your Identity?').then(resolved => {
if (resolved) {
this.open('Reset Identity', 'Are you really sure you want to reset your identity? You will lose the current one FOREVER!').then(resolved => {
if (resolved) {
localStorage.clear();
location.reload();
} else {
this.showConfirmModal = false;
this.isButtonVisible = false;
}
});
} else {
this.showConfirmModal = false;
this.isButtonVisible = false;
}
});
},
createIdentity() {
this.pin = '';
this.pin1 = '';
this.pinDialog = 2;
this.showPinConfirmInput = true;
this.pinMessage = 'Please choose a new Passcode';
this.showPinDialog = true;
this.setBackupStatus(false);
},
backupIdentity() {
if (chain.pinned() && !this.$store.state.automatedPIN) {
this.pin = '';
this.pinDialog = 1;
this.showPinDialog = true;
this.pinMessage = 'Please enter your Passcode';
} else {
if (chain.loadWallet(this.returnRememberedPIN) !== 'authError') {
this.privateKey = chain.wallet().phrase;
this.privateKeyDialog = true;
}
}
},
showPrivateKey() {
if (chain.pinned() && this.backupDone) {
this.pin = '';
this.pinDialog = 4;
this.showPinDialog = true;
this.pinMessage = 'Please enter your Passcode';
}
},
sharePrivateKey() {
if (chain.pinned() && this.backupDone) {
this.pin = '';
this.pinDialog = 5;
this.showPinDialog = true;
this.pinMessage = 'Please enter your Passcode';
}
},
restoreIdentityAtStart() {
this.check = false;
this.pin = '';
this.pin1 = '';
this.showPinConfirmInput = true;
this.pinMessage = 'Please choose a new Passcode';
this.inputMessage = 'Recovery phrase';
this.pinDialog = 3;
this.showPinDialog = true;
},
async doRestoreIdentity() {
if (this.seedCheck(this.privateKey)) {
this.privateKey = this.privateKey.toLowerCase();
if (!chain.pinned()) {
logger('new privateKey', this.privateKey);
this.$root.$emit('loaderOn');
try {
await chain.restoreIdentityAtStart(this.pin, this.privateKey);
this.$root.$emit('loaderOff');
this.$root.$emit('walletEvent');
this.$root.$emit('alertOn', 'Identity recovered successfully!', 'green');
this.setBackupStatus(true);
this.importDialog = false;
location.reload();
} catch (error) {
this.$root.$emit('loaderOff');
this.$root.$emit('alertOn', 'Wrong recovery phrase. Please try again.', 'red', 3500);
this.setBackupStatus(false);
this.importDialog = false;
}
this.privateKey = '';
}
} else {
this.$root.$emit('alertOn', 'The secret phrase have to be 12 words.', 'red');
}
},
async confirmPin() {
let isValidPasswords;
if (this.pinDialog === 2 || this.pinDialog === 3) {
isValidPasswords = this.validPasswords(this.pin, this.pin1, 6);
} else if (this.pinDialog !== 2 || this.pinDialog !== 3) {
isValidPasswords = this.validPasswords(this.pin);
}
if (isValidPasswords) {
if (this.pinDialog === 1) {
// Backup
if (chain.loadWallet(this.pin) !== 'authError') {
this.privateKey = chain.wallet().phrase;
if (this.mobileBackup) {
this.backupMode = true;
this.$root.$emit('backupMode', {
privateKey: this.privateKey,
backupMode: this.backupMode
});
} else {
this.privateKeyDialog = true;
this.pinAutomation(this.returnAutomation, this.pin);
this.setBackupStatus(true);
const card = document.querySelector('.card');
if (this.backupDone === true && card.classList.contains('do-backup')) {
card.classList.remove('do-backup');
}
}
} else {
this.$root.$emit('alertOn', 'Passcode mismatch.', 'red');
}
this.pin = '';
this.pin1 = '';
this.pinDialog = 0;
this.showPinConfirmInput = false;
this.showPinDialog = false;
} else if (this.pinDialog === 2) {
// New identity pin
if (!this.validPasswords(this.pin, this.pin1, 6)) {
this.pin = '';
this.pin1 = '';
} else {
if (this.pin === this.pin1) {
this.check = true;
this.showPinDialog = false;
this.$root.$emit('loaderOn');
await chain.init(this.pin);
this.pinned = chain.pinned();
this.pinAutomation(this.returnAutomation, this.pin);
this.$root.$emit('walletEvent');
this.$root.$emit('loaderOff');
if (!localStorage.getItem('backupDone')) {
this.setBackupStatus(false);
} else {
this.backupDone = JSON.parse(localStorage.getItem('backupDone'));
}