Modal additions incl. QR fixup and Seed View

pull/714/head
Vincent 5 years ago
parent 2caffa9289
commit 2ede557a74

@ -2102,16 +2102,26 @@
}, },
"showSeed": { "showSeed": {
"message": "Show seed", "message": "Show Seed",
"description": "description":
"Button action that the user can click to view their unique seed" "Button action that the user can click to view their unique seed"
}, },
"showSeedPasswordRequest": {
"message": "Please enter your password",
"description": "Request for user to enter password to show seed."
},
"seedSavePrompt": {
"message":
"Please save the seed below in a safe location. They can be used to restore your account if you lose access or migrate to a new device.",
"description": "Prompt on seed modal requesting user to save their seed"
},
"QRCodeTitle": { "QRCodeTitle": {
"message": "Your Public Key QRCode", "message": "Your Public Key QRCode",
"description": "Title given to QRCode modal" "description": "Title given to QRCode modal"
}, },
"QRCodeDescription": { "QRCodeDescription": {
"message": "Your friends can scan this QR code to start a conversation with you.", "message":
"Your friends can scan this QR code to start a conversation with you.",
"description": "Description given to QRCode modal" "description": "Description given to QRCode modal"
}, },
"showQRCode": { "showQRCode": {
@ -2168,7 +2178,10 @@
"description": "description":
"A button action that the user can click to reset the database" "A button action that the user can click to reset the database"
}, },
"password": {
"message": "Password",
"description": "Placeholder for password input"
},
"setPassword": { "setPassword": {
"message": "Set Password", "message": "Set Password",
"description": "Button action that the user can click to set a password" "description": "Button action that the user can click to set a password"
@ -2190,6 +2203,9 @@
"invalidPassword": { "invalidPassword": {
"message": "Invalid password" "message": "Invalid password"
}, },
"noGivenPassword": {
"message": "Please enter your password"
},
"passwordsDoNotMatch": { "passwordsDoNotMatch": {
"message": "Passwords do not match" "message": "Passwords do not match"
}, },

@ -61,7 +61,12 @@ const {
const { SessionToast } = require('../../ts/components/session/SessionToast'); const { SessionToast } = require('../../ts/components/session/SessionToast');
const { SessionToggle } = require('../../ts/components/session/SessionToggle'); const { SessionToggle } = require('../../ts/components/session/SessionToggle');
const { SessionModal } = require('../../ts/components/session/SessionModal'); const { SessionModal } = require('../../ts/components/session/SessionModal');
const { SessionQRModal } = require('../../ts/components/session/SessionQRModal'); const {
SessionQRModal,
} = require('../../ts/components/session/SessionQRModal');
const {
SessionSeedModal,
} = require('../../ts/components/session/SessionSeedModal');
const { const {
SessionConfirm, SessionConfirm,
} = require('../../ts/components/session/SessionConfirm'); } = require('../../ts/components/session/SessionConfirm');
@ -275,6 +280,7 @@ exports.setup = (options = {}) => {
SessionConfirm, SessionConfirm,
SessionModal, SessionModal,
SessionQRModal, SessionQRModal,
SessionSeedModal,
SessionDropdown, SessionDropdown,
MediaGallery, MediaGallery,
Message, Message,

@ -11,16 +11,17 @@
initialize(options) { initialize(options) {
this.value = options.value || ''; this.value = options.value || '';
this.close = this.close.bind(this); this.close = this.close.bind(this);
this.onKeyup = this.onKeyup.bind(this);
this.render(); this.render();
}, },
render() { render() {
this.dialogView = new Whisper.ReactWrapperView({ this.dialogView = new Whisper.ReactWrapperView({
className: 'qr-dialog', className: 'qr-dialog-wrapper',
Component: window.Signal.Components.SessionQRModal, Component: window.Signal.Components.SessionQRModal,
props: { props: {
value: this.value, value: this.value,
onClose: this.close,
}, },
}); });
@ -31,16 +32,5 @@
close() { close() {
this.remove(); this.remove();
}, },
onKeyup(event) {
switch (event.key) {
case 'Enter':
case 'Escape':
case 'Esc':
this.close();
break;
default:
break;
}
},
}); });
})(); })();

