diff options
author | jloup <jloup@jloup.work> | 2018-05-13 14:10:21 +0100 |
---|---|---|
committer | jloup <jloup@jloup.work> | 2018-05-13 14:10:21 +0100 |
commit | c6aa553f48d1014f651441bbd9e023508d0a819c (patch) | |
tree | bb9af139ba3d8d4c9cc74114473e03eaef0d9004 | |
parent | a7873be28f3bcda36dd9fc54df238738c4c2b998 (diff) | |
download | Front-c6aa553f48d1014f651441bbd9e023508d0a819c.tar.gz Front-c6aa553f48d1014f651441bbd9e023508d0a819c.tar.zst Front-c6aa553f48d1014f651441bbd9e023508d0a819c.zip |
Load credentials only when user requests it.
-rw-r--r-- | api/const.go | 3 | ||||
-rw-r--r-- | api/const_string.go | 12 | ||||
-rw-r--r-- | api/market_config.go | 2 | ||||
-rw-r--r-- | cmd/web/js/account.jsx | 46 |
4 files changed, 30 insertions, 33 deletions
diff --git a/api/const.go b/api/const.go index 1f15c6e..2ad4d61 100644 --- a/api/const.go +++ b/api/const.go | |||
@@ -19,6 +19,7 @@ const ( | |||
19 | InvalidCredentials | 19 | InvalidCredentials |
20 | InvalidEmail | 20 | InvalidEmail |
21 | InvalidMarketCredentials | 21 | InvalidMarketCredentials |
22 | MarketCredentialsNotConfigured | ||
22 | IPRestrictedApiKey | 23 | IPRestrictedApiKey |
23 | InvalidOtp | 24 | InvalidOtp |
24 | InvalidPassword | 25 | InvalidPassword |
@@ -36,7 +37,7 @@ func StatusToHttpCode(status Status, code ErrorCode) int { | |||
36 | } | 37 | } |
37 | 38 | ||
38 | switch code { | 39 | switch code { |
39 | case BadRequest, InvalidPassword, InvalidEmail, InvalidMarketCredentials, IPRestrictedApiKey: | 40 | case BadRequest, InvalidPassword, InvalidEmail, InvalidMarketCredentials, IPRestrictedApiKey, MarketCredentialsNotConfigured: |
40 | return http.StatusBadRequest | 41 | return http.StatusBadRequest |
41 | 42 | ||
42 | case InvalidCredentials, InvalidOtp: | 43 | case InvalidCredentials, InvalidOtp: |
diff --git a/api/const_string.go b/api/const_string.go index 58ed230..5af7574 100644 --- a/api/const_string.go +++ b/api/const_string.go | |||
@@ -1,8 +1,8 @@ | |||
1 | // Code generated by "stringer -type=Status,ErrorCode -output const_string.go"; DO NOT EDIT | 1 | // Code generated by "stringer -type=Status,ErrorCode -output const_string.go"; DO NOT EDIT. |
2 | 2 | ||
3 | package api | 3 | package api |
4 | 4 | ||
5 | import "fmt" | 5 | import "strconv" |
6 | 6 | ||
7 | const _Status_name = "OKNOK" | 7 | const _Status_name = "OKNOK" |
8 | 8 | ||
@@ -10,19 +10,19 @@ var _Status_index = [...]uint8{0, 2, 5} | |||
10 | 10 | ||
11 | func (i Status) String() string { | 11 | func (i Status) String() string { |
12 | if i >= Status(len(_Status_index)-1) { | 12 | if i >= Status(len(_Status_index)-1) { |
13 | return fmt.Sprintf("Status(%d)", i) | 13 | return "Status(" + strconv.FormatInt(int64(i), 10) + ")" |
14 | } | 14 | } |
15 | return _Status_name[_Status_index[i]:_Status_index[i+1]] | 15 | return _Status_name[_Status_index[i]:_Status_index[i+1]] |
16 | } | 16 | } |
17 | 17 | ||
18 | const _ErrorCode_name = "BadRequestEmailExistsExternalServiceTimeoutInternalErrorInvalidCredentialsInvalidEmailInvalidMarketCredentialsIPRestrictedApiKeyInvalidOtpInvalidPasswordNeedOtpValidationNotAuthorizedNotFoundOtpAlreadySetupOtpNotSetupUserNotConfirmed" | 18 | const _ErrorCode_name = "BadRequestEmailExistsExternalServiceTimeoutInternalErrorInvalidCredentialsInvalidEmailInvalidMarketCredentialsMarketCredentialsNotConfiguredIPRestrictedApiKeyInvalidOtpInvalidPasswordNeedOtpValidationNotAuthorizedNotFoundOtpAlreadySetupOtpNotSetupUserNotConfirmed" |
19 | 19 | ||
20 | var _ErrorCode_index = [...]uint8{0, 10, 21, 43, 56, 74, 86, 110, 128, 138, 153, 170, 183, 191, 206, 217, 233} | 20 | var _ErrorCode_index = [...]uint16{0, 10, 21, 43, 56, 74, 86, 110, 140, 158, 168, 183, 200, 213, 221, 236, 247, 263} |
21 | 21 | ||
22 | func (i ErrorCode) String() string { | 22 | func (i ErrorCode) String() string { |
23 | i -= 3 | 23 | i -= 3 |
24 | if i >= ErrorCode(len(_ErrorCode_index)-1) { | 24 | if i >= ErrorCode(len(_ErrorCode_index)-1) { |
25 | return fmt.Sprintf("ErrorCode(%d)", i+3) | 25 | return "ErrorCode(" + strconv.FormatInt(int64(i+3), 10) + ")" |
26 | } | 26 | } |
27 | return _ErrorCode_name[_ErrorCode_index[i]:_ErrorCode_index[i+1]] | 27 | return _ErrorCode_name[_ErrorCode_index[i]:_ErrorCode_index[i+1]] |
28 | } | 28 | } |
diff --git a/api/market_config.go b/api/market_config.go index e7b2341..09eb8a9 100644 --- a/api/market_config.go +++ b/api/market_config.go | |||
@@ -76,7 +76,7 @@ func (q TestMarketCredentialsQuery) Run() (interface{}, *Error) { | |||
76 | } | 76 | } |
77 | 77 | ||
78 | if config == nil || config.Config["key"] == "" || config.Config["secret"] == "" { | 78 | if config == nil || config.Config["key"] == "" || config.Config["secret"] == "" { |
79 | return nil, &Error{InvalidMarketCredentials, "no market credentials", fmt.Errorf("market credentials are empty for marketId '%v'", q.In.Market)} | 79 | return nil, &Error{MarketCredentialsNotConfigured, "no market credentials", fmt.Errorf("market credentials are empty for marketId '%v'", q.In.Market)} |
80 | } | 80 | } |
81 | 81 | ||
82 | resultErr := CallExternalService(fmt.Sprintf("'%s' TestCredentials", q.In.Market), EXTERNAL_SERVICE_TIMEOUT_SECONDS*time.Second, func() error { | 82 | resultErr := CallExternalService(fmt.Sprintf("'%s' TestCredentials", q.In.Market), EXTERNAL_SERVICE_TIMEOUT_SECONDS*time.Second, func() error { |
diff --git a/cmd/web/js/account.jsx b/cmd/web/js/account.jsx index 03ca117..c80be33 100644 --- a/cmd/web/js/account.jsx +++ b/cmd/web/js/account.jsx | |||
@@ -4,17 +4,20 @@ import React from 'react'; | |||
4 | class PoloniexConfiguration extends React.Component { | 4 | class PoloniexConfiguration extends React.Component { |
5 | constructor(props) { | 5 | constructor(props) { |
6 | super(props); | 6 | super(props); |
7 | this.state = {'apiKey': '', 'apiSecret': '', 'apiRequested': false, 'status': 'loading'}; | 7 | this.state = {'apiKey': '', 'apiSecret': '', 'apiRequested': false, 'status': 'loading', 'editMode': false}; |
8 | } | 8 | } |
9 | 9 | ||
10 | checkCredentials = () => { | 10 | checkCredentials = () => { |
11 | Api.Call('MARKET_TEST_CREDENTIALS', {'name': 'poloniex'}, function(err, status, data) { | 11 | Api.Call('MARKET_TEST_CREDENTIALS', {'name': 'poloniex'}, function(err, status, data) { |
12 | this.setState({'apiRequested': true}); | ||
12 | if (err) { | 13 | if (err) { |
13 | console.error(err, data); | 14 | console.error(err, data); |
14 | if (err.code === 'invalid_market_credentials') { | 15 | if (err.code === 'invalid_market_credentials') { |
15 | this.setState({'status': 'invalidCredentials'}); | 16 | this.setState({'status': 'invalidCredentials'}); |
16 | } else if (err.code === 'ip_restricted_api_key') { | 17 | } else if (err.code === 'ip_restricted_api_key') { |
17 | this.setState({'status': 'ipRestricted'}); | 18 | this.setState({'status': 'ipRestricted'}); |
19 | } else if (err.code === 'market_credentials_not_configured') { | ||
20 | this.setState({'status': 'emptyCredentials'}); | ||
18 | } | 21 | } |
19 | return; | 22 | return; |
20 | } | 23 | } |
@@ -28,7 +31,7 @@ class PoloniexConfiguration extends React.Component { | |||
28 | } | 31 | } |
29 | 32 | ||
30 | handleCredentialsSubmit = () => { | 33 | handleCredentialsSubmit = () => { |
31 | this.setState({'status': 'loading'}); | 34 | this.setState({'status': 'loading', 'editMode': false}); |
32 | Api.Call('UPDATE_MARKET', {'key': this.state.apiKey, 'secret': this.state.apiSecret, 'name': 'poloniex'}, function(err, status, data) { | 35 | Api.Call('UPDATE_MARKET', {'key': this.state.apiKey, 'secret': this.state.apiSecret, 'name': 'poloniex'}, function(err, status, data) { |
33 | if (err) { | 36 | if (err) { |
34 | console.error(err, data); | 37 | console.error(err, data); |
@@ -40,14 +43,17 @@ class PoloniexConfiguration extends React.Component { | |||
40 | return; | 43 | return; |
41 | } | 44 | } |
42 | 45 | ||
43 | this.setState({'status': 'loading'}); | ||
44 | this.checkCredentials(); | 46 | this.checkCredentials(); |
45 | }.bind(this)); | 47 | }.bind(this)); |
46 | } | 48 | } |
47 | 49 | ||
48 | componentDidMount = () => { | 50 | componentDidMount = () => { |
49 | Api.Call('MARKET', {'name': 'poloniex'}, function(err, status, data) { | 51 | this.checkCredentials(); |
50 | this.setState({'apiRequested': true}); | 52 | } |
53 | |||
54 | onEditClick = () => { | ||
55 | Api.Call('MARKET', {'name': 'poloniex'}, function(err, status, data) { | ||
56 | this.setState({'apiRequested': true, 'editMode': true}); | ||
51 | if (err) { | 57 | if (err) { |
52 | console.error(err, data); | 58 | console.error(err, data); |
53 | return; | 59 | return; |
@@ -56,8 +62,6 @@ class PoloniexConfiguration extends React.Component { | |||
56 | var newStatus = this.state.status; | 62 | var newStatus = this.state.status; |
57 | if (!data.key || !data.secret) { | 63 | if (!data.key || !data.secret) { |
58 | newStatus = 'emptyCredentials'; | 64 | newStatus = 'emptyCredentials'; |
59 | } else { | ||
60 | this.checkCredentials(); | ||
61 | } | 65 | } |
62 | 66 | ||
63 | this.setState({'apiKey': data.key, 'apiSecret': data.secret, 'status': newStatus}); | 67 | this.setState({'apiKey': data.key, 'apiSecret': data.secret, 'status': newStatus}); |
@@ -97,21 +101,17 @@ class PoloniexConfiguration extends React.Component { | |||
97 | apiSecret={this.state.apiSecret} | 101 | apiSecret={this.state.apiSecret} |
98 | apiKey={this.state.apiKey} | 102 | apiKey={this.state.apiKey} |
99 | status={this.state.status} | 103 | status={this.state.status} |
100 | statusMessage={displayText}/> | 104 | statusMessage={displayText} |
105 | editMode={this.state.editMode} | ||
106 | onEditClick={this.onEditClick}/> | ||
101 | </div> | 107 | </div> |
102 | ); | 108 | ); |
103 | } | 109 | } |
104 | } | 110 | } |
105 | 111 | ||
106 | class PoloniexCredentialsForm extends React.Component { | 112 | class PoloniexCredentialsForm extends React.Component { |
107 | constructor(props) { | ||
108 | super(props); | ||
109 | this.state = {'editMode': false}; | ||
110 | } | ||
111 | |||
112 | handleSubmit = (e) => { | 113 | handleSubmit = (e) => { |
113 | this.props.onCredentialsSubmit(); | 114 | this.props.onCredentialsSubmit(); |
114 | this.setState({'editMode': false}); | ||
115 | e.preventDefault(); | 115 | e.preventDefault(); |
116 | } | 116 | } |
117 | 117 | ||
@@ -123,15 +123,11 @@ class PoloniexCredentialsForm extends React.Component { | |||
123 | this.props.onCredentialsChange(this.props.apiKey, event.target.value); | 123 | this.props.onCredentialsChange(this.props.apiKey, event.target.value); |
124 | } | 124 | } |
125 | 125 | ||
126 | onEditClick = () => { | ||
127 | this.setState({'editMode': true}); | ||
128 | } | ||
129 | |||
130 | render = () => { | 126 | render = () => { |
131 | var submitType = this.state.editMode === true ? 'submit' : 'hidden'; | 127 | var submitType = this.props.editMode === true ? 'submit' : 'hidden'; |
132 | var buttonDisplay = this.state.editMode === true ? 'none' : 'inline'; | 128 | var buttonDisplay = this.props.editMode === true ? 'none' : 'inline'; |
133 | var secretDisplayed = this.state.editMode === true ? this.props.apiSecret : 'XXXXXXX'; | 129 | var secretDisplayed = this.props.editMode === true ? this.props.apiSecret : 'XXXXXXX'; |
134 | var keyDisplayed = this.state.editMode === true ? this.props.apiKey : 'XXXXXXX'; | 130 | var keyDisplayed = this.props.editMode === true ? this.props.apiKey : 'XXXXXXX'; |
135 | 131 | ||
136 | var iconName = 'icon-cancel-circled'; | 132 | var iconName = 'icon-cancel-circled'; |
137 | switch (this.props.status) { | 133 | switch (this.props.status) { |
@@ -157,13 +153,13 @@ class PoloniexCredentialsForm extends React.Component { | |||
157 | <div className="col-12"> | 153 | <div className="col-12"> |
158 | <form role="form" onSubmit={this.handleSubmit}> | 154 | <form role="form" onSubmit={this.handleSubmit}> |
159 | <label className="w-100">Key: | 155 | <label className="w-100">Key: |
160 | <input className="form-control" type="text" placeholder="key" value={keyDisplayed} onChange={this.handleApiKeyChange} disabled={!this.state.editMode}/> | 156 | <input className="form-control" type="text" placeholder="key" value={keyDisplayed} onChange={this.handleApiKeyChange} disabled={!this.props.editMode}/> |
161 | </label> | 157 | </label> |
162 | <label className="w-100">Secret: | 158 | <label className="w-100">Secret: |
163 | <input className="form-control" type="text" placeholder="secret" value={secretDisplayed} onChange={this.handleApiSecretChange} disabled={!this.state.editMode}/> | 159 | <input className="form-control" type="text" placeholder="secret" value={secretDisplayed} onChange={this.handleApiSecretChange} disabled={!this.props.editMode}/> |
164 | </label> | 160 | </label> |
165 | <input className="form-control submit" type={submitType} value="Save" /> | 161 | <input className="form-control submit" type={submitType} value="Save" /> |
166 | <button className="form-control submit" style={{display: buttonDisplay}} onSubmit={null} onClick={this.onEditClick} type="button">Show/Edit</button> | 162 | <button className="form-control submit" style={{display: buttonDisplay}} onSubmit={null} onClick={this.props.onEditClick} type="button">Show/Edit</button> |
167 | </form> | 163 | </form> |
168 | </div> | 164 | </div> |
169 | </div> | 165 | </div> |