171 lines
4.0 KiB
Go
171 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
encrypt "fckeuspy-go/lib"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/app"
|
|
"fyne.io/fyne/v2/container"
|
|
"fyne.io/fyne/v2/dialog"
|
|
"fyne.io/fyne/v2/widget"
|
|
)
|
|
|
|
func NewUI() (stprageDir string, window fyne.Window) {
|
|
// App + storage dir
|
|
a := app.New()
|
|
w := a.NewWindow("Encryptor (Fyne)")
|
|
prefs := a.Preferences()
|
|
width := prefs.IntWithFallback("winW", 1100)
|
|
height := prefs.IntWithFallback("winH", 720)
|
|
w.Resize(fyne.NewSize(float32(width), float32(height)))
|
|
w.SetOnClosed(func() {
|
|
sz := w.Canvas().Size()
|
|
prefs.SetInt("winW", int(sz.Width))
|
|
prefs.SetInt("winH", int(sz.Height))
|
|
})
|
|
|
|
// docasny bypass
|
|
/*
|
|
base, err := os.UserConfigDir()
|
|
if err != nil {
|
|
base, _ = os.UserHomeDir()
|
|
}
|
|
*/
|
|
base := "./"
|
|
|
|
//return filepath.Join(base, "fckeuspy-go"), w
|
|
return filepath.Join(base, ""), w
|
|
}
|
|
|
|
// ShowPasswordVaultDialog zobrazí dialog pro vytvoření nebo otevření trezoru.
|
|
// Zatím pouze skeleton: vrací heslo přes callback, reálné volání CreateEncryptedStore/OpenEncryptedStore mimo.
|
|
func ShowPasswordVaultDialog(w fyne.Window, vaultPath string, onResult func(create bool, password string)) {
|
|
// Unlock tab
|
|
unlockPw := widget.NewPasswordEntry()
|
|
unlockPw.SetPlaceHolder("Heslo…")
|
|
unlockForm := widget.NewForm(
|
|
widget.NewFormItem("Heslo", unlockPw),
|
|
)
|
|
unlockContent := container.NewVBox(unlockForm)
|
|
|
|
// Create tab
|
|
createPw1 := widget.NewPasswordEntry()
|
|
createPw1.SetPlaceHolder("Heslo…")
|
|
createPw2 := widget.NewPasswordEntry()
|
|
createPw2.SetPlaceHolder("Znovu heslo…")
|
|
strengthBar := widget.NewProgressBar()
|
|
strengthBar.Min = 0
|
|
strengthBar.Max = 100
|
|
strengthLabel := widget.NewLabel("")
|
|
updateStrength := func(pw string) {
|
|
score, desc := simpleScore(pw)
|
|
strengthBar.SetValue(float64(score))
|
|
strengthLabel.SetText(desc)
|
|
}
|
|
createPw1.OnChanged = updateStrength
|
|
genBtn := widget.NewButton("Generovat", func() {
|
|
if v, err := encrypt.GenerateRandomPassword(20); err == nil {
|
|
createPw1.SetText(v)
|
|
createPw2.SetText(v)
|
|
updateStrength(v)
|
|
}
|
|
})
|
|
meter := container.NewVBox(strengthBar, strengthLabel)
|
|
topCreate := container.NewBorder(nil, nil, nil, genBtn, meter)
|
|
createForm := widget.NewForm(
|
|
widget.NewFormItem("Heslo", createPw1),
|
|
widget.NewFormItem("Potvrzení", createPw2),
|
|
)
|
|
createContent := container.NewVBox(topCreate, createForm)
|
|
|
|
tabs := container.NewAppTabs(
|
|
container.NewTabItem("Odemknout", unlockContent),
|
|
container.NewTabItem("Vytvořit", createContent),
|
|
)
|
|
tabs.SetTabLocation(container.TabLocationTop)
|
|
// Výběr aktivní záložky dle existence souboru
|
|
if _, err := os.Stat(vaultPath); err != nil { // neexistuje => vytvořit
|
|
tabs.SelectIndex(1)
|
|
} else {
|
|
tabs.SelectIndex(0)
|
|
}
|
|
|
|
d := dialog.NewCustomConfirm("Trezor", "OK", "Zrušit", tabs, func(ok bool) {
|
|
if !ok {
|
|
onResult(false, "")
|
|
return
|
|
}
|
|
sel := tabs.Selected()
|
|
if sel != nil && sel.Text == "Vytvořit" {
|
|
pw := createPw1.Text
|
|
if pw != createPw2.Text {
|
|
dialog.NewError(errors.New("Hesla se neshodují"), w).Show()
|
|
return
|
|
}
|
|
if err := encrypt.ValidatePasswordForUI(pw); err != nil {
|
|
dialog.NewError(err, w).Show()
|
|
return
|
|
}
|
|
onResult(true, pw)
|
|
return
|
|
}
|
|
// Unlock
|
|
onResult(false, unlockPw.Text)
|
|
}, w)
|
|
// Větší rozměr pro lepší přehlednost
|
|
d.Resize(fyne.NewSize(620, 440))
|
|
d.Show()
|
|
}
|
|
|
|
// simpleScore: hrubá heuristika (0-100)
|
|
func simpleScore(pw string) (int, string) {
|
|
l := len(pw)
|
|
var u, lw, dg, sp int
|
|
specials := "!@#-_+="
|
|
for _, r := range pw {
|
|
switch {
|
|
case r >= 'A' && r <= 'Z':
|
|
u++
|
|
case r >= 'a' && r <= 'z':
|
|
lw++
|
|
case r >= '0' && r <= '9':
|
|
dg++
|
|
default:
|
|
if strings.ContainsRune(specials, r) {
|
|
sp++
|
|
}
|
|
}
|
|
}
|
|
cats := 0
|
|
if u > 0 {
|
|
cats++
|
|
}
|
|
if lw > 0 {
|
|
cats++
|
|
}
|
|
if dg > 0 {
|
|
cats++
|
|
}
|
|
if sp > 0 {
|
|
cats++
|
|
}
|
|
score := l*4 + cats*10
|
|
if score > 100 {
|
|
score = 100
|
|
}
|
|
desc := "Slabé"
|
|
switch {
|
|
case score >= 85:
|
|
desc = "Silné"
|
|
case score >= 60:
|
|
desc = "Dobré"
|
|
case score >= 30:
|
|
desc = "Střední"
|
|
}
|
|
return score, desc
|
|
}
|