Captcha-reCAPTCHA-Mailhide

 view release on metacpan or  search on metacpan

lib/Captcha/reCAPTCHA/Mailhide.pm  view on Meta::CPAN

package Captcha::reCAPTCHA::Mailhide;

use warnings;
use strict;
use Carp;
use Crypt::Rijndael;
use MIME::Base64;
use HTML::Tiny;

our $VERSION = '0.94';

use constant API_MAILHIDE_SERVER =>
 'http://www.google.com/recaptcha/mailhide';

sub new {
  my $class = shift;
  my $self = bless {}, $class;
  croak "new takes no parameters" if @_;
  return $self;
}

sub _aes_encrypt {
  my ( $val, $ky ) = @_;

  my $val_len = length( $val );
  my $pad_len = int( ( $val_len + 15 ) / 16 ) * 16;

  # Pad value
  $val .= chr( 16 - $val_len % 16 ) x ( $pad_len - $val_len )
   if $val_len < $pad_len;

  my $cipher = Crypt::Rijndael->new( $ky, Crypt::Rijndael::MODE_CBC );
  $cipher->set_iv( "\0" x 16 );

  return $cipher->encrypt( $val );
}

sub _urlbase64 {
  my $str = shift;
  chomp( my $enc = encode_base64( $str ) );
  $enc =~ tr{+/}{-_};
  return $enc;
}

sub mailhide_url {
  my $self = shift;
  my ( $pubkey, $privkey, $email ) = @_;

  croak
   "To use reCAPTCHA::Mailhide, you have to sign up for a public and "
   . "private key. You can do so at http://www.google.com/recaptcha/mailhide/apikey."
   unless $pubkey && $privkey;

  croak "You must supply an email address"
   unless $email;

  my $h = HTML::Tiny->new();

  return
   API_MAILHIDE_SERVER . '/d?'
   . $h->query_encode(
    {
      k => $pubkey,
      c => _urlbase64( _aes_encrypt( $email, pack( 'H*', $privkey ) ) )
    }
   );
}

sub _email_parts {
  my ( $user, $dom ) = split( /\@/, shift, 2 );
  my $ul = length( $user );
  return ( substr( $user, 0, $ul <= 4 ? 1 : $ul <= 6 ? 3 : 4 ),
    '...', '@', $dom );
}

sub mailhide_html {
  my $self = shift;
  my ( $pubkey, $privkey, $email ) = @_;

  my $h = HTML::Tiny->new();

  my $url = $self->mailhide_url( $pubkey, $privkey, $email );
  my ( $user, $dots, $at, $dom ) = _email_parts( $email );

  my %window_options = (
    toolbar    => 0,
    scrollbars => 0,
    location   => 0,
    statusbar  => 0,
    menubar    => 0,
    resizable  => 0,
    width      => 500,



( run in 0.743 second using v1.01-cache-2.11-cpan-df04353d9ac )