all: replace passPHRASE with passWORD in user interactions (#19932)

* Ref #19906 - replace passPHRASE with passWORD in any user interactions

this skips doccomments and variablenames to minimize impact. It does
however include a rename of the `ethkey` `changepassphrase` parameter

* console: fix JavaScript error capitalization
pull/19942/head
SjonHortensius 5 years ago committed by Péter Szilágyi
parent c9cdf144d5
commit 36994e4e0b
  1. 2
      accounts/errors.go
  2. 6
      accounts/external/backend.go
  3. 2
      accounts/keystore/keystore.go
  4. 2
      accounts/keystore/plain_test.go
  5. 2
      accounts/keystore/testdata/keystore/README
  6. 4
      cmd/clef/README.md
  7. 12
      cmd/clef/main.go
  8. 16
      cmd/clef/tutorial.md
  9. 12
      cmd/ethkey/README.md
  10. 14
      cmd/ethkey/changepassword.go
  11. 2
      cmd/ethkey/main.go
  12. 6
      cmd/ethkey/message_test.go
  13. 12
      cmd/ethkey/utils.go
  14. 30
      cmd/geth/accountcmd.go
  15. 48
      cmd/geth/accountcmd_test.go
  16. 2
      cmd/puppeth/wizard_faucet.go
  17. 2
      cmd/puppeth/wizard_node.go
  18. 2
      cmd/wnode/main.go
  19. 12
      console/bridge.go

@ -35,7 +35,7 @@ var ErrNotSupported = errors.New("not supported")
// ErrInvalidPassphrase is returned when a decryption operation receives a bad
// passphrase.
var ErrInvalidPassphrase = errors.New("invalid passphrase")
var ErrInvalidPassphrase = errors.New("invalid password")
// ErrWalletAlreadyOpen is returned if a wallet is attempted to be opened the
// second time.

@ -204,14 +204,14 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
}
func (api *ExternalSigner) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) {
return []byte{}, fmt.Errorf("passphrase-operations not supported on external signers")
return []byte{}, fmt.Errorf("password-operations not supported on external signers")
}
func (api *ExternalSigner) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
return nil, fmt.Errorf("passphrase-operations not supported on external signers")
return nil, fmt.Errorf("password-operations not supported on external signers")
}
func (api *ExternalSigner) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) {
return nil, fmt.Errorf("passphrase-operations not supported on external signers")
return nil, fmt.Errorf("password-operations not supported on external signers")
}
func (api *ExternalSigner) listAccounts() ([]common.Address, error) {

@ -43,7 +43,7 @@ import (
var (
ErrLocked = accounts.NewAuthNeededError("password or unlock")
ErrNoMatch = errors.New("no key for given address or file")
ErrDecrypt = errors.New("could not decrypt key with given passphrase")
ErrDecrypt = errors.New("could not decrypt key with given password")
)
// KeyStoreType is the reflect type of a keystore backend.

@ -96,7 +96,7 @@ func TestKeyStorePassphraseDecryptionFail(t *testing.T) {
t.Fatal(err)
}
if _, err = ks.GetKey(k1.Address, account.URL.Path, "bar"); err != ErrDecrypt {
t.Fatalf("wrong error for invalid passphrase\ngot %q\nwant %q", err, ErrDecrypt)
t.Fatalf("wrong error for invalid password\ngot %q\nwant %q", err, ErrDecrypt)
}
}

@ -1,5 +1,5 @@
This directory contains accounts for testing.
The passphrase that unlocks them is "foobar".
The password that unlocks them is "foobar".
The "good" key files which are supposed to be loadable are:

@ -566,8 +566,8 @@ Response
### account_export
#### Export account from keystore
Export a private key from the keystore. The exported private key is encrypted with the original passphrase. When the
key is imported later this passphrase is required.
Export a private key from the keystore. The exported private key is encrypted with the original password. When the
key is imported later this password is required.
#### Arguments
- account [address]: export private key that is associated with this account

@ -335,7 +335,7 @@ func setCredential(ctx *cli.Context) error {
utils.Fatalf("Invalid address specified: %s", addr)
}
address := common.HexToAddress(addr)
password := getPassPhrase("Please enter a passphrase to store for this address:", true)
password := getPassPhrase("Please enter a password to store for this address:", true)
fmt.Println()
stretchedKey, err := readMasterKey(ctx, nil)
@ -845,17 +845,17 @@ func testExternalUI(api *core.SignerAPI) {
// TODO: there are many `getPassPhrase` functions, it will be better to abstract them into one.
func getPassPhrase(prompt string, confirmation bool) string {
fmt.Println(prompt)
password, err := console.Stdin.PromptPassword("Passphrase: ")
password, err := console.Stdin.PromptPassword("Password: ")
if err != nil {
utils.Fatalf("Failed to read passphrase: %v", err)
utils.Fatalf("Failed to read password: %v", err)
}
if confirmation {
confirm, err := console.Stdin.PromptPassword("Repeat passphrase: ")
confirm, err := console.Stdin.PromptPassword("Repeat password: ")
if err != nil {
utils.Fatalf("Failed to read passphrase confirmation: %v", err)
utils.Fatalf("Failed to read password confirmation: %v", err)
}
if password != confirm {
utils.Fatalf("Passphrases do not match")
utils.Fatalf("Passwords do not match")
}
}
return password

@ -22,8 +22,8 @@ Enter 'ok' to proceed:
The master seed of clef will be locked with a password.
Please specify a password. Do not forget this password!
Passphrase:
Repeat passphrase:
Password:
Repeat password:
A master seed has been generated into /home/martin/.clef/masterseed.json
@ -124,7 +124,7 @@ $ sha256sum rules.js
$ clef attest 645b58e4f945e24d0221714ff29f6aa8e860382ced43490529db1695f5fcc71c
Decrypt master seed of clef
Passphrase:
Password:
INFO [07-01|13:25:03.290] Ruleset attestation updated sha256=645b58e4f945e24d0221714ff29f6aa8e860382ced43490529db1695f5fcc71c
```
@ -193,12 +193,12 @@ In order to make more useful rules - like signing transactions - the signer need
```text
$ clef setpw 0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3
Please enter a passphrase to store for this address:
Passphrase:
Repeat passphrase:
Please enter a password to store for this address:
Password:
Repeat password:
Decrypt master seed of clef
Passphrase:
Passpword:
INFO [07-01|14:05:56.031] Credential store updated key=0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3
```
@ -237,7 +237,7 @@ f163a1738b649259bb9b369c593fdc4c6b6f86cc87e343c3ba58faee03c2a178 rules.js
$ clef attest f163a1738b649259bb9b369c593fdc4c6b6f86cc87e343c3ba58faee03c2a178
Decrypt master seed of clef
Passphrase:
Password:
INFO [07-01|14:11:28.509] Ruleset attestation updated sha256=f163a1738b649259bb9b369c593fdc4c6b6f86cc87e343c3ba58faee03c2a178
```

@ -35,18 +35,18 @@ It is possible to refer to a file containing the message.
To sign a message contained in a file, use the --msgfile flag.
### `ethkey changepassphrase <keyfile>`
### `ethkey changepassword <keyfile>`
Change the passphrase of a keyfile.
Change the password of a keyfile.
use the `--newpasswordfile` to point to the new password file.
## Passphrases
## Passwords
For every command that uses a keyfile, you will be prompted to provide the
passphrase for decrypting the keyfile. To avoid this message, it is possible
to pass the passphrase by using the `--passwordfile` flag pointing to a file that
contains the passphrase.
password for decrypting the keyfile. To avoid this message, it is possible
to pass the password by using the `--passwordfile` flag pointing to a file that
contains the password.
## JSON

@ -28,15 +28,15 @@ import (
var newPassphraseFlag = cli.StringFlag{
Name: "newpasswordfile",
Usage: "the file that contains the new passphrase for the keyfile",
Usage: "the file that contains the new password for the keyfile",
}
var commandChangePassphrase = cli.Command{
Name: "changepassphrase",
Usage: "change the passphrase on a keyfile",
Name: "changepassword",
Usage: "change the password on a keyfile",
ArgsUsage: "<keyfile>",
Description: `
Change the passphrase of a keyfile.`,
Change the password of a keyfile.`,
Flags: []cli.Flag{
passphraseFlag,
newPassphraseFlag,
@ -58,12 +58,12 @@ Change the passphrase of a keyfile.`,
}
// Get a new passphrase.
fmt.Println("Please provide a new passphrase")
fmt.Println("Please provide a new password")
var newPhrase string
if passFile := ctx.String(newPassphraseFlag.Name); passFile != "" {
content, err := ioutil.ReadFile(passFile)
if err != nil {
utils.Fatalf("Failed to read new passphrase file '%s': %v", passFile, err)
utils.Fatalf("Failed to read new password file '%s': %v", passFile, err)
}
newPhrase = strings.TrimRight(string(content), "\r\n")
} else {
@ -73,7 +73,7 @@ Change the passphrase of a keyfile.`,
// Encrypt the key with the new passphrase.
newJson, err := keystore.EncryptKey(key, newPhrase, keystore.StandardScryptN, keystore.StandardScryptP)
if err != nil {
utils.Fatalf("Error encrypting with new passphrase: %v", err)
utils.Fatalf("Error encrypting with new password: %v", err)
}
// Then write the new keyfile in place of the old one.

@ -49,7 +49,7 @@ func init() {
var (
passphraseFlag = cli.StringFlag{
Name: "passwordfile",
Usage: "the file that contains the passphrase for the keyfile",
Usage: "the file that contains the password for the keyfile",
}
jsonFlag = cli.BoolFlag{
Name: "json",

@ -37,8 +37,8 @@ func TestMessageSignVerify(t *testing.T) {
generate := runEthkey(t, "generate", keyfile)
generate.Expect(`
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Repeat passphrase: {{.InputLine "foobar"}}
Password: {{.InputLine "foobar"}}
Repeat password: {{.InputLine "foobar"}}
`)
_, matches := generate.ExpectRegexp(`Address: (0x[0-9a-fA-F]{40})\n`)
address := matches[1]
@ -48,7 +48,7 @@ Repeat passphrase: {{.InputLine "foobar"}}
sign := runEthkey(t, "signmessage", keyfile, message)
sign.Expect(`
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Password: {{.InputLine "foobar"}}
`)
_, matches = sign.ExpectRegexp(`Signature: ([0-9a-f]+)\n`)
signature := matches[1]

@ -31,18 +31,18 @@ import (
// promptPassphrase prompts the user for a passphrase. Set confirmation to true
// to require the user to confirm the passphrase.
func promptPassphrase(confirmation bool) string {
passphrase, err := console.Stdin.PromptPassword("Passphrase: ")
passphrase, err := console.Stdin.PromptPassword("Password: ")
if err != nil {
utils.Fatalf("Failed to read passphrase: %v", err)
utils.Fatalf("Failed to read password: %v", err)
}
if confirmation {
confirm, err := console.Stdin.PromptPassword("Repeat passphrase: ")
confirm, err := console.Stdin.PromptPassword("Repeat password: ")
if err != nil {
utils.Fatalf("Failed to read passphrase confirmation: %v", err)
utils.Fatalf("Failed to read password confirmation: %v", err)
}
if passphrase != confirm {
utils.Fatalf("Passphrases do not match")
utils.Fatalf("Passwords do not match")
}
}
@ -58,7 +58,7 @@ func getPassphrase(ctx *cli.Context) string {
if passphraseFile != "" {
content, err := ioutil.ReadFile(passphraseFile)
if err != nil {
utils.Fatalf("Failed to read passphrase file '%s': %v",
utils.Fatalf("Failed to read password file '%s': %v",
passphraseFile, err)
}
return strings.TrimRight(string(content), "\r\n")

@ -116,11 +116,11 @@ Print a short summary of all accounts`,
Creates a new account and prints the address.
The account is saved in encrypted format, you are prompted for a passphrase.
The account is saved in encrypted format, you are prompted for a password.
You must remember this passphrase to unlock your account in the future.
You must remember this password to unlock your account in the future.
For non-interactive use the passphrase can be specified with the --password flag:
For non-interactive use the password can be specified with the --password flag:
Note, this is meant to be used for testing only, it is a bad idea to save your
password to file or expose in any other way.
@ -142,12 +142,12 @@ password to file or expose in any other way.
Update an existing account.
The account is saved in the newest version in encrypted format, you are prompted
for a passphrase to unlock the account and another to save the updated file.
for a password to unlock the account and another to save the updated file.
This same command can therefore be used to migrate an account of a deprecated
format to the newest format or change the password for an account.
For non-interactive use the passphrase can be specified with the --password flag:
For non-interactive use the password can be specified with the --password flag:
geth account update [options] <address>
@ -174,11 +174,11 @@ Prints the address.
The keyfile is assumed to contain an unencrypted private key in hexadecimal format.
The account is saved in encrypted format, you are prompted for a passphrase.
The account is saved in encrypted format, you are prompted for a password.
You must remember this passphrase to unlock your account in the future.
You must remember this password to unlock your account in the future.
For non-interactive use the passphrase can be specified with the -password flag:
For non-interactive use the password can be specified with the -password flag:
geth account import [options] <keyfile>
@ -247,17 +247,17 @@ func getPassPhrase(prompt string, confirmation bool, i int, passwords []string)
if prompt != "" {
fmt.Println(prompt)
}
password, err := console.Stdin.PromptPassword("Passphrase: ")
password, err := console.Stdin.PromptPassword("Password: ")
if err != nil {
utils.Fatalf("Failed to read passphrase: %v", err)
utils.Fatalf("Failed to read password: %v", err)
}
if confirmation {
confirm, err := console.Stdin.PromptPassword("Repeat passphrase: ")
confirm, err := console.Stdin.PromptPassword("Repeat password: ")
if err != nil {
utils.Fatalf("Failed to read passphrase confirmation: %v", err)
utils.Fatalf("Failed to read password confirmation: %v", err)
}
if password != confirm {
utils.Fatalf("Passphrases do not match")
utils.Fatalf("Passwords do not match")
}
}
return password
@ -268,7 +268,7 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr
for _, a := range err.Matches {
fmt.Println(" ", a.URL)
}
fmt.Println("Testing your passphrase against all of them...")
fmt.Println("Testing your password against all of them...")
var match *accounts.Account
for _, a := range err.Matches {
if err := ks.Unlock(a, auth); err == nil {
@ -279,7 +279,7 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr
if match == nil {
utils.Fatalf("None of the listed files could be unlocked.")
}
fmt.Printf("Your passphrase unlocked %s\n", match.URL)
fmt.Printf("Your password unlocked %s\n", match.URL)
fmt.Println("In order to avoid this warning, you need to remove the following duplicate key files:")
for _, a := range err.Matches {
if a != *match {

@ -72,8 +72,8 @@ func TestAccountNew(t *testing.T) {
geth.Expect(`
Your new account is locked with a password. Please give a password. Do not forget this password.
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Repeat passphrase: {{.InputLine "foobar"}}
Password: {{.InputLine "foobar"}}
Repeat password: {{.InputLine "foobar"}}
Your new key was generated
`)
@ -94,9 +94,9 @@ func TestAccountNewBadRepeat(t *testing.T) {
geth.Expect(`
Your new account is locked with a password. Please give a password. Do not forget this password.
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "something"}}
Repeat passphrase: {{.InputLine "something else"}}
Fatal: Passphrases do not match
Password: {{.InputLine "something"}}
Repeat password: {{.InputLine "something else"}}
Fatal: Passwords do not match
`)
}
@ -109,10 +109,10 @@ func TestAccountUpdate(t *testing.T) {
geth.Expect(`
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Password: {{.InputLine "foobar"}}
Please give a new password. Do not forget this password.
Passphrase: {{.InputLine "foobar2"}}
Repeat passphrase: {{.InputLine "foobar2"}}
Password: {{.InputLine "foobar2"}}
Repeat password: {{.InputLine "foobar2"}}
`)
}
@ -121,7 +121,7 @@ func TestWalletImport(t *testing.T) {
defer geth.ExpectExit()
geth.Expect(`
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foo"}}
Password: {{.InputLine "foo"}}
Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f}
`)
@ -136,8 +136,8 @@ func TestWalletImportBadPassword(t *testing.T) {
defer geth.ExpectExit()
geth.Expect(`
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "wrong"}}
Fatal: could not decrypt key with given passphrase
Password: {{.InputLine "wrong"}}
Fatal: could not decrypt key with given password
`)
}
@ -150,7 +150,7 @@ func TestUnlockFlag(t *testing.T) {
geth.Expect(`
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Password: {{.InputLine "foobar"}}
`)
geth.ExpectExit()
@ -174,12 +174,12 @@ func TestUnlockFlagWrongPassword(t *testing.T) {
geth.Expect(`
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "wrong1"}}
Password: {{.InputLine "wrong1"}}
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3
Passphrase: {{.InputLine "wrong2"}}
Password: {{.InputLine "wrong2"}}
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3
Passphrase: {{.InputLine "wrong3"}}
Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given passphrase)
Password: {{.InputLine "wrong3"}}
Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given password)
`)
}
@ -193,9 +193,9 @@ func TestUnlockFlagMultiIndex(t *testing.T) {
geth.Expect(`
Unlocking account 0 | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Password: {{.InputLine "foobar"}}
Unlocking account 2 | Attempt 1/3
Passphrase: {{.InputLine "foobar"}}
Password: {{.InputLine "foobar"}}
`)
geth.ExpectExit()
@ -238,7 +238,7 @@ func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
"--password", "testdata/wrong-passwords.txt", "--unlock", "0,2")
defer geth.ExpectExit()
geth.Expect(`
Fatal: Failed to unlock account 0 (could not decrypt key with given passphrase)
Fatal: Failed to unlock account 0 (could not decrypt key with given password)
`)
}
@ -258,12 +258,12 @@ func TestUnlockFlagAmbiguous(t *testing.T) {
geth.Expect(`
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foobar"}}
Password: {{.InputLine "foobar"}}
Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
keystore://{{keypath "1"}}
keystore://{{keypath "2"}}
Testing your passphrase against all of them...
Your passphrase unlocked keystore://{{keypath "1"}}
Testing your password against all of them...
Your password unlocked keystore://{{keypath "1"}}
In order to avoid this warning, you need to remove the following duplicate key files:
keystore://{{keypath "2"}}
`)
@ -295,11 +295,11 @@ func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
geth.Expect(`
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
!! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "wrong"}}
Password: {{.InputLine "wrong"}}
Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
keystore://{{keypath "1"}}
keystore://{{keypath "2"}}
Testing your passphrase against all of them...
Testing your password against all of them...
Fatal: None of the listed files could be unlocked.
`)
geth.ExpectExit()

@ -147,7 +147,7 @@ func (w *wizard) deployFaucet() {
infos.node.keyPass = w.readPassword()
if _, err := keystore.DecryptKey([]byte(infos.node.keyJSON), infos.node.keyPass); err != nil {
log.Error("Failed to decrypt key with given passphrase")
log.Error("Failed to decrypt key with given password")
infos.node.keyJSON = ""
infos.node.keyPass = ""
}

@ -142,7 +142,7 @@ func (w *wizard) deployNode(boot bool) {
infos.keyPass = w.readPassword()
if _, err := keystore.DecryptKey([]byte(infos.keyJSON), infos.keyPass); err != nil {
log.Error("Failed to decrypt key with given passphrase")
log.Error("Failed to decrypt key with given password")
return
}
}

@ -356,7 +356,7 @@ func configureNode() {
if len(symPass) == 0 {
symPass, err = console.Stdin.PromptPassword("Please enter the password for symmetric encryption: ")
if err != nil {
utils.Fatalf("Failed to read passphrase: %v", err)
utils.Fatalf("Failed to read password: %v", err)
}
}

@ -59,14 +59,14 @@ func (b *bridge) NewAccount(call otto.FunctionCall) (response otto.Value) {
switch {
// No password was specified, prompt the user for it
case len(call.ArgumentList) == 0:
if password, err = b.prompter.PromptPassword("Passphrase: "); err != nil {
if password, err = b.prompter.PromptPassword("Password: "); err != nil {
throwJSException(err.Error())
}
if confirm, err = b.prompter.PromptPassword("Repeat passphrase: "); err != nil {
if confirm, err = b.prompter.PromptPassword("Repeat password: "); err != nil {
throwJSException(err.Error())
}
if password != confirm {
throwJSException("passphrases don't match!")
throwJSException("passwords don't match!")
}
// A single string password was specified, use that
@ -180,7 +180,7 @@ func (b *bridge) OpenWallet(call otto.FunctionCall) (response otto.Value) {
func (b *bridge) readPassphraseAndReopenWallet(call otto.FunctionCall) (otto.Value, error) {
var passwd otto.Value
wallet := call.Argument(0)
if input, err := b.prompter.PromptPassword("Please enter your passphrase: "); err != nil {
if input, err := b.prompter.PromptPassword("Please enter your password: "); err != nil {
throwJSException(err.Error())
} else {
passwd, _ = otto.ToValue(input)
@ -223,7 +223,7 @@ func (b *bridge) UnlockAccount(call otto.FunctionCall) (response otto.Value) {
if call.Argument(1).IsUndefined() || call.Argument(1).IsNull() {
fmt.Fprintf(b.printer, "Unlock account %s\n", account)
if input, err := b.prompter.PromptPassword("Passphrase: "); err != nil {
if input, err := b.prompter.PromptPassword("Password: "); err != nil {
throwJSException(err.Error())
} else {
passwd, _ = otto.ToValue(input)
@ -270,7 +270,7 @@ func (b *bridge) Sign(call otto.FunctionCall) (response otto.Value) {
// if the password is not given or null ask the user and ensure password is a string
if passwd.IsUndefined() || passwd.IsNull() {
fmt.Fprintf(b.printer, "Give password for account %s\n", account)
if input, err := b.prompter.PromptPassword("Passphrase: "); err != nil {
if input, err := b.prompter.PromptPassword("Password: "); err != nil {
throwJSException(err.Error())
} else {
passwd, _ = otto.ToValue(input)

Loading…
Cancel
Save