pharo-graphics / Toplo

A widget framework on top of Bloc
MIT License
19 stars 9 forks source link

Typical password-like input field #202

Open tinchodias opened 2 months ago

tinchodias commented 2 months ago

@plantec how do you recommend implementing it?

plantec commented 2 months ago

you ask how to hide the text of the password ?

tinchodias commented 2 months ago

Not hide but replace by an asterisk each character.

El vie, 13 sept 2024 a la(s) 9:58 a.m., Alain Plantec ( @.***) escribió:

you ask how to hide the text of the password ?

— Reply to this email directly, view it on GitHub https://github.com/pharo-graphics/Toplo/issues/202#issuecomment-2348901486, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAXHHKLRINZ6GRAZP3ERJPLZWLOPBAVCNFSM6AAAAABOEEEUU6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNBYHEYDCNBYGY . You are receiving this because you authored the thread.Message ID: @.***>

plantec commented 2 months ago

maybe there is a font for that

Nyan11 commented 1 month ago

If you only change the font, could you copy/paste the password ? If yes, would it make it a security issue ?

tinchodias commented 1 month ago

Both are good points :)

For Morphic backend, that is always a reference implementation, it is a font. See RubTextFieldMorph>>#beEncrypted:

beEncrypted
    encrypted := true.
    self textMorph font: (StrikeFont passwordFontSize: self theme textFont pointSize)

where that font is:

Screenshot 2024-09-27 at 13 05 56

I don't know of an existing analogous way to do it for Bloc.

In Morphic, you CAN copy to clipboard (and paste the entered string).

You can test it with:

m := SpRubTextFieldMorph new.
m encrypted: true.
m openInWindow.

and wrapped in Spec:

text := SpTextInputFieldPresenter new.
text bePassword.
text open.

As a reference in HTML, I tested the password input field in this webpage: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/password on a Macbook, in Chrome, Firefox and Safari. In all cases, the CMD+c was ignored. This should be possible to implement. In Morphic, by avoiding the execution of RubTextEditor>>#copySelection when the shortcut is pressed, or when menu item pressed on context menu.

plantec commented 1 month ago

security ? ok disabling the shortcut can be done easily and it is mandatory to do it for a password textfield. but it will very easy to hack any image with a script that catch the passwd textfield content ☺️

tinchodias commented 1 month ago

Ok! I'd be nice to disable the copy shortcut (not paste!). In an image with IDE tools disabled, the password will be safe from user point of view.

El sáb, 28 sept 2024 a la(s) 6:06 a.m., Alain Plantec ( @.***) escribió:

security ? ok disabling the shortcut can be done easily and it is mandatory to do it for a password textfield. but it will very easy to hack any image with a script that catch the passwd textfield content ☺️

— Reply to this email directly, view it on GitHub https://github.com/pharo-graphics/Toplo/issues/202#issuecomment-2380575336, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAXHHKNRMHZWQVVZ6UDGPUDZYZWRXAVCNFSM6AAAAABOEEEUU6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOBQGU3TKMZTGY . You are receiving this because you authored the thread.Message ID: @.***>

plantec commented 1 month ago

@tinchodias would you introduce a ToPasswordTextField class ?

tinchodias commented 1 week ago

I did some steps on a prototype that handles events on text changing, and stores in an instvar the entered characters but replaces the text in the field with asterisks.

tinchodias commented 1 week ago

Thanks Alain @plantec for your help. For the record, this is a script that converts a text field as a password field:

| filterField |
filterField := ToTextField new withoutLineBreak.
filterField userData at: #input put: filterField text copy.

filterField addEventHandlerOn: AlbTextInsertedEvent do: [ :evt |
    | cursorPosition |
    (filterField userData at: #input)
        insertText: evt text at: evt index.
    cursorPosition := evt target cursor position.
    evt target selecter all; apply.
    evt target inserter
        atEnd;
        string: (String new: evt target text size withAll: $*);
        apply.
    evt target cursor position: cursorPosition ].

filterField addEventHandlerOn: AlbTextDeletedEvent do: [ :evt |
    | cursorPosition |
    (filterField userData at: #input)
        delete: evt fromIndex to: evt toIndex.
    evt target selecter all; apply.
    evt target inserter
        atEnd;
        string: (String new: evt target text size withAll: $*);
        apply.
    evt target cursor position: evt fromIndex - 1 ].

filterField addEventHandlerOn: AlbTextReplacedEvent do: [ :evt |
    (filterField userData at: #input)
        deleteAll;
        insertText: evt text at: 0.
    evt target selecter all; apply.
    evt target inserter
        atEnd;
        string: (String new: evt target text size withAll: $*);
        apply ].

filterField addEditorShortcut: (BlShortcutWithAction new
         combination: BlKeyCombination return;
         action: [ :event | (filterField userData at: #input) traceCr ];
         yourself).

filterField openInSpace

Press enter to see the current password on Transcript.

This works:

tinchodias commented 1 week ago

I encapsulated that code into a custom handler... not sure if I do a PR like this or polish it more...

tinchodias commented 1 week ago

For the moment, it's all in this fileout. It includes an example on class-side.

ToPasswordFieldEventHandler.st.zip

tinchodias commented 1 week ago

Another version with a fix (it has another class name): SpToploPasswordFieldEventHandler.st.zip