Skip to content

Commit

Permalink
146-2-step-confirmation-on-delete-wallet-action (#227)
Browse files Browse the repository at this point in the history
adds a confirmation step on cancel wallet
  • Loading branch information
SebastienValla authored Oct 26, 2022
1 parent 6a4d223 commit b888e35
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 13 deletions.
1 change: 1 addition & 0 deletions int/api/html/front/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const errorCodes = new Map([
["Wallet-0001", "That nickname is taken. Try Another"],
["Wallet-0002", "Wrong password. Try again"],
["Wallet-0003", "Error while retrieving that wallet. Try again"],
["Wallet-0004", "Wallet not canceled"],
["Wallet-1001", "Enter a wallet nickname"],
["Wallet-1002", "Enter a wallet password"],
["Wallet-1003", "Error while creating your wallet. Try again"],
Expand Down
3 changes: 1 addition & 2 deletions int/api/html/front/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,9 @@ function deleteRow(element) {
.delete("/mgmt/wallet/" + nickname)
.then((_) => {
wallets = wallets.filter((wallet) => wallet.nickname != nickname);
document.getElementById("user-wallet-table").deleteRow(rowIndex);
})
.catch((e) => {
errorAlert(getErrorMessage(e.response.data.code));
});

document.getElementById("user-wallet-table").deleteRow(rowIndex);
}
2 changes: 1 addition & 1 deletion int/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func StartServer(app *fyne.App) {
localAPI.MgmtWalletGetHandler = wallet.NewGet(&walletStorage)
localAPI.MgmtWalletCreateHandler = wallet.NewCreate(&walletStorage)
localAPI.MgmtWalletImportHandler = wallet.NewImport(&walletStorage)
localAPI.MgmtWalletDeleteHandler = wallet.NewDelete(&walletStorage)
localAPI.MgmtWalletDeleteHandler = wallet.NewDelete(&walletStorage, app)

localAPI.WebsiteCreatorPrepareHandler = operations.WebsiteCreatorPrepareHandlerFunc(
websites.CreatePrepareForWebsiteHandler(app),
Expand Down
37 changes: 29 additions & 8 deletions int/api/wallet/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,31 @@ package wallet
import (
"sync"

"fyne.io/fyne/v2"
"github.com/go-openapi/runtime/middleware"
"github.com/massalabs/thyra/api/swagger/server/models"
"github.com/massalabs/thyra/api/swagger/server/restapi/operations"
"github.com/massalabs/thyra/pkg/gui"
"github.com/massalabs/thyra/pkg/wallet"
)

//nolint:nolintlint,ireturn
func NewDelete(walletStorage *sync.Map) operations.MgmtWalletDeleteHandler {
return &walletDelete{walletStorage: walletStorage}
func NewDelete(walletStorage *sync.Map, app *fyne.App) operations.MgmtWalletDeleteHandler {
return &walletDelete{walletStorage: walletStorage, app: app}
}

type walletDelete struct {
walletStorage *sync.Map
app *fyne.App
}

//nolint:nolintlint,ireturn
func (c *walletDelete) Handle(params operations.MgmtWalletDeleteParams) middleware.Responder {
walletLoaded, err := wallet.Load(params.Nickname)
if err != nil {
return createInternalServerError(errorCodeGetWallet, err.Error())
}

if len(params.Nickname) == 0 {
return operations.NewMgmtWalletDeleteBadRequest().WithPayload(
&models.Error{
Expand All @@ -28,16 +36,29 @@ func (c *walletDelete) Handle(params operations.MgmtWalletDeleteParams) middlewa
})
}

password := gui.AskPasswordDeleteWallet(params.Nickname, c.app)

err = walletLoaded.Unprotect(password, 0)
if err != nil {
return createInternalServerError(errorCodeWalletWrongPassword, err.Error())
}

c.walletStorage.Delete(params.Nickname)

err := wallet.Delete(params.Nickname)
err = wallet.Delete(params.Nickname)
if err != nil {
return operations.NewMgmtWalletDeleteInternalServerError().WithPayload(
&models.Error{
Code: errorCodeWalletDeleteFile,
Message: err.Error(),
})
return createInternalServerError(errorCodeWalletDeleteFile, err.Error())
}

return operations.NewMgmtWalletDeleteNoContent()
}

//nolint:nolintlint,ireturn
func createInternalServerError(errorCode string, errorMessage string) middleware.Responder {
return operations.NewWebsiteCreatorPrepareInternalServerError().
WithPayload(
&models.Error{
Code: errorCode,
Message: errorMessage,
})
}
3 changes: 3 additions & 0 deletions int/api/wallet/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package wallet

const (
errorCodeWalletAlreadyExists = "Wallet-0001"
errorCodeWalletWrongPassword = "Wallet-0002"
errorCodeGetWallet = "Wallet-0003"
errorCodeCanceled = "Wallet-0004"
errorCodeWalletCreateNoNickname = "Wallet-1001"
errorCodeWalletCreateNoPassword = "Wallet-1002"
errorCodeWalletCreateNew = "Wallet-1003"
Expand Down
56 changes: 54 additions & 2 deletions pkg/gui/password.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@ package gui

import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
)

func AskPassword(nickname string, app *fyne.App) string {
return Password(nickname, app)
}

func AskPasswordDeleteWallet(nickname string, app *fyne.App) string {
return PasswordDeleteWallet(nickname, app)
}

// inspired by https://hackernoon.com/asyncawait-in-golang-an-introductory-guide-ol1e34sg

// Thyra password input dialog.
func PasswordDialog(nickname string, app *fyne.App) chan string {
passwordText := make(chan string)

window := (*app).NewWindow("Massa - Thyra")

width := 250.0
height := 90.0

Expand Down Expand Up @@ -50,7 +54,55 @@ func PasswordDialog(nickname string, app *fyne.App) chan string {
return passwordText
}

func PasswordDeleteDialog(nickname string, app *fyne.App) chan string {
passwordText := make(chan string)

window := (*app).NewWindow("Massa - Thyra")

width := 250.0
height := 80.0

window.Resize(fyne.Size{Width: float32(width), Height: float32(height)})

password := widget.NewPasswordEntry()
items := []*widget.FormItem{
widget.NewFormItem("Password", password),
}

//nolint:exhaustruct
form := &widget.Form{
Items: items,
OnSubmit: func() {
window.Hide()
passwordText <- password.Text
},
OnCancel: func() {
passwordText <- ""
window.Hide()
},
SubmitText: "Delete",
CancelText: "Cancel",
}
spacer := layout.NewSpacer()
text1 := widget.NewLabel(`Delete "` + nickname + `" Wallet ?`)
title := container.New(layout.NewHBoxLayout(), spacer, text1, spacer)
text2 := widget.NewLabel("If you delete a wallet, you will lose your MAS associated to it and ")
text3 := widget.NewLabel("won't be able to edit websites linked to this wallet anymore ")
content := container.New(layout.NewVBoxLayout(), text2, text3, spacer)
centeredForm := container.New(layout.NewVBoxLayout(), spacer, form, spacer)
window.SetContent(container.New(layout.NewVBoxLayout(), title, spacer, content, spacer, centeredForm, spacer))
window.CenterOnScreen()
window.Canvas().Focus(password)
window.Show()

return passwordText
}

// This function is blocking, it returns when the user submit or cancel the form.
func Password(nickname string, app *fyne.App) string {
return <-PasswordDialog(nickname, app)
}

func PasswordDeleteWallet(nickname string, app *fyne.App) string {
return <-PasswordDeleteDialog(nickname, app)
}

0 comments on commit b888e35

Please sign in to comment.