Bug fixes and tooltips
This commit is contained in:
parent
c9c9326897
commit
5224432780
|
@ -135,6 +135,7 @@ var keyfilePath string
|
|||
var keyfileLabel = "Use a keyfile"
|
||||
var metadata string
|
||||
var metadataPrompt = "Metadata (optional):"
|
||||
var metadataState = giu.InputTextFlagsNone
|
||||
var shredTemp bool
|
||||
var paranoid bool
|
||||
var keep bool
|
||||
|
@ -142,6 +143,7 @@ var reedsolo bool
|
|||
var split bool
|
||||
var splitSize string
|
||||
var fast bool
|
||||
var deleteEncrypted bool
|
||||
var kept = false // If a file was corrupted/modified, but the output was kept
|
||||
|
||||
var showGenpass = false
|
||||
|
@ -305,6 +307,7 @@ func startUI(){
|
|||
giu.Row(
|
||||
giu.Dummy(-58,0),
|
||||
giu.Button("Clear").Size(50,0).OnClick(resetUI),
|
||||
giu.Tooltip("Clear all input files and reset UI state."),
|
||||
),
|
||||
),
|
||||
|
||||
|
@ -335,33 +338,43 @@ func startUI(){
|
|||
|
||||
outputEntry = file
|
||||
}).Size(64,0),
|
||||
giu.Tooltip("Select a custom name and path to save the output as."),
|
||||
),
|
||||
|
||||
// Prompt for password
|
||||
giu.Row(
|
||||
giu.Label("Password:"),
|
||||
giu.Custom(func(){
|
||||
giu.Row(
|
||||
giu.Custom(func(){
|
||||
if mode!="decrypt"{
|
||||
giu.Row(
|
||||
giu.SmallButton("Generate").OnClick(func(){
|
||||
giu.Button("Generate").OnClick(func(){
|
||||
showGenpass = true
|
||||
}),
|
||||
giu.SmallButton("Copy").OnClick(func(){
|
||||
giu.Tooltip("Use this to generate a cryptographically secure password."),
|
||||
|
||||
giu.Button("Copy").OnClick(func(){
|
||||
clipboard.WriteAll(password)
|
||||
}),
|
||||
giu.Tooltip("Copies the contents of the password field into your clipboard."),
|
||||
).Build()
|
||||
}
|
||||
}),
|
||||
giu.SmallButton("Paste").OnClick(func(){
|
||||
giu.Button("Paste").OnClick(func(){
|
||||
tmp,_ := clipboard.ReadAll()
|
||||
password = tmp
|
||||
cPassword = tmp
|
||||
passwordStrength = zxcvbn.PasswordStrength(password,nil).Score
|
||||
giu.Update()
|
||||
}),
|
||||
giu.SmallButton(passwordStateLabel).OnClick(func(){
|
||||
giu.Tooltip("Paste your clipboard content into the password fields."),
|
||||
|
||||
giu.Button("Clear").OnClick(func(){
|
||||
password = ""
|
||||
cPassword = ""
|
||||
}),
|
||||
giu.Tooltip("Clear both password fields."),
|
||||
|
||||
giu.Button(passwordStateLabel).OnClick(func(){
|
||||
if passwordState==giu.InputTextFlagsPassword{
|
||||
passwordState = giu.InputTextFlagsNone
|
||||
passwordStateLabel = "Hide"
|
||||
|
@ -370,11 +383,10 @@ func startUI(){
|
|||
passwordStateLabel = "Show"
|
||||
}
|
||||
}),
|
||||
).Build()
|
||||
}),
|
||||
giu.Tooltip("Click to toggle the password state."),
|
||||
),
|
||||
giu.Row(
|
||||
giu.InputText(&password).Size(241/dpi).Flags(passwordState).OnChange(func(){
|
||||
giu.InputText(&password).Size(300/dpi).Flags(passwordState).OnChange(func(){
|
||||
passwordStrength = zxcvbn.PasswordStrength(password,nil).Score
|
||||
}),
|
||||
|
||||
|
@ -410,7 +422,7 @@ func startUI(){
|
|||
-1)
|
||||
canvas.PathStroke(col,false,3)
|
||||
}),
|
||||
giu.Dummy(-160,0),
|
||||
giu.Dummy(12,0),
|
||||
giu.Custom(func(){
|
||||
if !(mode=="decrypt"&&!keyfile){
|
||||
giu.Button(keyfileLabel).OnClick(func(){
|
||||
|
@ -428,7 +440,7 @@ func startUI(){
|
|||
if keyfile&&mode=="encrypt"{
|
||||
giu.Button("Clear").OnClick(func(){
|
||||
keyfile = false
|
||||
keyfileLabel = "Use a keyfile"
|
||||
keyfileLabel = "Use keyfile(s)"
|
||||
keyfilePath = ""
|
||||
}).Build()
|
||||
}
|
||||
|
@ -441,7 +453,7 @@ func startUI(){
|
|||
if mode!="decrypt"{
|
||||
giu.Label("Confirm password:").Build()
|
||||
giu.Row(
|
||||
giu.InputText(&cPassword).Size(241/dpi).Flags(passwordState),
|
||||
giu.InputText(&cPassword).Size(300/dpi).Flags(passwordState),
|
||||
giu.Custom(func(){
|
||||
canvas := giu.GetCanvas()
|
||||
pos := giu.GetCursorScreenPos()
|
||||
|
@ -468,7 +480,7 @@ func startUI(){
|
|||
|
||||
// Optional metadata
|
||||
giu.Label(metadataPrompt),
|
||||
giu.InputText(&metadata).Size(-0.0000001),
|
||||
giu.InputText(&metadata).Size(-0.0000001).Flags(metadataState),
|
||||
|
||||
giu.Custom(func(){
|
||||
if mode!=""{
|
||||
|
@ -479,17 +491,30 @@ func startUI(){
|
|||
// Advanced options can be enabled with checkboxes
|
||||
giu.Custom(func(){
|
||||
if mode=="encrypt"{
|
||||
giu.Checkbox("Shred temporary files (can be slow for large files)",&shredTemp).Build()
|
||||
giu.Checkbox("Fast mode (slightly less secure, not as durable)",&fast).Build()
|
||||
giu.Checkbox("Paranoid mode (extremely secure, but slower)",¶noid).Build()
|
||||
giu.Checkbox("Shred temporary files",&shredTemp).Build()
|
||||
giu.Tooltip("Use this to shred temporary zip archives and volumes used by Picocrypt.").Build()
|
||||
|
||||
giu.Checkbox("Use fast mode",&fast).OnChange(func(){
|
||||
paranoid = false
|
||||
}).Build()
|
||||
giu.Tooltip("Uses BLAKE2b instead of SHA3 with less Argon2; faster, but less secure.").Build()
|
||||
|
||||
giu.Checkbox("Use paranoid mode",¶noid).OnChange(func(){
|
||||
fast = false
|
||||
}).Build()
|
||||
giu.Tooltip("Cascades Serpent with XChaCha20 plus high Argon2; highly secure, but slower.").Build()
|
||||
|
||||
giu.Row(
|
||||
giu.Checkbox("Encode with Reed-Solomon to prevent corruption (slow)",&reedsolo),
|
||||
giu.Checkbox("Encode with Reed-Solomon",&reedsolo),
|
||||
giu.Tooltip("Reed-Solomon can detect and fix corrupted data."),
|
||||
giu.Button("?").Size(24,25).OnClick(func(){
|
||||
browser.OpenURL(rsWikipedia)
|
||||
}),
|
||||
).Build()
|
||||
|
||||
giu.Row(
|
||||
giu.Checkbox("Split output into chunks of",&split),
|
||||
giu.Tooltip("Use this to split the output file into chunks."),
|
||||
giu.InputText(&splitSize).Size(50).Flags(giu.InputTextFlagsCharsDecimal).OnChange(func(){
|
||||
if splitSize==""{
|
||||
split = false
|
||||
|
@ -499,9 +524,14 @@ func startUI(){
|
|||
}),
|
||||
giu.Combo("##splitter",splitUnits[splitSelected],splitUnits,&splitSelected).Size(52),
|
||||
).Build()
|
||||
|
||||
giu.Dummy(0,1).Build()
|
||||
}else if mode=="decrypt"{
|
||||
giu.Checkbox("Keep decrypted output even if it's corrupted or modified",&keep).Build()
|
||||
giu.Tooltip("Tells Picocrypt to always keep decrypted outputs.").Build()
|
||||
|
||||
giu.Checkbox("Delete the input file(s) after decryption",&deleteEncrypted).Build()
|
||||
giu.Tooltip("Removes the encrypted Picocrypt volume (and chunks).").Build()
|
||||
giu.Dummy(0,112).Build()
|
||||
}else{
|
||||
giu.Dummy(0,67).Build()
|
||||
|
@ -718,6 +748,7 @@ func startUI(){
|
|||
giu.Label("Patrons:"),
|
||||
giu.Label(" - Frederick Doe"),
|
||||
giu.Label("Donators:"),
|
||||
giu.Label(" - jp26"),
|
||||
giu.Label(" - W.Graham"),
|
||||
giu.Label(" - N. Chin"),
|
||||
giu.Label(" - Manjot"),
|
||||
|
@ -726,6 +757,7 @@ func startUI(){
|
|||
giu.Label("Translators"),
|
||||
giu.Label(" - umitseyhan75 (Turkish)"),
|
||||
giu.Label(" - digitalblossom (German)"),
|
||||
giu.Label(" - maguszeal (Brazilian Portuguese)"),
|
||||
giu.Label("Other"),
|
||||
giu.Label(" - Fuderal for setting up Picocrypt's Discord server"),
|
||||
giu.Label(" - u/greenreddits for constant feedback and support"),
|
||||
|
@ -789,9 +821,11 @@ func onDrop(names []string){
|
|||
|
||||
// Decide if encrypting or decrypting
|
||||
if strings.HasSuffix(names[0],".pcv")||isSplit{
|
||||
var err error
|
||||
mode = "decrypt"
|
||||
inputLabel = name+" (will decrypt)"
|
||||
metadataPrompt = "Metadata (read-only):"
|
||||
metadataState = giu.InputTextFlagsReadOnly
|
||||
|
||||
if isSplit{
|
||||
inputLabel = name+" (will recombine and decrypt)"
|
||||
|
@ -831,8 +865,17 @@ func onDrop(names []string){
|
|||
fin.Seek(0,0)
|
||||
|
||||
// Read metadata and insert into box
|
||||
var err error
|
||||
fin.Read(make([]byte,15))
|
||||
//var err error
|
||||
tmp = make([]byte,15)
|
||||
fin.Read(tmp)
|
||||
tmp,_ = rsDecode(rs5,tmp)
|
||||
if string(tmp)=="v1.14"||string(tmp)=="v1.15"||string(tmp)=="v1.16"{
|
||||
resetUI()
|
||||
_status = "Please use Picocrypt v1.16 to decrypt this file."
|
||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||
fin.Close()
|
||||
return
|
||||
}
|
||||
tmp = make([]byte,15)
|
||||
fin.Read(tmp)
|
||||
tmp,err = rsDecode(rs5,tmp)
|
||||
|
@ -1251,7 +1294,7 @@ func work(){
|
|||
4,
|
||||
32,
|
||||
)[:]
|
||||
}else{
|
||||
}else if paranoid{
|
||||
key = argon2.IDKey(
|
||||
[]byte(password),
|
||||
salt,
|
||||
|
@ -1260,6 +1303,15 @@ func work(){
|
|||
8,
|
||||
32,
|
||||
)[:]
|
||||
}else{
|
||||
key = argon2.IDKey(
|
||||
[]byte(password),
|
||||
salt,
|
||||
4,
|
||||
1048576,
|
||||
4,
|
||||
32,
|
||||
)[:]
|
||||
}
|
||||
|
||||
if !working{
|
||||
|
@ -1632,6 +1684,22 @@ func work(){
|
|||
}
|
||||
}
|
||||
|
||||
if deleteEncrypted{
|
||||
if recombine{
|
||||
total := 0
|
||||
for{
|
||||
_,err := os.Stat(fmt.Sprintf("%s.%d",inputFile,total))
|
||||
if err!=nil{
|
||||
break
|
||||
}
|
||||
os.Remove(fmt.Sprintf("%s.%d",inputFile,total))
|
||||
total++
|
||||
}
|
||||
}else{
|
||||
os.Remove(inputFile)
|
||||
}
|
||||
}
|
||||
|
||||
resetUI()
|
||||
|
||||
// If user chose to keep a corrupted/modified file, let them know
|
||||
|
@ -1958,12 +2026,14 @@ func resetUI(){
|
|||
keyfile = false
|
||||
metadata = ""
|
||||
metadataPrompt = "Metadata (optional):"
|
||||
metadataState = giu.InputTextFlagsNone
|
||||
shredTemp = false
|
||||
keep = false
|
||||
reedsolo = false
|
||||
split = false
|
||||
splitSize = ""
|
||||
fast = false
|
||||
deleteEncrypted = false
|
||||
paranoid = false
|
||||
progress = 0
|
||||
progressInfo = ""
|
||||
|
@ -2020,6 +2090,9 @@ func humanize(seconds int) string{
|
|||
seconds %= 3600
|
||||
minutes := int(math.Floor(float64(seconds)/60))
|
||||
seconds %= 60
|
||||
hours = int(math.Max(float64(hours),0))
|
||||
minutes = int(math.Max(float64(minutes),0))
|
||||
seconds = int(math.Max(float64(seconds),0))
|
||||
return fmt.Sprintf("%02d:%02d:%02d",hours,minutes,seconds)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue