Set column to read-only but only in some cases

Set column to read-only but only in some cases

matschematsche Posts: 14Questions: 6Answers: 0
edited September 2019 in Free community support

One of my columns is a password column. The user should not see the passwords in plain text. So i added a simple getFormatter to hide the passwords.

Field::inst( 'password' )
    ->getFormatter( function ( $val, $data ) {
        // convert password to ***
        // example: 'secret'    -> '******'
        // example: 'secret123' -> '*********'
        return empty($val) ? '' : str_repeat('*', strlen($val));
    } )

This is working fine but when an user edit another column value (not the password value) than the password will be set to ***
My idea is: If no new password has been set ($val contains only * or is empty) then the password column should be set to read-only.

Field::inst( 'password' )
    ->setFormatter( function ( $val, $data ) {
        if(preg_match('/[^\*]/', $val) && !empty($val)) {
            return $val;
        } else {
            // Set password column to read-only
            // Field::inst( 'password' )->set( false );
            return '';
        }
    } )

Unfortunately this is not working. Can someone help me?

This question has an accepted answers - jump to answer

Answers

  • colincolin Posts: 15,142Questions: 1Answers: 2,586

    Hi @matsche ,

    Have you seen the password? This is likely doing what you want.

    Cheers,

    Colin

  • matschematsche Posts: 14Questions: 6Answers: 0

    Hi @colin ,

    password is only working within the editor. The normal datatables view still shows the password in plain text.
    When i am only using your suggestion, all passwords will be synced (between client and server api) in plain text. If an user is using the webbrowser developer possibilities, he can read out every password. With my solution, only '***' (with an individual length) will be synced. Only when the user is changing the password (or set new password) the actual password will be synced in plain text.

    Field::inst( 'password' )
        ->setFormatter( function ( $val, $data ) {
            if(...) {
                // Set password column to read-only
                // Field::inst( 'password' )->set( false );
                return '';
            }
        } )
    

    How do I have to call the field().set() ? Or is there another pretty solution?

  • allanallan Posts: 61,642Questions: 1Answers: 10,093 Site admin
    edited September 2019 Answer ✓

    The normal datatables view still shows the password in plain text.

    Haha :). Add ->get( false ) to the Field() chain in the server-side script. Have a look at this post to see a little example of that.

    Also, you really really want to not store your passwords in plain text! Use a getFormatter to hash them - since you are using PHP, use the password_hash function.

    Allan

  • matschematsche Posts: 14Questions: 6Answers: 0

    Thanks Allen, it is working :)

    For users which have the same issue like me:

    $api = new Editor( $db, $db_table );
    $api->fields(Field::inst( 'password' )
            ->getFormatter( function ( $val, $data ) {
                // convert password to ***
                // example: 'secret' -> '******'
                return empty($val) ? '' : str_repeat('*', strlen($val));
            } )
    );
    
    $api->on( 'preEdit', function ( $editor, $id, $values ) use ( $api ) {
        if(!empty($values['password']) && preg_match('/[\*]/', $values['password'])) {
            $api->field('password')->set( false ); // Do not save the user input to database
        }
    });
    
This discussion has been closed.