So here’s my clunky version of a password getter that lets you set a minimum password length and lets you require or forbid upper/lower/special characters! It also retains the initial password typed so that, if the user switches to/from bullets the password is preserved so they don’t have to type again.
PromptUserForPassword("test")
on PromptUserForPassword(theTitle)
script o
property MinLength : 1
property CharSet : {{name:"lower case", forbidden:false, required:false, Chars:"aäáà âãåăąæbcçćÄdÄÄ‘eéèêëěęfghiÃìîïjklĺľłmnñńňoöóòôõőøpqrÅ•Å™sÅŸÅ¡Å›tťţuüúùûůűvwxyýzžźżþ"}, ¬
{name:"upper case", forbidden:false, required:false, Chars:"AÄÃÀÂÃÅĂĄÆBCÇĆČDÄŽÄEÉÈÊËĚĘFGHIÃÌÎÃJKLĹĽÅMNÑŃŇOÖÓÒÔÕÅØPQRŔŘSŞŠŚTŤŢUÜÚÙÛŮŰVWXYÃZŽŹŻÞ"}, ¬
{name:"special", forbidden:false, required:false, Chars:"!@#$%^&*()-=_+[]{}/\\,.≠?'`;:"}}
on prmpt(msg, promptTitle, defaultAns, ButtonList, UseBullets)
if (count ButtonList) > 2 then
set {NumRequired, NumForbidden} to {0, 0}
repeat with c in CharSet
set {NumRequired, NumForbidden} to {NumRequired + (c's required as integer), NumForbidden + (c's forbidden as integer)}
end repeat
if NumRequired > 0 then
set msg to msg & return & "(Needs at least 1 "
set i to 1
repeat with c in CharSet
if c's required then
set msg to msg & c's name
if i < NumRequired then
set msg to msg & ", "
else
set msg to msg & " character)"
end if
set i to i + 1
end if
end repeat
end if
if NumForbidden > 0 then
set msg to msg & return & "(Don't use "
set i to 1
repeat with c in CharSet
if c's forbidden then
set msg to msg & c's name
if i < NumForbidden - 1 then
set msg to msg & ", "
else if i < NumForbidden then
set msg to msg & " or "
end if
set i to i + 1
end if
end repeat
set msg to msg & " characters)"
end if
end if
return (display dialog msg with title promptTitle default answer defaultAns buttons ButtonList cancel button 1 default button "OK" hidden answer UseBullets with icon caution)
end prmpt
on passOK(ThePass)
local RequiredOK
if (count ThePass) is 0 then
return {false, "Empty string entered!"}
else if (count ThePass) < MinLength then
return {false, "Please enter at least " & MinLength & " characters."}
else
set RequiredOK to {}
repeat with c in CharSet
set end of RequiredOK to not c's required
if c's required or c's forbidden then
repeat with pc in (ThePass as string)
if c's required and not (end of RequiredOK) and pc is in c's Chars then set RequiredOK's item (count RequiredOK) to true
if c's forbidden and pc is in c's Chars then return {false, "Password cannot contain " & c's name & " characters!"}
end repeat
end if
end repeat
repeat with i from 1 to count RequiredOK
if not (item i of RequiredOK) then return {false, "Password requires at least 1 " & name of (CharSet's item i) & " character!"}
end repeat
end if
return {true}
end passOK
end script
set UseBullets to true
set ButtonList to {"Cancel", "Show Password", "OK"}
set Pass1 to ""
repeat
try
set {Pass1, TheButton} to {text returned, button returned} of o's prmpt("Please enter password:", theTitle, Pass1, ButtonList, UseBullets)
if (TheButton is "OK") then
considering case
set PassCheck to o's passOK(Pass1)
if not beginning of PassCheck then
display alert ((end of PassCheck) as string) as warning
else if ((not UseBullets) or (text returned of o's prmpt("Please re-enter password:", theTitle, "", {"Cancel", "OK"}, UseBullets) is Pass1)) then
return Pass1
else
display alert "Passwords do not match!" as warning
set Pass1 to ""
end if
end considering
else
set UseBullets to (not UseBullets)
set item 2 of ButtonList to item ((UseBullets as integer) + 1) of {"Hide Password", "Show Password"}
end if
on error
return false
end try
end repeat
end PromptUserForPassword