package Config::ClawsMail::Account;
use v5.26;
use Moo;
use Types::Standard qw(Str InstanceOf);
use Config::ClawsMail::Server;
use namespace::clean;
has [qw(account_name name address organization)] => (
is => 'ro',
required => 1,
isa => Str,
);
has [qw(imap smtp)] => (
is => 'ro',
isa => InstanceOf['Config::ClawsMail::Server'],
);
my @ssl_string=qw(no ssl starttls);
my %imap_auth_method = (
1 => 'plaintext',
2 => 'CRAM_MD5',
4 => 'ANONYMOUS',
8 => 'GSSAPI',
16 => 'DIGEST_MD5',
32 => 'SCRAM_SHA1',
64 => 'PLAIN',
128 => 'LOGIN',
256 => 'XOAUTH2',
512 => 'SCRAM_SHA224',
1024 => 'SCRAM_SHA256',
2048 => 'SCRAM_SHA384',
4096 => 'SCRAM_SHA512',
);
my %smtp_auth_method = (
1 => 'LOGIN',
2 => 'CRAM_MD5',
4 => 'DIGEST_MD5',
8 => 'tls_available',
16 => 'PLAIN',
32 => 'XOAUTH2',
);
sub _expand_bitfield {
my ($bits, $map) = @_;
my @result;
for my $key (sort { $a <=> $b } keys %$map) {
if ($bits & $key) {
push @result, $map->{$key};
}
}
return \@result;
}
sub new_from_config {
my ($class,$args) = @_;
my $config = $args->{account_config};
return unless $config->{protocol} eq '1';
my $section = $args->{account_section};
(my $password_section = $section)=~ s{Account: }{account:};
my $password_store = $args->{password_store};
my $imap_server = Config::ClawsMail::Server->new({
host => $config->{receive_server},
port => (
$config->{set_imapport}
? $config->{imap_port}
: $config->{ssl_imap} == 1
? scalar getservbyname('imaps','tcp')
: scalar getservbyname('imap','tcp')
),
ssl => $ssl_string[$config->{ssl_imap}],
%{$config}{qw(user_id)},
password => $password_store->password_for($password_section,'recv'),
auth_methods => _expand_bitfield($config->{imap_auth_method},\%imap_auth_method),
});
my $smtp_server = Config::ClawsMail::Server->new({
host => $config->{smtp_server}||$config->{receive_server},
port => (
$config->{set_smtpport}
? $config->{smtp_port}
: $config->{ssl_smtp} == 1
? scalar getservbyname('smtps','tcp')
: scalar getservbyname('smtp','tcp')
),
ssl => $ssl_string[$config->{ssl_smtp}],
( $config->{use_smtp_auth} ? (
user_id => $config->{smtp_user_id} || $config->{user_id},
password => $password_store->password_for($password_section,'send') || $password_store->password_for($password_section,'recv'),
auth_methods => _expand_bitfield($config->{smtp_auth_method},\%smtp_auth_method),
) : () ),
});
return $class->new({
%{$config}{qw(account_name name address organization)},
imap => $imap_server,
smtp => $smtp_server,
});
}
sub email_transport {
my ($self) = @_;
require Email::Sender::Transport::SMTP;
my $smtp = $self->smtp;
return Email::Sender::Transport::SMTP->new(
host => $smtp->host,
port => $smtp->port,
ssl => $smtp->ssl,
( $smtp->user_id ? (
sasl_username => $smtp->user_id,
sasl_password => $smtp->password,
) : () )
);
}
1;