@ -1,4 +1,4 @@
/* global Whisper, i18n, Signal, passwordUtil */ /* global Whisper */
// eslint-disable-next-line func-names // eslint-disable-next-line func-names
(function() { (function() {
@ -8,90 +8,26 @@
Whisper.SeedDialogView = Whisper.View.extend({ Whisper.SeedDialogView = Whisper.View.extend({
className: 'loki-dialog seed-dialog modal', className: 'loki-dialog seed-dialog modal',
templateName: 'seed-dialog', initialize() {
initialize(options = {}) { this.close = this.close.bind(this);
this.okText = options.okText || i18n('ok');
this.cancelText = options.cancelText || i18n('cancel');
this.confirmText = options.confirmText || i18n('confirm');
this.copyText = options.copyText || i18n('copySeed');
this.seed = options.seed || '-';
this.render(); this.render();
this.showSeedView(false);
this.initPasswordHash();
this.$('#password').bind('keyup', event => this.onKeyup(event));
},
events: {
'click .ok': 'close',
'click .confirm': 'confirmPassword',
'click .copy-seed': 'copySeed',
},
render_attributes() {
return {
passwordViewTitle: i18n('passwordViewTitle'),
seedViewTitle: i18n('seedViewTitle'),
ok: this.okText,
copyText: this.copyText,
confirm: this.confirmText,
cancel: this.cancelText,
};
},
async initPasswordHash() {
const hash = await Signal.Data.getPasswordHash();
this.passwordHash = hash;
this.showSeedView(!hash);
},
showSeedView(show) {
const seedView = this.$('.seedView');
const passwordView = this.$('.passwordView');
if (show) {
this.$('.seed').html(this.seed);
seedView.show();
passwordView.hide();
} else {
this.$('.seed').html('');
passwordView.show();
this.$('#password').focus();
seedView.hide();
}
}, },
confirmPassword() {
this.$('.error').html();
const password = this.$('#password').val();
if (
this.passwordHash &&
!passwordUtil.matchesHash(password, this.passwordHash)
) {
this.$('.error').html(`Error: ${i18n('invalidPassword')}`);
return;
}
this.showSeedView(true); render() {
this.dialogView = new Whisper.ReactWrapperView({
className: 'seed-dialog-wrapper',
Component: window.Signal.Components.SessionSeedModal,
props: {
onClose: this.close,
},
});
this.$el.append(this.dialogView.el);
return this;
}, },
close() { close() {
this.remove(); this.remove();
}, },
copySeed() {
window.clipboard.writeText(this.seed);
window.pushToast({
title: i18n('copiedMnemonic'),
type: 'success',
id: 'copySeedToast',
});
},
onKeyup(event) {
switch (event.key) {
case 'Enter':
this.confirmPassword();
break;
case 'Escape':
case 'Esc':
this.close();
break;
default:
break;
}
},
}); });
})(); })();

@ -1,32 +0,0 @@
/* global Whisper */
// eslint-disable-next-line func-names
(function() {
'use strict';
window.Whisper = window.Whisper || {};
Whisper.SessionDropdownView = Whisper.View.extend({
initialize(options) {
this.props = {
items: options.items,
};
this.render();
},
render() {
this.dropdownView = new Whisper.ReactWrapperView({
className: 'session-dropdown-wrapper',
Component: window.Signal.Components.SessionDropdown,
props: this.props,
});
this.$el.append(this.dropdownView.el);
},
openDropdown() {},
closeDropdown() {},
});
})();

@ -101,7 +101,6 @@
"pify": "3.0.0", "pify": "3.0.0",
"protobufjs": "6.8.6", "protobufjs": "6.8.6",
"proxy-agent": "3.0.3", "proxy-agent": "3.0.3",
"qrcode": "^1.4.4",
"react": "16.8.3", "react": "16.8.3",
"react-contextmenu": "2.11.0", "react-contextmenu": "2.11.0",
"react-dom": "16.8.3", "react-dom": "16.8.3",

