# Name Mail:Alias::LocalFile Resolve email aliases from a locally maintained aliases file in addition to the system-wide aliases file # Version version 0.01 # Synopsis ``` use Mail::Alias::LocalFile; my $resolver = Mail::Alias::LocalFile->new(aliases => $aliases); my $result = $resolver->resolve_recipients($intended_recipients); my $recipients = $result->{recipients}; my $warning = $result->{warning}; - $aliases is a hashref of a local aliases file - $intended_recipients is a list or arrayref of addressees (i.e. mary@example.com, joe, group2) - $recipients is the comma separated list of email addressees needed by you email client code - $warning identifies problems encountered (if any) See below and use perldoc LocalFile.pm for additional documentation ``` # Description This module allows the use of a locally maintained aliases file in addition to the aliases file provided by the Mail Transfer Agent (MTA). This module reduces dependence on the system wide MTA aliases file. You can avoid the use of the system aliases entirely or you can use some of them to supplement your local maintained aliases. This module is useful when you want to maintain your own email aliases file, with limited use of the system wide aliases file. The type of local file holding the alias definitions is up to your application. File types such as JSON, YAML, XML, INI and many others could be used, provided the file loads an appropriately structured hashref. # Rational This module allows the use of a locally maintained aliases file in addition to using the aliases file used by the MTA. This is beneficial for several reasons: - The MTA aliases file may not be available to you because editing it is restricted by corporate policy - The MTA aliases file is shared and you want to avoid conflicting alias names already in use by others - The MTA is being edited by persons not affliated with your application and their actions could affect your emails - You want control of your own aliases in a file not availble to others but also have access to system aliases when needed # Input In your application, create a new resolver object - using Moo style named parameters - my $resolver = Mail::Alias::LocalFile->new(aliases => $aliases); Where inputs are: - $aliases is a hash_ref of key/value pairs holding the entire contents of your locally maintained aliases file # Output - my $result = $resolver->resolve_recipients($intended_recipients); - $intended_recipients is an array_ref holding the email addressses and aliases of the intended email recipients - Where $result is a hash_ref as shown below: ``` my $recipients = $result->{recipients}; my $warning = $result->{warning}; my $alias_file_contents = $result->{aliases}; my $original_input = $result->{original_input}; my $processed_aliases = $result->{processed_aliases}; my $uniq_email_addresses = $result->{uniq_email_addresses}; my $expanded_addresses = $result->{expanded_addresses}; ``` Output includes all of the following to use as desired: - $recipients is the desired email aliases expansion like "john\@company.com,joe\@example.com,mary\@example.com" - $warnings is an array_ref holding issues encountered, like a malformed email address or misspelled alias - $alias_file_contents is the entire contents of the local alias file, possibly for troubleshooting - $original_input is an array_ref holding the $intended_recipients, for troubleshooting - $processed_aliases is a hash_ref identifying each alias that was expanded to email addresses, for troubleshooting - $expanded_addresses is an array_ref built as each alias is expanded, which can include duplicate email addresses - $uniq_email_addresses is an array_ref like $expanded_addresses but with the duplicates (if any) removed $recipients is the same content as $uniq_email_addresses, except it is held as the comma separated string most likely desired by your email code # Dependencies ``` The Mail::Alias::LocalFile.pm package uses: - use Moo; - use namespace::autoclean; - use Email::Valid; - use Scalar::Util qw(reftype); - use Types::Standard qw(ArrayRef HashRef Str); ``` This module is NOT dependent on the (excellent) Mail::Alias module. Mail::Alias is designed to read, write, update and convert between the Sendmail, Ucbmail and Binmail MTA alias file formats. This module has a diffferent purpose, which is to avoid reliance on the MTA alias file entirely or just to the extent desired. # INSTALLATION ``` To install this module: perl Makefile.PL make make test make install ``` # Assumptions: - The application can load a locally maintained aliases configuration file - The aliases file can use any practical format such as YAML, JSON, XML, INI or similar - When the entire aliases file is loaded, the data is held in a Perl hash reference - Each hash key is the name of an alias - The values, when loaded, are seen as strings or arrays. (Hashes are not supported as values) - Values are combinations of one or more email addresses and alias names, just as is customary in the MTA system aliases file - The script or application, when sending outbound email, expects recipients to be a comma separated list of email addresses, ie joe\@example.com,mary\@company.com,mike\@sample.com # Sample Aliases Files: Sample configuration files (YAML and JSON formatted) are provided as examples of locally maintained aliases files that load as a hash_ref containing acceptable keys and values. They intentionally use various (unlikely) types of comma and space separation to demonstrate the flexibility allowed in value formatting. They hold examples of the 'mta_' prefix used to include aliases from the system MTA aliases file. Some sample files intentionally contain circular references for aliases, for illustrative purposes. Sample scripts are included to demonstrate usage and capabilities. Use perldoc for POD descriptions. # Limitations and Applicability - This module converts aliases to email addresses using a local file you manually edit and maintain. The more complex capabilities of a MTA system wide aliases file (such as sending email to files or passing through pipes) still require the use of that file. When needed, those capabilities can be accessed from entries in your local file. - This module resolves email addresses from aliases from the hash_ref provided when you load your local aliases file. It does not create or update the file. You edit your local file manually, just like the system mail aliases file. - YAML and JASON formatted sample alias files are provides because they have an easy to maintain layout. However, you can use any format you like as long as it can be loaded as a hash reference that contains keys with values that load as strings or arrays. # Regular aliases and mta_ prefix aliases - **Regular aliases** Just like in the system aliases file, values in the local alias file can consist of one or more email addresses and locally defined aliases representing email addresses. Locally defined aliases listed as values are expanded without the use of the system aliases file. For example, an alias named 'sales' is expanded to the email addresses assigned to the 'sales' alias defined in the local aliases file. If there is also a sales alias defined in the system aliases file, it is not used. Except as described for the mta_ prefix, the local alias definition supersedes the system file definition. - **mta_ prefixes** The 'mta_' prefix is used within a local alias file **value** to allow aliases to be expanded by the MTA instead of being expanded locally. For example, assume a **value** in the local aliases file hold alias 'mta_sales'. This module recognizes the 'mta_' prefix, removes the prefix, and allows the remainder (in this case sales) to pass through for eventual expansion by the MTA using the system aliases file. 'mta_' prefixed aliases can be used in conjunction with the local file aliases. Assume the sales alias in the system file includes two email addresses for senior managers joe and mary: sales: joe@hq.company.com, mary@hq.company.com (In the system aliases file) The local alias file could hold this entry: sales: billy@local.company.com, mta_sales **(Important: mta_ prefixes are never used as local alias file keys, only within values)** The module would expand the local alias (picking up billy\@local.company.com as a recipient) and strip the prefix from mta_sales. The 'To: ' section of your email header would receive 'billy\@local.company.com,sales'. When the email is processed by the MTA, sales is expanded using the system aliases file to include joe and mary's email addresses. The three recipients become 'billy\@local.company.com,joe\@hq.company.com,mary\@hq.company.com' To send email to a local user mail account on the server, create an alias for the username in the local aliases file and assign a value that uses the mta_ prefix. For a user with login name INC0027 the YAML formatted local aliases file entry could be: INC0027: mta_INC0027 The 'mta_' prefix can also be used to take advantage of advanced aliasing features not supported by the local aliases file, such as appending email to files, or using pipes to execute commands. As long as the alias is defined in the system aliases file, the local alias file can use a corresponding mta_ prefix to incorporate it. The 'mta_' prefix cannot be used as prefix to a key in the local aliases. Its use is restricted to inclusion as part of a value. In the local aliases file: mta_postmaster: postmaster (**NOT ALLOWED**. The mta_ prefix cannot be used as a local alias key) postmaster: mta_postmaster (Correct. Becomes 'postmaster as seen by the system file) # Functionality: Methods are described within the POD. (perldoc LocalFile.pm) Method provided functionality includes: - Malformed email addresses are skipped - References to non-existent aliases are skipped - Each alias is only expanded once, so circular references are tolerated by suppression. - Warnings messages when encountering the above issues are captured - Duplicated email recipients are removed - Basic email address format validity is determined through Email::Valid->address - Converts all email addresses to lower case lettering - Utilizes the system wide MTA aliases file when the 'mta_' prefix is attached to a value in the local aliases file # Detect and report circular references LocalFile.pm is generally tolerant of circular alias references within the local aliases file. An attempt is made to avoid a loop by only expanding each alias once. Nevertheless, good practice necessitates removing circular references whenever possible. Screen for circular references in the local aliases file is follows: ``` $resolver = Mail::Alias::LocalFile->new(aliases => $aliases); @circular_refs = $resolver->detect_circular_references($aliases); if ($circular_refs[0]) { print "WARNING: Circular references detected:\n"; foreach my $circ_ref_item (@circular_refs) { print " $circ_ref_item\n"; } } ``` # Issues - https://github.com/usna78/Mail-Alias-LocalFile/issues # Copyright Copyright 2025, Dwight R. Brewer (Russ), All Rights Reserved # LICENSE GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999. See included LICENSE file. # Author Russ Brewer