App-Greple-pw

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

      - Created 18 tests covering basic functionality, configuration, and options
      - Test runner integration using git submodules
      
    - Enhanced documentation and user experience
      - Improved module description: "Interactive password and ID information extractor"
      - Added structured Key Features section highlighting security and usability
      - Comprehensive configuration examples and browser integration documentation
      - Hidden internal functions from user-facing documentation
      
    - Bug fixes and code improvements
      - Fixed critical clipboard assignment vs comparison bug (= to eq)
      - Fixed browser variable typo ($brouse to $browser) 
      - Improved option naming consistency (underscores vs hyphens)
      - Added proper data encapsulation for PwBlock parameter management

1.00 2025-07-25T02:50:55Z

    - original version

README.md  view on Meta::CPAN


The **pw** module is a **greple** extension that provides secure, interactive
handling of sensitive information such as passwords, user IDs, and account
details found in text files. It is designed with security in mind, ensuring
that sensitive data doesn't remain visible on screen or in terminal history.

## Key Features

- **Interactive password handling**

    Passwords are masked by default and can be safely copied to clipboard
    without displaying the actual content on screen.

- **Secure cleanup**

    Terminal scroll buffer and screen are automatically cleared when the
    command exits, and clipboard content is replaced with a harmless string
    to prevent sensitive information from persisting.

- **Encrypted file support**

    Seamlessly works with PGP encrypted files using **greple**'s standard
    features. Files with "_.gpg_" extension are automatically decrypted,
    and the **--pgp** option allows entering the passphrase once for
    multiple files.

- **Intelligent pattern recognition**

README.md  view on Meta::CPAN

            greple -Mpw --config clear_screen=0 --config debug=1 --

    - Direct command-line options

        Many parameters have direct command-line equivalents:

            greple -Mpw --no-clear-screen --debug --browser=safari --

    Currently following configuration options are available:

        clear_clipboard
        clear_string
        clear_screen
        clear_buffer
        goto_home
        browser
        timeout
        debug
        parse_matrix
        parse_id
        parse_pw

lib/App/Greple/pw.pm  view on Meta::CPAN

handling of sensitive information such as passwords, user IDs, and account
details found in text files. It is designed with security in mind, ensuring
that sensitive data doesn't remain visible on screen or in terminal history.

=head2 Key Features

=over 4

=item * B<Interactive password handling>

Passwords are masked by default and can be safely copied to clipboard
without displaying the actual content on screen.

=item * B<Secure cleanup>

Terminal scroll buffer and screen are automatically cleared when the
command exits, and clipboard content is replaced with a harmless string
to prevent sensitive information from persisting.

=item * B<Encrypted file support>

Seamlessly works with PGP encrypted files using B<greple>'s standard
features. Files with "I<.gpg>" extension are automatically decrypted,
and the B<--pgp> option allows entering the passphrase once for
multiple files.

=item * B<Intelligent pattern recognition>

lib/App/Greple/pw.pm  view on Meta::CPAN

=item Direct command-line options

Many parameters have direct command-line equivalents:

    greple -Mpw --no-clear-screen --debug --browser=safari --

=back

Currently following configuration options are available:

    clear_clipboard
    clear_string
    clear_screen
    clear_buffer
    goto_home
    browser
    timeout
    debug
    parse_matrix
    parse_id
    parse_pw

lib/App/Greple/pw.pm  view on Meta::CPAN

use Carp;
use Data::Dumper;
use App::Greple::Common;
use App::Greple::PwBlock;
use Getopt::EX::Config qw(config);

my $execution = 0;

# Getopt::EX::Config support
my $config = Getopt::EX::Config->new(
    clear_clipboard => 1,
    clear_string    => 'Hasta la vista.',
    clear_screen    => 1,
    clear_buffer    => 1,
    goto_home       => 0,
    browser         => 'chrome',
    timeout         => 300,
    debug           => 0,
    # PwBlock parameters - direct references to PwBlock config members
    parse_matrix    => \$App::Greple::PwBlock::config->{parse_matrix},
    parse_id        => \$App::Greple::PwBlock::config->{parse_id},

lib/App/Greple/pw.pm  view on Meta::CPAN

    pw_chars        => \$App::Greple::PwBlock::config->{pw_chars},
    pw_color        => \$App::Greple::PwBlock::config->{pw_color},
    pw_label_color  => \$App::Greple::PwBlock::config->{pw_label_color},
    pw_blackout     => \$App::Greple::PwBlock::config->{pw_blackout},
);