@ -105,6 +105,13 @@ div.spacer-lg {
text-align: center; text-align: center;
} }
@mixin text-highlight($color) {
background-color: rgba($color, 0.8);
padding: $session-margin-xs;
border-radius: 3px;
display: inline-block;
}
.fullwidth { .fullwidth {
width: 100%; width: 100%;
} }
@ -115,7 +122,9 @@ $session-icon-size-sm: 15px;
$session-icon-size-md: 20px; $session-icon-size-md: 20px;
$session-icon-size-lg: 30px; $session-icon-size-lg: 30px;
$session-modal-size: 220px; $session-modal-size-sm: 220px;
$session-modal-size-md: 400px;
$session-modal-size-lg: 650px;
$session-conversation-header-height: 60px; $session-conversation-header-height: 60px;
@ -470,7 +479,7 @@ label {
right: $session-margin-lg; right: $session-margin-lg;
bottom: $session-margin-lg; bottom: $session-margin-lg;
z-index: 100; z-index: 10000;
} }
.session-toast { .session-toast {
@ -552,6 +561,7 @@ label {
left: 50%; left: 50%;
top: 50%; top: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
min-width: 300px;
box-sizing: border-box; box-sizing: border-box;
max-height: 70vh; max-height: 70vh;
@ -622,6 +632,10 @@ label {
margin: 0 $session-margin-xs; margin: 0 $session-margin-xs;
} }
} }
&__text-highlight {
@include text-highlight($session-shade-15);
}
} }
.session-toggle { .session-toggle {
@ -803,16 +817,22 @@ label {
} }
#qr svg { #qr svg {
width: $session-modal-size; width: $session-modal-size-sm;
height: $session-modal-size; height: $session-modal-size-sm;
border: 6px solid white; border: 6px solid white;
border-radius: 3px; border-radius: 3px;
} }
.qr-dialog { .qr-dialog {
&__description { &__description {
max-width: $session-modal-size; max-width: $session-modal-size-sm;
text-align: center; text-align: center;
margin: 0 auto; margin: 0 auto;
} }
} }
.seed-dialog {
&__description {
max-width: $session-modal-size-lg;
}
}

