on master help sign in
Support optional BIP39 passphrases in auth views.

Also cleans up some commented-out code.

commit18ec1b69484973ad4533666f51b7749c90ba6702 authorJared Tobin <jared@jtobin.io> dateThu 4 Apr 2019, 09:54 (8 years ago) parentcead653
3 files changed+105−28
src/bridge/views/Mnemonic.js+42−5 src/bridge/views/Shards.js+33−11 src/bridge/views/Ticket.js+30−12
src/bridge/views/Mnemonic.js+42−5
@@ -21,28 +21,47 @@ class Mnemonic extends React.Component {
2121
2222 this.state = {
2323 mnemonic: '',
24+ passphrase: '',
2425 hdpath: DEFAULT_HD_PATH,
2526 }
2627
2728 this.handleMnemonicInput = this.handleMnemonicInput.bind(this)
29+ this.handlePassphraseInput = this.handlePassphraseInput.bind(this)
2830 this.handleHdPathInput = this.handleHdPathInput.bind(this)
2931 }
3032
3133 componentDidMount() {
32− const { mnemonic, hdpath } = this.state
33− this.attemptWalletDerivation(mnemonic, hdpath)
34+ const { mnemonic, hdpath, passphrase } = this.state
35+ this.attemptWalletDerivation(mnemonic, hdpath, passphrase)
3436
3537 this.setState({
3638 exampleMnemonic: bip39.generateMnemonic(),
3739 })
3840 }
3941
42+ handlePassphraseInput(passphrase) {
43+ this.setState((state, _) => {
44+ const mnemonic = state.mnemonic
45+ const hdpath = state.hdpath
46+ this.attemptWalletDerivation(
47+ mnemonic,
48+ hdpath === '' ? DEFAULT_HD_PATH : hdpath,
49+ passphrase
50+ )
51+ return {
52+ passphrase
53+ }
54+ })
55+ }
56+
4057 handleMnemonicInput(mnemonic) {
4158 this.setState((state, _) => {
4259 const hdpath = state.hdpath
60+ const passphrase = state.passphrase
4361 this.attemptWalletDerivation(
4462 mnemonic,
45− hdpath === '' ? DEFAULT_HD_PATH : hdpath
63+ hdpath === '' ? DEFAULT_HD_PATH : hdpath,
64+ passphrase
4665 )
4766 return {
4867 mnemonic
@@ -53,9 +72,11 @@ class Mnemonic extends React.Component {
5372 handleHdPathInput(hdpath) {
5473 this.setState((state, _) => {
5574 const mnemonic = state.mnemonic
75+ const passphrase = state.passphrase
5676 this.attemptWalletDerivation(
5777 mnemonic,
58− hdpath === '' ? DEFAULT_HD_PATH : hdpath
78+ hdpath === '' ? DEFAULT_HD_PATH : hdpath,
79+ passphrase
5980 )
6081 return {
6182 hdpath
@@ -76,7 +97,8 @@ class Mnemonic extends React.Component {
7697 const {
7798 mnemonic,
7899 hdpath,
79− exampleMnemonic
100+ exampleMnemonic,
101+ passphrase
80102 } = this.state
81103
82104 return (
@@ -101,6 +123,21 @@ class Mnemonic extends React.Component {
101123 <InnerLabel>{'Mnemonic'}</InnerLabel>
102124 </MnemonicInput>
103125
126+ <InputCaption>
127+ {`If your wallet requires a passphrase, you may enter it below.`}
128+ </InputCaption>
129+
130+ <Input
131+ className='pt-8'
132+ prop-size='md'
133+ prop-format='innerLabel'
134+ name='passphrase'
135+ type='password'
136+ value={ passphrase }
137+ autocomplete='off'
138+ onChange={ this.handlePassphraseInput }>
139+ <InnerLabel>{'Passphrase'}</InnerLabel>
140+ </Input>
104141
105142 <InputCaption>
106143 {`If you'd like to use a custom derivation path, you may enter it below.`}
src/bridge/views/Shards.js+33−11
@@ -40,12 +40,14 @@ class Shards extends React.Component {
4040 shard1: '',
4141 shard2: '',
4242 shard3: '',
43+ passphrase: '',
4344 pointName: ''
4445 }
4546
4647 this.pointPlaceholder = placeholder(4)
4748 this.ticketPlaceholder = placeholder(16)
4849
50+ this.handlePassphraseInput = this.handlePassphraseInput.bind(this)
4951 this.handleShardInput = this.handleShardInput.bind(this)
5052 this.handlePointNameInput = this.handlePointNameInput.bind(this)
5153 }
@@ -60,19 +62,17 @@ class Shards extends React.Component {
6062 }
6163 }
6264
65+ handlePassphraseInput(passphrase) {
66+ this.setState({ passphrase })
67+ }
68+
6369 handlePointNameInput(pointName) {
6470 if (pointName.length < 15) {
6571 this.setState({ pointName })
6672 }
6773 }
6874
69− // buttonTriState = (wallet) => {
70− // if (wallet.isNothing()) return 'blue'
71− // if (wallet === false) return 'yellow'
72− // if (Maybe.Nothing.hasInstance(wallet)) return 'green'
73− // }
74−
75− async walletFromShards(shard1, shard2, shard3, pointName) {
75+ async walletFromShards(shard1, shard2, shard3, pointName, passphrase) {
7676 const { setWallet, setUrbitWallet } = this.props
7777
7878 const s1 = shard1 === '' ? undefined : shard1
@@ -89,10 +89,11 @@ class Shards extends React.Component {
8989 if (ticket !== undefined) {
9090 const urbitWallet = await kg.generateWallet({
9191 ticket: ticket,
92− ship: ob.patp2dec(pointName)
92+ ship: ob.patp2dec(pointName),
93+ passphrase: passphrase
9394 })
9495 const mnemonic = urbitWallet.ownership.seed
95− const wallet = walletFromMnemonic(mnemonic, DEFAULT_HD_PATH)
96+ const wallet = walletFromMnemonic(mnemonic, DEFAULT_HD_PATH, passphrase)
9697 setWallet(wallet)
9798 setUrbitWallet(Just(urbitWallet))
9899 }
@@ -100,7 +101,7 @@ class Shards extends React.Component {
100101
101102 render() {
102103 const { popRoute, pushRoute, wallet } = this.props
103− const { shard1, shard2, shard3, pointName } = this.state
104+ const { shard1, shard2, shard3, pointName, passphrase } = this.state
104105
105106 const phPoint = this.pointPlaceholder
106107 const phTick = this.ticketPlaceholder
@@ -176,13 +177,34 @@ class Shards extends React.Component {
176177 <InnerLabel>{ 'Shard 3' }</InnerLabel>
177178 </ShardInput>
178179
180+ <InputCaption>
181+ { 'If your wallet requires a passphrase, you may enter it below.' }
182+ </InputCaption>
183+
184+ <Input
185+ className='pt-8'
186+ prop-size='md'
187+ prop-format='innerLabel'
188+ name='passphrase'
189+ type='password'
190+ value={ passphrase }
191+ autocomplete='off'
192+ onChange={ this.handlePassphraseInput }>
193+ <InnerLabel>{'Passphrase'}</InnerLabel>
194+ </Input>
195+
179196 <Button
180197 disabled={ !ready }
181198 className={'mt-8'}
182199 prop-size={'lg wide'}
183200 // prop-color={this.buttonTriState(wallet)}
184201 onClick={() =>
185− this.walletFromShards(shard1, shard2, shard3, pointName)
202+ this.walletFromShards(
203+ shard1,
204+ shard2,
205+ shard3,
206+ pointName,
207+ passphrase)
186208 }>
187209 {'Unlock Wallet →'}
188210 </Button>
src/bridge/views/Ticket.js+30−12
@@ -33,6 +33,7 @@ class Ticket extends React.Component {
3333 this.state = {
3434 ticket: '',
3535 pointName: '',
36+ passphrase: '',
3637 isUnlocking: false
3738 }
3839
@@ -40,6 +41,7 @@ class Ticket extends React.Component {
4041 this.ticketPlaceholder = placeholder(8)
4142
4243 this.handleTicketInput = this.handleTicketInput.bind(this)
44+ this.handlePassphraseInput = this.handlePassphraseInput.bind(this)
4345 this.handlePointNameInput = this.handlePointNameInput.bind(this)
4446 }
4547
@@ -47,19 +49,17 @@ class Ticket extends React.Component {
4749 this.setState({ ticket })
4850 }
4951
52+ handlePassphraseInput(passphrase) {
53+ this.setState({ passphrase })
54+ }
55+
5056 handlePointNameInput(pointName) {
5157 if (pointName.length < 15) {
5258 this.setState({ pointName })
5359 }
5460 }
5561
56− // buttonTriState = (wallet) => {
57− // if (wallet.isNothing()) return 'blue'
58− // if (wallet === false) return 'yellow'
59− // if (Maybe.Nothing.hasInstance(wallet)) return 'green'
60− // }
61−
62− async walletFromTicket(ticket, pointName) {
62+ async walletFromTicket(ticket, pointName, passphrase) {
6363 const { setWallet, setUrbitWallet } = this.props
6464
6565 this.setState({
@@ -68,10 +68,11 @@ class Ticket extends React.Component {
6868
6969 const urbitWallet = await kg.generateWallet({
7070 ticket: ticket,
71− ship: ob.patp2dec(pointName)
71+ ship: ob.patp2dec(pointName),
72+ passphrase: passphrase
7273 })
7374 const mnemonic = urbitWallet.ownership.seed
74− const wallet = walletFromMnemonic(mnemonic, DEFAULT_HD_PATH)
75+ const wallet = walletFromMnemonic(mnemonic, DEFAULT_HD_PATH, passphrase)
7576 setWallet(wallet)
7677 setUrbitWallet(Just(urbitWallet))
7778
@@ -82,7 +83,7 @@ class Ticket extends React.Component {
8283
8384 render() {
8485 const { popRoute, pushRoute, wallet } = this.props
85− const { ticket, pointName } = this.state
86+ const { ticket, pointName, passphrase } = this.state
8687
8788 const phPoint = this.pointPlaceholder
8889 const phTick = this.ticketPlaceholder
@@ -126,12 +127,29 @@ class Ticket extends React.Component {
126127 <InnerLabel>{ 'Ticket' }</InnerLabel>
127128 </TicketInput>
128129
130+ <InputCaption>
131+ { 'If your wallet requires a passphrase, you may enter it below.' }
132+ </InputCaption>
133+
134+ <Input
135+ className='pt-8'
136+ prop-size='md'
137+ prop-format='innerLabel'
138+ name='passphrase'
139+ type='password'
140+ value={ passphrase }
141+ autocomplete='off'
142+ onChange={ this.handlePassphraseInput }>
143+ <InnerLabel>{'Passphrase'}</InnerLabel>
144+ </Input>
145+
129146 <Button
130147 className={'mt-8'}
131148 prop-size={'lg wide'}
132149 disabled={this.state.isUnlocking || Just.hasInstance(wallet)}
133− // prop-color={this.buttonTriState(wallet)}
134− onClick={() => this.walletFromTicket(ticket, pointName)}>
150+ onClick={
151+ () => this.walletFromTicket(ticket, pointName, passphrase)
152+ }>
135153
136154 <span className="relative">
137155 {this.state.isUnlocking &&