sub finalize {
    our($mod, $argv) = @_;
    $config->deal_with(
	$argv,
	"clear_clipboard|clear-clipboard!",
	"clear_string|clear-string=s",
	"clear_screen|clear-screen!",
	"clear_buffer|clear-buffer!",
	"goto_home|goto-home!",
	"browser=s",
	"timeout=i",
	"debug!",
	# PwBlock parameters - underscore and hyphen versions
	"parse_matrix|parse-matrix!",
	"parse_id|parse-id!",

lib/App/Greple/pw.pm  view on Meta::CPAN

    command_loop($pw) or do { pw_epilogue(); exit };

    return '';
}


use constant { CSI => "\e[" };

sub pw_epilogue {
    $execution == 0 and return;
    copy(config('clear_string')) if config('clear_clipboard');
    print STDERR CSI, "H" if config('goto_home');
    print STDERR CSI, "2J" if config('clear_screen');
    print STDERR CSI, "3J" if config('clear_buffer');
}

sub pw_timeout {
    if (config('debug')) {
	warn "pw_timeout() called.\n";
	sleep 1;
    }

lib/App/Greple/pw.pm  view on Meta::CPAN

	    alarm config('timeout');
	    warn "Set timeout to ", config('timeout'), " seconds\n" if config('debug');
	}
	/\S/ or next;
	$term->addhistory($_);
	s/\s+\z//;
	$_ = kana2alpha($_);

	if (my $id = $pw->id($_)) {
	    if (copy($id)) {
		printf "ID [%s] was copied to clipboard.\n", $id;
	    }
	    next;
	}
	elsif (my $pass = $pw->pw($_)) {
	    if (copy($pass)) {
		printf "Password [%s] was copied to clipboard.\n", $_;
	    }
	    next;
	}

	if (0) {}
	elsif (/^dump\b/)  { print Dumper $pw }
	elsif (/^N/i) { last }
	elsif (/^P/i) { print $pw->masked }
	elsif (/^Q/i) { return 0 }
	elsif (/^V/i) {

lib/App/Greple/pw.pm  view on Meta::CPAN

    ア => 'A', イ => 'B', ウ => 'C', エ => 'D', オ => 'E',
    カ => 'F', キ => 'G', ク => 'H', ケ => 'I', コ => 'J',
    );

sub kana2alpha {
    local $_ = shift;
    s/([アイウエオカキクケコ])/$kana2alpha{$1}/g;
    $_;
}

my $clipboard;
BEGIN {
    eval "use Clipboard";
    if (not $@) {
	$clipboard = "Clipboard";
    }
    elsif (-x "/usr/bin/pbcopy") {
	$clipboard = "pbcopy";
    }
    else {
	warn("==========================================\n",
	     "Clipboard is not available on this system.\n",
	     "Install Clipboard module from CPAN.\n",
	     "==========================================\n");
    }
}

sub copy {
    my $text = shift;
    if (not $clipboard) {
	warn "Clipboard is not available.\n";
	return undef;
    }
    elsif ($clipboard eq "Clipboard") {
	Clipboard->copy($text);
    }
    elsif ($clipboard eq "pbcopy") {
	dumpto($clipboard, $text);
    }
    1;
}

sub dumpto {
    my $command = shift;
    my $text = shift;
    open COM, "| $command" or die "$command: $!\n";
    print COM $text;
    close COM;

t/02_config.t  view on Meta::CPAN


# Module config syntax (::config=) cannot be tested with current Util.pm design
# pw() function adds arguments after '-Mpw', but ::config= needs to be part of module name
# This would require: greple -Mpw::config=debug=1 (not: greple -Mpw ::config=debug=1)

# Test multiple config parameters
my $multi_config_result = pw(qw(--config clear_screen=0 --config debug=1 -- -c User))->setstdin($test_data)->run;
is($multi_config_result->{result} >> 8, 0, "multiple config parameters work");

# Test boolean config parameters
my $bool_result = pw(qw(--config clear_clipboard=0 -- -c User))->setstdin($test_data)->run;
is($bool_result->{result} >> 8, 0, "boolean config parameter works");

# Test string config parameters
my $string_result = pw(qw(--config browser=firefox -- -c User))->setstdin($test_data)->run;
is($string_result->{result} >> 8, 0, "string config parameter works");

done_testing;



( run in 2.294 seconds using v1.01-cache-2.11-cpan-2398b32b56e )