@ -49,7 +49,7 @@ export class DevicePairingDialog extends React.Component<Props, State> {
}; };
} }
componentDidMount() { public componentDidMount() {
this.getSecondaryDevices(); this.getSecondaryDevices();
} }
@ -98,7 +98,7 @@ export class DevicePairingDialog extends React.Component<Props, State> {
value={window.textsecure.storage.user.getNumber()} value={window.textsecure.storage.user.getNumber()}
bgColor="#FFFFFF" bgColor="#FFFFFF"
fgColor="#000000" fgColor="#000000"
level="L" level="L"
/> />
</div> </div>
@ -207,58 +207,58 @@ export class DevicePairingDialog extends React.Component<Props, State> {
this.showView(); this.showView();
} }
private requestReceived(secondaryDevicePubKey: string | EventHandlerNonNull) { // private requestReceived(secondaryDevicePubKey: string | EventHandlerNonNull) {
// FIFO: push at the front of the array with unshift() // // FIFO: push at the front of the array with unshift()
this.state.pubKeyRequests.unshift(secondaryDevicePubKey); // this.state.pubKeyRequests.unshift(secondaryDevicePubKey);
if (!this.state.currentPubKey) { // if (!this.state.currentPubKey) {
this.nextPubKey(); // this.nextPubKey();
this.showView('requestReceived'); // this.showView('requestReceived');
} // }
} // }
private allowDevice() { // private allowDevice() {
this.setState({ // this.setState({
accepted: true, // accepted: true,
}); // });
window.Whisper.trigger( // window.Whisper.trigger(
'devicePairingRequestAccepted', // 'devicePairingRequestAccepted',
this.state.currentPubKey, // this.state.currentPubKey,
(errors: any) => { // (errors: any) => {
this.transmisssionCB(errors); // this.transmisssionCB(errors);
return true; // return true;
} // }
); // );
this.showView(); // this.showView();
} // }
private transmisssionCB(errors: any) { // private transmisssionCB(errors: any) {
if (!errors) { // if (!errors) {
this.setState({ // this.setState({
success: true, // success: true,
}); // });
} else { // } else {
return; // return;
} // }
} // }
private skipDevice() { // private skipDevice() {
window.Whisper.trigger( // window.Whisper.trigger(
'devicePairingRequestRejected', // 'devicePairingRequestRejected',
this.state.currentPubKey // this.state.currentPubKey
); // );
this.nextPubKey(); // this.nextPubKey();
this.showView(); // this.showView();
} // }
private nextPubKey() { // private nextPubKey() {
// FIFO: pop at the back of the array using pop() // // FIFO: pop at the back of the array using pop()
const pubKeyRequests = this.state.pubKeyRequests; // const pubKeyRequests = this.state.pubKeyRequests;
this.setState({ // this.setState({
currentPubKey: pubKeyRequests.pop(), // currentPubKey: pubKeyRequests.pop(),
}); // });
} // }
private onKeyUp(event: any) { private onKeyUp(event: any) {
switch (event.key) { switch (event.key) {

@ -3,12 +3,7 @@ import React from 'react';
import { ContactName } from './ContactName'; import { ContactName } from './ContactName';
import { Avatar } from '../Avatar'; import { Avatar } from '../Avatar';
import { Colors, LocalizerType } from '../../types/Util'; import { Colors, LocalizerType } from '../../types/Util';
import { import { ContextMenu, MenuItem, SubMenu } from 'react-contextmenu';
ContextMenu,
ContextMenuTrigger,
MenuItem,
SubMenu,
} from 'react-contextmenu';
import { import {
SessionIconButton, SessionIconButton,
@ -22,8 +17,6 @@ import {
SessionButtonType, SessionButtonType,
} from '../session/SessionButton'; } from '../session/SessionButton';
import { SessionDropdownTrigger } from '../session/SessionDropdownTrigger';
interface TimerOption { interface TimerOption {
name: string; name: string;
value: number; value: number;
@ -239,7 +232,7 @@ export class ConversationHeader extends React.Component<Props> {
); );
} }
public renderOptions(triggerId: string) { public renderOptions() {
const { showBackButton } = this.props; const { showBackButton } = this.props;
if (showBackButton) { if (showBackButton) {
@ -247,12 +240,12 @@ export class ConversationHeader extends React.Component<Props> {
} }
return ( return (
<SessionDropdownTrigger> <>
<SessionIconButton <SessionIconButton
iconType={SessionIconType.Ellipses} iconType={SessionIconType.Ellipses}
iconSize={SessionIconSize.Large} iconSize={SessionIconSize.Large}
/> />
</SessionDropdownTrigger> </>
); );
} }

@ -84,7 +84,10 @@ export class SessionModal extends React.PureComponent<Props, State> {
}); });
window.removeEventListener('keyup', this.onKeyUp); window.removeEventListener('keyup', this.onKeyUp);
this.props.onClose();
if (this.props.onClose) {
this.props.onClose();
}
} }
public onKeyUp(event: any) { public onKeyUp(event: any) {

@ -2,9 +2,11 @@ import React from 'react';
import { QRCode } from 'react-qr-svg'; import { QRCode } from 'react-qr-svg';
import { SessionModal } from './SessionModal'; import { SessionModal } from './SessionModal';
import { SessionButton } from './SessionButton';
interface Props { interface Props {
value: string; value: string;
onClose: any;
} }
export class SessionQRModal extends React.Component<Props> { export class SessionQRModal extends React.Component<Props> {
@ -13,37 +15,30 @@ export class SessionQRModal extends React.Component<Props> {
} }
public render() { public render() {
const { value } = this.props; const { value, onClose } = this.props;
console.log('skbsvbsgb');
console.log('skbsvbsgb');
console.log('skbsvbsgb');
return ( return (
<SessionModal <SessionModal
title={window.i18n('QRCodeTitle')} title={window.i18n('QRCodeTitle')}
onOk={() => null} onOk={() => null}
onClose={() => null} onClose={onClose}
> >
<div className="spacer-sm"></div> <div className="spacer-sm" />
<div className='qr-dialog__description text-subtle'> <div className="qr-dialog__description text-subtle">
<p> <p>{window.i18n('QRCodeDescription')}</p>
{window.i18n('QRCodeDescription')}
</p>
</div> </div>
<div className="spacer-lg"></div> <div className="spacer-lg" />
<div id="qr"> <div id="qr">
<QRCode <QRCode value={value} bgColor="#FFFFFF" fgColor="#000000" level="L" />
value={value} </div>
bgColor="#FFFFFF"
fgColor="#000000" <div className="spacer-lg" />
level="L" <div className="session-modal__button-group">
/> <SessionButton text={window.i18n('close')} onClick={onClose} />
</div> </div>
</SessionModal> </SessionModal>
); );
} }
} }

@ -0,0 +1,198 @@
import React from 'react';
import { SessionModal } from './SessionModal';
import { SessionButton } from './SessionButton';
interface Props {
onClose: any;
}
interface State {
error: string;
loadingPassword: boolean;
loadingSeed: boolean;
seed: string;
hasPassword: boolean | null;
passwordHash: string;
passwordValid: boolean;
}
export class SessionSeedModal extends React.Component<Props, State> {
constructor(props: any) {
super(props);
this.state = {
error: '',
loadingPassword: true,
loadingSeed: true,
seed: '',
hasPassword: null,
passwordHash: '',
passwordValid: false,
};
this.copySeed = this.copySeed.bind(this);
this.getSeed = this.getSeed.bind(this);
this.confirmPassword = this.confirmPassword.bind(this);
this.checkHasPassword = this.checkHasPassword.bind(this);
}
public render() {
const i18n = window.i18n;
const { onClose } = this.props;
const maxPasswordLen = 64;
this.checkHasPassword();
this.getSeed();
const error = this.state.error;
const hasPassword = this.state.hasPassword;
const passwordValid = this.state.passwordValid;
const loading = this.state.loadingPassword || this.state.loadingSeed;
return (
<SessionModal
title={i18n('showSeed')}
onOk={() => null}
onClose={onClose}
>
{!loading && (
<>
<div className="spacer-sm" />
{hasPassword && !passwordValid ? (
<div>
<p>{i18n('showSeedPasswordRequest')}</p>
<input
type="password"
id="seed-input-password"
placeholder={i18n('password')}
maxLength={maxPasswordLen}
/>
{error && (
<>
<div className="spacer-xs" />
<div className="session-label danger">{error}</div>
</>
)}
<div className="spacer-lg" />
<div className="session-modal__button-group">
<SessionButton
text={i18n('confirm')}
onClick={this.confirmPassword}
/>
<SessionButton text={i18n('cancel')} onClick={onClose} />
</div>
</div>
) : (
<>
<div className="session-modal__centered text-center">
<p className="session-modal__description">
{i18n('seedSavePrompt')}
</p>
<div className="spacer-md" />
<i className="session-modal__text-highlight">
{this.state.seed}
</i>
</div>
<div className="spacer-lg" />
<div className="session-modal__button-group">
<SessionButton text={i18n('ok')} onClick={onClose} />
<SessionButton
text={i18n('copySeed')}
onClick={() => {
this.copySeed(this.state.seed);
}}
/>
</div>
</>
)}
</>
)}
</SessionModal>
);
}
private confirmPassword() {
const passwordHash = this.state.passwordHash;
const passwordValue = $('#seed-input-password').val();
const isPasswordValid = window.passwordUtil.matchesHash(
passwordValue,
passwordHash
);
if (!passwordValue) {
this.setState({
error: window.i18n('noGivenPassword'),
});
return false;
}
if (passwordHash && !isPasswordValid) {
this.setState({
error: window.i18n('invalidPassword'),
});
return false;
}
this.setState({
passwordValid: true,
error: '',
});
return true;
}
private checkHasPassword() {
if (!this.state.loadingPassword) {
return;
}
const hashPromise = window.Signal.Data.getPasswordHash();
hashPromise.then((hash: any) => {
this.setState({
hasPassword: !!hash,
passwordHash: hash,
loadingPassword: false,
});
});
}
private async getSeed() {
if (this.state.seed) {
return this.state.seed;
}
const manager = await window.getAccountManager();
const seed = manager.getCurrentMnemonic();
this.setState({
seed,
loadingSeed: false,
});
return seed;
}
private copySeed(seed: string) {
window.clipboard.writeText(seed);
window.pushToast({
title: window.i18n('copiedMnemonic'),
type: 'success',
id: 'copySeedToast',
});
}
}

1
ts/global.d.ts vendored

@ -1,6 +1,7 @@
interface Window { interface Window {
getAccountManager: any; getAccountManager: any;
mnemonic: any; mnemonic: any;
clipboard: any;
passwordUtil: any; passwordUtil: any;
dcodeIO: any; dcodeIO: any;
libsignal: any; libsignal: any;

@ -139,9 +139,9 @@
integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ== integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==
"@types/dompurify@^2.0.0": "@types/dompurify@^2.0.0":
version "2.0.1" version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.0.1.tgz#0bf3a9f8ee21d81adb20b8c374ab034d6a74dbf7" resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.0.0.tgz#9616caa5bf2569aea2e4889d4f929d968c081b40"
integrity sha512-OQ16dECrRv/I//woKkVUxyVGYR94W3qp3Wy//B63awHVe3h/1/URFqP5a/V2m4k01DEvWs1+z7FWW3xfM1lH3Q== integrity sha512-g/ilp+Bo6Ljy60i5LnjkGw00X7EIoFjoPGlxqZhV8TJ9fWEzXheioU1O+U/UzCzUA7pUDy/JNMytTQDJctpUHg==
dependencies: dependencies:
"@types/trusted-types" "*" "@types/trusted-types" "*"
@ -1243,19 +1243,6 @@ buble@^0.19.3:
os-homedir "^1.0.1" os-homedir "^1.0.1"
vlq "^1.0.0" vlq "^1.0.0"
buffer-alloc-unsafe@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
buffer-alloc@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
dependencies:
buffer-alloc-unsafe "^1.1.0"
buffer-fill "^1.0.0"
buffer-crc32@0.2.13, buffer-crc32@^0.2.1: buffer-crc32@0.2.13, buffer-crc32@^0.2.1:
version "0.2.13" version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@ -1265,20 +1252,10 @@ buffer-equal@0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b"
buffer-fill@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
buffer-from@^1.0.0: buffer-from@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531"
buffer-from@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
buffer-indexof@^1.0.0: buffer-indexof@^1.0.0:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
@ -1295,14 +1272,6 @@ buffer@^4.3.0:
ieee754 "^1.1.4" ieee754 "^1.1.4"
isarray "^1.0.0" isarray "^1.0.0"
buffer@^5.4.3:
version "5.4.3"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115"
integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==
dependencies:
base64-js "^1.0.2"
ieee754 "^1.1.4"
buffers@~0.1.1: buffers@~0.1.1:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb"
@ -2553,11 +2522,6 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0" miller-rabin "^4.0.0"
randombytes "^2.0.0" randombytes "^2.0.0"
dijkstrajs@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.1.tgz#d3cd81221e3ea40742cfcde556d4e99e98ddc71b"
integrity sha1-082BIh4+pAdCz83lVtTpnpjdxxs=
dir-glob@^2.0.0: dir-glob@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034"
@ -5018,11 +4982,6 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isarray@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
isbinaryfile@^4.0.2: isbinaryfile@^4.0.2:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.2.tgz#bfc45642da645681c610cca831022e30af426488" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.2.tgz#bfc45642da645681c610cca831022e30af426488"
@ -7022,11 +6981,6 @@ pngjs@^3.0.0:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.0.1.tgz#b15086ac1ac47298c8fd3f9cdf364fa9879c4db6" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.0.1.tgz#b15086ac1ac47298c8fd3f9cdf364fa9879c4db6"
pngjs@^3.3.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
portfinder@^1.0.9: portfinder@^1.0.9:
version "1.0.13" version "1.0.13"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
@ -7525,19 +7479,6 @@ qr.js@0.0.0:
resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f" resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
integrity sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8= integrity sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=
qrcode@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.4.tgz#f0c43568a7e7510a55efc3b88d9602f71963ea83"
integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==
dependencies:
buffer "^5.4.3"
buffer-alloc "^1.2.0"
buffer-from "^1.1.1"
dijkstrajs "^1.0.1"
isarray "^2.0.1"
pngjs "^3.3.0"
yargs "^13.2.4"
qs@5.2.0: qs@5.2.0:
version "5.2.0" version "5.2.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be"
@ -10446,7 +10387,7 @@ yargs@^10.0.3:
y18n "^3.2.1" y18n "^3.2.1"
yargs-parser "^8.0.0" yargs-parser "^8.0.0"
yargs@^13.2.4, yargs@^13.3.0: yargs@^13.3.0:
version "13.3.0" version "13.3.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83"
integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==

Loading…
Cancel
Save