[Rt-commit] rt branch, 4.4-trunk, updated. rt-4.4.1-201-gcb9c3d6

Shawn Moore shawn at bestpractical.com
Tue Dec 27 13:32:46 EST 2016


The branch, 4.4-trunk has been updated
       via  cb9c3d6210d338353d6ae30a541564b739c727ec (commit)
       via  2171a89ff9a083838e2eec6bc25dba655e5c39ec (commit)
       via  398ec1b9a1b86ad5d66c209dec07825ab95648dd (commit)
       via  988f7133a9a6de15956ae006648512b4f4be5dc1 (commit)
       via  a3e11d047dc6cfa5c5c9e5b9dd48f68e11a4b91a (commit)
       via  d9feec6fa4685efc9b229e3e5e7f314d41e45df9 (commit)
       via  f1c247a2b029d15cc9b6fc738d5a2b645b6aff86 (commit)
       via  a24f4358480d8665b985f9ccddbec2d1cb724388 (commit)
       via  a0f38800f21edbaed3e6a5e29a6a0ecaa6978c37 (commit)
       via  43aa03582cddc23aee38a52a4aeacf042766176e (commit)
       via  c9774928c6da3757b266e305a2794f0b4122ac47 (commit)
       via  99c08c1141c9a38cb727073d70d95d92243df1ef (commit)
       via  18cc75db4638cb9b7e6117217f5ee9d4a945fdf9 (commit)
       via  cbd5ed469f41db880ad041c56e547f5a8fb4a95d (commit)
       via  05ddb1844560bc8153e9ccf52e7956c506fc33c7 (commit)
       via  d6cdacb638315ae2772ba97d0c5894e9daa22e6d (commit)
       via  fd91b5b5c37af455414b96b05241a6183ff79d48 (commit)
       via  b00a27fdb942e033bc6eaa83cac228298da425c0 (commit)
       via  3da2bf2868ff72f5e13b19eba4f02eb8f5a85f70 (commit)
       via  fb4bdf2d6fe2742fe1c510af7446e1dd6b888e92 (commit)
       via  40d289bbc0b41ceadecc50e4b2a50d5c7be96432 (commit)
       via  bdd6bd96ece4faebb5a067bdd787b8e2e4fec755 (commit)
       via  8cd8411090e783a460d84a4725e7f33a81145d2f (commit)
       via  9b4705611e637604a3c00b7c3f036196928c581f (commit)
       via  69474c481897f655239467077976fbdc11b6879d (commit)
       via  b34993b69bbb8480f2759950a926995b0fae7aed (commit)
       via  1e3010c6bffdbf4923edf0cdc439fba39655acc0 (commit)
       via  f815e22ff4861eadeb77a0eca9faccb761ee465f (commit)
       via  14c420dc448fadbf97d925928f70ab3f006edca3 (commit)
       via  434613b4a64a43edce7fd825720b063633f769c1 (commit)
       via  542ffc5412bf8293c67420a7801a66e7868d77d9 (commit)
       via  51f6226fa546f6e67f190977bd7d6981763f62c7 (commit)
       via  4ed0f4e647d4d1243c7aa3d1da649ae57d36b98c (commit)
       via  7bdd183b11be1b24d137115454d6de55818de42e (commit)
       via  a3988c716512dbc11da5dc48cb5affcfc8b10ca6 (commit)
       via  e56326444ffaa560926610c52c8391cbc21196ea (commit)
       via  d82a3f9b49d9349ce569a1f5da5f385d2ba3f536 (commit)
       via  f94b7adcf95cb89cdec16351530b42e35290bbde (commit)
       via  9f5b8613d97b73bf5e0b3a0980cac3addd36b4a7 (commit)
       via  2472f6f8627c7c708c4afdff324eb2f1aa580f64 (commit)
       via  b4f82e954efd0057863fbaba6bef0322579ad2bb (commit)
       via  b41a13e8555e98283e5e5ad6721931c819ca09d1 (commit)
       via  877b88b07f34e39ac0d0c82a938a31faff4edc7a (commit)
       via  deb8019a0d83b37499c9094a860538dcfadc3685 (commit)
       via  84ec669470f5b550fc5bfc8175393e644e7c2870 (commit)
       via  05db56f2b375b6219859a627731f344f34c95489 (commit)
      from  a670d25b4b565601020102e27cd63728c3e763f4 (commit)

Summary of changes:
 etc/RT_Config.pm.in                           | 26 ++++++++++++
 lib/RT.pm                                     |  1 +
 lib/RT/Crypt/SMIME.pm                         |  8 ++++
 lib/RT/I18N.pm                                |  9 ++--
 lib/RT/Interface/Email.pm                     | 60 ++++++++++++++++++---------
 lib/RT/Plugin.pm                              | 11 +++++
 share/html/Admin/Scrips/index.html            | 30 ++++++++++++--
 share/html/Admin/Tools/Configuration.html     | 17 ++++++++
 share/html/Admin/Users/Modify.html            |  5 +++
 share/html/Articles/Elements/BeforeMessageBox |  2 +-
 share/html/Elements/ColumnMap                 |  2 +-
 share/html/Elements/Tabs                      |  7 ++--
 share/html/Search/Chart                       | 10 ++++-
 share/html/Ticket/Elements/UpdateCc           |  4 ++
 share/static/css/base/ticket-form.css         |  4 ++
 t/lifecycles/basics.t                         |  2 +-
 t/lifecycles/dates.t                          |  2 +-
 t/lifecycles/moving.t                         |  2 +-
 t/lifecycles/types.t                          |  2 +-
 t/lifecycles/unresolved-deps.t                |  2 +-
 t/mail/mime_decoding.t                        | 10 +++++
 t/mail/outgoing-mail-from.t                   | 56 +++++++++++++++++++++++++
 t/mail/precedence-outgoing.t                  | 59 ++++++++++++++++++++++++++
 t/web/cf_groupings.t                          |  2 +-
 t/web/installer.t                             |  5 ++-
 25 files changed, 295 insertions(+), 43 deletions(-)
 create mode 100644 t/mail/outgoing-mail-from.t
 create mode 100644 t/mail/precedence-outgoing.t

- Log -----------------------------------------------------------------
commit cb9c3d6210d338353d6ae30a541564b739c727ec
Merge: a670d25 2171a89
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Dec 27 13:32:35 2016 -0500

    Merge branch '4.2-trunk' into 4.4-trunk

diff --cc etc/RT_Config.pm.in
index c34c04e,fd5a866..9366a23
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@@ -1763,125 -1687,18 +1780,134 @@@ you will have no access to Articles
  
  Set($HideArticleSearchOnReplyCreate, 0);
  
+ =item C<$LinkArticlesOnInclude>
+ 
+ Set this to 0 to suppress the default behavior of automatically linking
+ to Articles when they are included in a message.
+ 
+ =cut
+ 
+ Set($LinkArticlesOnInclude, 1);
+ 
  =back
  
 +=head1 Assets
 +
 +=over 4
 +
 +=item C<@AssetQueues>
 +
 +This should be a list of names of queues whose tickets should always
 +display the "Assets" box.  This is useful for queues which deal
 +primarily with assets, as it provides a ready box to link an asset to
 +the ticket, even when the ticket has no related assets yet.
 +
 +=cut
 +
 +# Set(@AssetQueues, ());
 +
 +=item C<$DefaultCatalog>
 +
 +This provides the default catalog after a user initially logs in.
 +However, the default catalog is "sticky," and so will remember the
 +last-selected catalog thereafter.
 +
 +=cut
 +
 +# Set($DefaultCatalog, 'General assets');
 +
 +=item C<$AssetSearchFields>
 +
 +Specifies which fields of L<RT::Asset> to match against and how to match
 +each field when performing a quick search on assets.  Valid match
 +methods are LIKE, STARTSWITH, ENDSWITH, =, and !=.  Valid search fields
 +are id, Name, Description, or custom fields, which are specified as
 +"CF.1234" or "CF.Name"
 +
 +=cut
 +
 +Set($AssetSearchFields, {
 +    id          => '=',
 +    Name        => 'LIKE',
 +    Description => 'LIKE',
 +});
 +
 +=item C<$AssetSearchFormat>
 +
 +The format that results of the asset search are displayed with.  This is
 +either a string, which will be used for all catalogs, or a hash
 +reference, keyed by catalog's name/id.  If a hashref and neither name or
 +id is found therein, falls back to the key ''.
 +
 +If you wish to use the multiple catalog format, your configuration would look
 +something like:
 +
 +    Set($AssetSearchFormat, {
 +        'General assets' => q[Format String for the General Assets Catalog],
 +        8                => q[Format String for Catalog 8],
 +        ''               => q[Format String for any catalogs not listed explicitly],
 +    });
 +
 +=cut
 +
 +# loc('Related tickets')
 +Set($AssetSearchFormat, q[
 +    '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
 +    Description,
 +    '__Status__ (__Catalog__)/TITLE:Status',
 +    Owner,
 +    HeldBy,
 +    Contacts,
 +    '__ActiveTickets__ __InactiveTickets__/TITLE:Related tickets',
 +]);
 +
 +=item C<$AssetSummaryFormat>
 +
 +The information that is displayed on ticket display pages about assets
 +related to the ticket.  This is displayed in a table beneath the asset
 +name.
 +
 +=cut
 +
 +Set($AssetSummaryFormat, q[
 +    '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
 +    Description,
 +    '__Status__ (__Catalog__)/TITLE:Status',
 +    Owner,
 +    HeldBy,
 +    Contacts,
 +    '__ActiveTickets__ __InactiveTickets__/TITLE:Related tickets',
 +]);
 +
 +=item C<$AssetSummaryRelatedTicketsFormat>
 +
 +The information that is displayed on ticket display pages about tickets
 +related to assets related to the ticket.  This is displayed as a list of
 +tickets underneath the asset properties.
 +
 +=cut
  
 +Set($AssetSummaryRelatedTicketsFormat, q[
 +    '<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>',
 +    '(__OwnerName__)',
 +    '<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>',
 +    QueueName,
 +    Status,
 +]);
 +
 +=item C<$AssetBasicCustomFieldsOnCreate>
 +
 +Specify a list of Asset custom fields to show in "Basics" widget on create.
 +
 +e.g.
 +
 +Set( $AssetBasicCustomFieldsOnCreate, [ 'foo', 'bar' ] );
 +
 +=cut
 +
 +# Set($AssetBasicCustomFieldsOnCreate, undef );
 +
 +=back
  
  =head2 Message box properties
  
diff --cc lib/RT/Interface/Email.pm
index 23543fc,1d5f3bb..281c5c2
--- a/lib/RT/Interface/Email.pm
+++ b/lib/RT/Interface/Email.pm
@@@ -462,322 -323,61 +462,348 @@@ C<Return-path>, C<Errors-To>, C<Reply-T
  
  =cut
  
 -sub WillSignEncrypt {
 -    my %args = @_;
 -    my $attachment = delete $args{Attachment};
 -    my $ticket     = delete $args{Ticket};
 -
 -    if ( not RT->Config->Get('Crypt')->{'Enable'} ) {
 -        $args{Sign} = $args{Encrypt} = 0;
 -        return wantarray ? %args : 0;
 -    }
 +sub ParseErrorsToAddressFromHead {
 +    my $head = shift;
  
 -    for my $argument ( qw(Sign Encrypt) ) {
 -        next if defined $args{ $argument };
 +    foreach my $header ( 'Errors-To', 'Reply-To', 'From', 'Sender' ) {
 +        my $value = Encode::decode( "UTF-8", $head->get($header) );
 +        next unless $value;
  
 -        if ( $attachment and defined $attachment->GetHeader("X-RT-$argument") ) {
 -            $args{$argument} = $attachment->GetHeader("X-RT-$argument");
 -        } elsif ( $ticket and $argument eq "Encrypt" ) {
 -            $args{Encrypt} = $ticket->QueueObj->Encrypt();
 -        } elsif ( $ticket and $argument eq "Sign" ) {
 -            # Note that $queue->Sign is UI-only, and that all
 -            # UI-generated messages explicitly set the X-RT-Crypt header
 -            # to 0 or 1; thus this path is only taken for messages
 -            # generated _not_ via the web UI.
 -            $args{Sign} = $ticket->QueueObj->SignAuto();
 -        }
 +        my ( $email ) = RT::EmailParser->ParseEmailAddress($value);
 +        return $email->address if $email;
      }
 -
 -    return wantarray ? %args : ($args{Sign} || $args{Encrypt});
  }
  
 -sub _OutgoingMailFrom {
 -    my $TicketObj = shift;
 +=head3 IsMachineGeneratedMail Message => C<message>
  
 -    my $MailFrom = RT->Config->Get('SetOutgoingMailFrom');
 -    my $OutgoingMailAddress = $MailFrom =~ /\@/ ? $MailFrom : undef;
 -    my $Overrides = RT->Config->Get('OverrideOutgoingMailFrom') || {};
 +Checks if the mail is machine-generated (via a bounce, mail headers,
  
 -    if ($TicketObj) {
 -        my $Queue = $TicketObj->QueueObj;
 -        my $QueueAddressOverride = $Overrides->{$Queue->id}
 -            || $Overrides->{$Queue->Name};
 +=cut
 +
 +sub IsMachineGeneratedMail {
 +    my %args = (
 +        Message => undef,
 +        Subject => undef,
 +        @_
 +    );
 +    my $head = $args{'Message'}->head;
 +
 +    my $IsAutoGenerated = CheckForAutoGenerated($head);
 +    my $IsALoop = CheckForLoops($head);
 +
 +    my $owner_mail = RT->Config->Get('OwnerEmail');
 +
 +    # Don't let the user stuff the RT-Squelch-Replies-To header.
 +    $head->delete('RT-Squelch-Replies-To');
 +
 +    # If the message is autogenerated, we need to know, so we can not
 +    # send mail to the sender
 +    return unless $IsAutoGenerated || $IsALoop;
 +
 +    # Warn someone if it's a loop, before we drop it on the ground
 +    if ($IsALoop) {
 +        my $MessageId = Encode::decode( "UTF-8", $head->get('Message-ID') );
 +        $RT::Logger->crit("RT Received mail ($MessageId) from itself.");
 +
 +        #Should we mail it to RTOwner?
 +        if ( RT->Config->Get('LoopsToRTOwner') ) {
 +            MailError(
 +                To          => $owner_mail,
 +                Subject     => "RT Bounce: ".$args{'Subject'},
 +                Explanation => "RT thinks this message may be a bounce",
 +            );
 +        }
 +
 +        #Do we actually want to store it?
 +        FAILURE( "Message is a bounce" ) unless RT->Config->Get('StoreLoops');
 +    }
 +
 +    # Squelch replies to the sender, and also leave a clue to
 +    # allow us to squelch ALL outbound messages. This way we
 +    # can punt the logic of "what to do when we get a bounce"
 +    # to the scrip. We might want to notify nobody. Or just
 +    # the RT Owner. Or maybe all Privileged watchers.
 +    my ( $Sender ) = ParseSenderAddressFromHead($head);
 +    $head->replace( 'RT-Squelch-Replies-To',    Encode::encode("UTF-8", $Sender ) );
 +    $head->replace( 'RT-DetectedAutoGenerated', 'true' );
 +
 +    return 1;
 +}
 +
 +=head3 CheckForLoops HEAD
 +
 +Takes a L<MIME::Head> object and returns true if the message was sent by
 +this RT instance, by checking the C<X-RT-Loop-Prevention> header.
 +
 +=cut
 +
 +sub CheckForLoops {
 +    my $head = shift;
 +
 +    # If this instance of RT sent it our, we don't want to take it in
 +    my $RTLoop = Encode::decode( "UTF-8", $head->get("X-RT-Loop-Prevention") || "" );
 +    chomp ($RTLoop); # remove that newline
 +    if ( $RTLoop eq RT->Config->Get('rtname') ) {
 +        return 1;
 +    }
 +
 +    # TODO: We might not trap the case where RT instance A sends a mail
 +    # to RT instance B which sends a mail to ...
 +    return undef;
 +}
 +
 +=head3 CheckForAutoGenerated HEAD
 +
 +Takes a HEAD object of L<MIME::Head> class and returns true if message is
 +autogenerated. Checks C<Precedence>, RFC3834 C<Auto-Submitted>, and
 +C<X-FC-Machinegenerated> fields of the head in tests.
 +
 +=cut
 +
 +sub CheckForAutoGenerated {
 +    my $head = shift;
 +
 +    # Bounces, via return-path
 +    my $ReturnPath = $head->get("Return-path") || "";
 +    return 1 if $ReturnPath =~ /<>/;
 +
 +    # Bounces, via mailer-daemon or postmaster
 +    my ( $From ) = ParseSenderAddressFromHead($head);
 +    return 1 if defined $From and $From =~ /^mailer-daemon\@/i;
 +    return 1 if defined $From and $From =~ /^postmaster\@/i;
 +    return 1 if defined $From and $From eq "";
 +
 +    # Bulk or junk messages are auto-generated
 +    return 1 if grep {/^(bulk|junk)/i} $head->get_all("Precedence");
 +
 +    # Per RFC3834, any Auto-Submitted header which is not "no" means
 +    # it is auto-generated.
 +    my $AutoSubmitted = $head->get("Auto-Submitted") || "";
 +    return 1 if length $AutoSubmitted and $AutoSubmitted ne "no";
 +
 +    # First Class mailer uses this as a clue.
 +    my $FCJunk = $head->get("X-FC-Machinegenerated") || "";
 +    return 1 if $FCJunk =~ /^true/i;
 +
 +    return 0;
 +}
 +
 +=head3 ExtractTicketId
 +
 +Passed a L<MIME::Entity> object, and returns a either ticket id or undef
 +to signal 'new ticket'.
 +
 +This is a great entry point if you need to customize how ticket ids are
 +handled for your site. L<RT::Extension::RepliesToResolved> demonstrates
 +one possible use for this extension.
 +
 +If the Subject of the L<MIME::Entity> is modified, the updated subject
 +will be used during ticket creation.
 +
 +=cut
 +
 +sub ExtractTicketId {
 +    my $entity = shift;
 +
 +    my $subject = Encode::decode( "UTF-8", $entity->head->get('Subject') || '' );
 +    chomp $subject;
 +    return ParseTicketId( $subject );
 +}
 +
 +=head3 ParseTicketId
 +
 +Takes a string and searches for [subjecttag #id]
 +
 +Returns the id if a match is found.  Otherwise returns undef.
 +
 +=cut
 +
 +sub ParseTicketId {
 +    my $Subject = shift;
 +
 +    my $rtname = RT->Config->Get('rtname');
 +    my $test_name = RT->Config->Get('EmailSubjectTagRegex') || qr/\Q$rtname\E/i;
 +
 +    # We use @captures and pull out the last capture value to guard against
 +    # someone using (...) instead of (?:...) in $EmailSubjectTagRegex.
 +    my $id;
 +    if ( my @captures = $Subject =~ /\[$test_name\s+\#(\d+)\s*\]/i ) {
 +        $id = $captures[-1];
 +    } else {
 +        foreach my $tag ( RT->System->SubjectTag ) {
 +            next unless my @captures = $Subject =~ /\[\Q$tag\E\s+\#(\d+)\s*\]/i;
 +            $id = $captures[-1];
 +            last;
 +        }
 +    }
 +    return undef unless $id;
 +
 +    $RT::Logger->debug("Found a ticket ID. It's $id");
 +    return $id;
 +}
 +
 +=head3 MailError PARAM HASH
 +
 +Sends an error message. Takes a param hash:
 +
 +=over 4
 +
 +=item From
 +
 +Sender's address, defaults to L<RT_Config/$CorrespondAddress>;
 +
 +=item To
 +
 +Recipient, defaults to L<RT_Config/$OwnerEmail>;
 +
 +=item Subject
 +
 +Subject of the message, defaults to C<There has been an error>;
 +
 +=item Explanation
 +
 +Main content of the error, default value is C<Unexplained error>;
 +
 +=item MIMEObj
 +
 +Optional L<MIME::Entity> that is attached to the error mail.
 +Additionally, the C<In-Reply-To> header will point to this message.
 +
 +=item Attach
 +
 +Optional text that attached to the error as a C<message/rfc822> part.
 +
 +=item LogLevel
 +
 +Log level the subject and explanation is written to the log; defaults to
 +C<critical>.
 +
 +=back
 +
 +=cut
 +
 +sub MailError {
 +    my %args = (
 +        To          => RT->Config->Get('OwnerEmail'),
 +        From        => RT->Config->Get('CorrespondAddress'),
 +        Subject     => 'There has been an error',
 +        Explanation => 'Unexplained error',
 +        MIMEObj     => undef,
 +        Attach      => undef,
 +        LogLevel    => 'crit',
 +        FAILURE     => 0,
 +        @_
 +    );
 +
 +    $RT::Logger->log(
 +        level   => $args{'LogLevel'},
 +        message => "$args{Subject}: $args{'Explanation'}",
 +    ) if $args{'LogLevel'};
 +
 +    # the colons are necessary to make ->build include non-standard headers
 +    my %entity_args = (
 +        Type                    => "multipart/mixed",
 +        From                    => Encode::encode( "UTF-8", $args{'From'} ),
 +        To                      => Encode::encode( "UTF-8", $args{'To'} ),
 +        Subject                 => EncodeToMIME( String => $args{'Subject'} ),
 +        'X-RT-Loop-Prevention:' => Encode::encode( "UTF-8", RT->Config->Get('rtname') ),
 +    );
 +
 +    # only set precedence if the sysadmin wants us to
 +    if (defined(RT->Config->Get('DefaultErrorMailPrecedence'))) {
 +        $entity_args{'Precedence:'} =
 +            Encode::encode( "UTF-8", RT->Config->Get('DefaultErrorMailPrecedence') );
 +    }
 +
 +    my $entity = MIME::Entity->build(%entity_args);
 +    SetInReplyTo( Message => $entity, InReplyTo => $args{'MIMEObj'} );
 +
 +    $entity->attach(
 +        Type    => "text/plain",
 +        Charset => "UTF-8",
 +        Data    => Encode::encode( "UTF-8", $args{'Explanation'} . "\n" ),
 +    );
 +
 +    if ( $args{'MIMEObj'} ) {
 +        $args{'MIMEObj'}->sync_headers;
 +        $entity->add_part( $args{'MIMEObj'} );
 +    }
 +
 +    if ( $args{'Attach'} ) {
 +        $entity->attach( Data => Encode::encode( "UTF-8", $args{'Attach'} ), Type => 'message/rfc822' );
 +
 +    }
 +
 +    SendEmail( Entity => $entity, Bounce => 1 );
 +
 +    FAILURE( "$args{Subject}: $args{Explanation}" ) if $args{FAILURE};
 +}
 +
++sub _OutgoingMailFrom {
++    my $TicketObj = shift;
++
++    my $MailFrom = RT->Config->Get('SetOutgoingMailFrom');
++    my $OutgoingMailAddress = $MailFrom =~ /\@/ ? $MailFrom : undef;
++    my $Overrides = RT->Config->Get('OverrideOutgoingMailFrom') || {};
++
++    if ($TicketObj) {
++        my $Queue = $TicketObj->QueueObj;
++        my $QueueAddressOverride = $Overrides->{$Queue->id}
++            || $Overrides->{$Queue->Name};
+ 
+         if ($QueueAddressOverride) {
+             $OutgoingMailAddress = $QueueAddressOverride;
+         } else {
+             $OutgoingMailAddress ||= $Queue->CorrespondAddress
+                 || RT->Config->Get('CorrespondAddress');
+         }
+     }
+     elsif ($Overrides->{'Default'}) {
+         $OutgoingMailAddress = $Overrides->{'Default'};
+     }
+ 
+     return $OutgoingMailAddress;
+ }
+ 
 +=head2 SENDING EMAIL
 +
 +=head3 SendEmail Entity => undef, [ Bounce => 0, Ticket => undef, Transaction => undef ]
 +
 +Sends an email (passed as a L<MIME::Entity> object C<ENTITY>) using
 +RT's outgoing mail configuration. If C<BOUNCE> is passed, and is a
 +true value, the message will be marked as an autogenerated error, if
 +possible. Sets Date field of the head to now if it's not set.
 +
 +If the C<X-RT-Squelch> header is set to any true value, the mail will
 +not be sent. One use is to let extensions easily cancel outgoing mail.
 +
 +Ticket and Transaction arguments are optional. If Transaction is
 +specified and Ticket is not then ticket of the transaction is
 +used, but only if the transaction belongs to a ticket.
 +
 +Returns 1 on success, 0 on error or -1 if message has no recipients
 +and hasn't been sent.
 +
 +=head3 Signing and Encrypting
 +
 +This function as well signs and/or encrypts the message according to
 +headers of a transaction's attachment or properties of a ticket's queue.
 +To get full access to the configuration Ticket and/or Transaction
 +arguments must be provided, but you can force behaviour using Sign
 +and/or Encrypt arguments.
 +
 +The following precedence of arguments are used to figure out if
 +the message should be encrypted and/or signed:
 +
 +* if Sign or Encrypt argument is defined then its value is used
 +
 +* else if Transaction's first attachment has X-RT-Sign or X-RT-Encrypt
 +header field then it's value is used
 +
 +* else properties of a queue of the Ticket are used.
 +
 +=cut
 +
  sub SendEmail {
      my (%args) = (
          Entity => undef,
diff --cc share/html/Admin/Users/Modify.html
index 0b30780,984a29b..63144db
--- a/share/html/Admin/Users/Modify.html
+++ b/share/html/Admin/Users/Modify.html
@@@ -242,8 -246,10 +246,9 @@@ $ARGS{Disabled} = $ARGS{Enabled} ? 0 : 
  delete $ARGS{Disabled} unless $ARGS{SetEnabled};
  
  my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo
 -                Organization RealName NickName Lang EmailEncoding WebEncoding
 -                ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId
 -                AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1
 -                Address2 City State Zip Country Timezone
 +                Organization RealName NickName Lang Gecos HomePhone WorkPhone
 +                MobilePhone PagerPhone Address1 Address2 City State Zip Country
++                Timezone
                 );
  
  if ($Create) {
diff --cc share/html/Elements/Tabs
index 083d89d,0a00512..8579f67
--- a/share/html/Elements/Tabs
+++ b/share/html/Elements/Tabs
@@@ -1124,7 -937,7 +1125,7 @@@ my $build_main_nav = sub 
          PageMenu()->child( edit => title => loc('Edit'), path => '/Prefs/MyRT.html' );
      }
  
-     $m->callback( CallbackName => 'Privileged', Path => $request_path, ARGSRef => \%ARGS );
 -    $m->callback( CallbackName => 'Privileged', Path => $request_path, Search_Args => $args, Has_Query => $has_query );
++    $m->callback( CallbackName => 'Privileged', Path => $request_path, Search_Args => $args, Has_Query => $has_query, ARGSRef => \%ARGS );
  };
  
  my $build_selfservice_nav = sub {
diff --cc share/html/Ticket/Elements/UpdateCc
index 641fa33,bb65553..4b65367
--- a/share/html/Ticket/Elements/UpdateCc
+++ b/share/html/Ticket/Elements/UpdateCc
@@@ -70,10 -65,8 +71,11 @@@
      onClick="checkboxToInput('UpdateCc', <% "UpdateCc-$addr" |n,j%>, <%$clean_addr|n,j%> );"
      <% $ARGS{'UpdateCc-'.$addr} ? 'checked="checked"' : ''%> >
        <label for="UpdateCc-<%$addr%>"><& /Elements/ShowUser, Address => $txn_addresses{$addr}&></label>
+ </span>
  %}
 +%if (@one_time_Ccs && $hide_cc_suggestions) {
 +</div>
 +%}
  </td></tr>
  <tr><td class="label"><&|/l&>One-time Bcc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateBcc', Size => undef, Default => $ARGS{UpdateBcc}, AutocompleteMultiple => 1 &><br />
  %if (scalar @one_time_Ccs) {
@@@ -95,22 -83,8 +98,23 @@@
      onClick="checkboxToInput('UpdateBcc', <% "UpdateBcc-$addr" |n,j%>, <%$clean_addr|n,j%> );"
      <% $ARGS{'UpdateBcc-'.$addr} ? 'checked="checked"' : ''%> >
        <label for="UpdateBcc-<%$addr%>"><& /Elements/ShowUser, Address => $txn_addresses{$addr}&></label>
+ </span>
  %}
 +%if (@one_time_Ccs && $hide_cc_suggestions) {
 +</div>
 +<script type="text/javascript">
 +jQuery(function() {
 +    jQuery('a.ToggleSuggestions').click(function(e) {
 +        e.preventDefault();
 +        var toggleSuggestions = jQuery(this);
 +        var oneTimeCcs = toggleSuggestions.closest('td').find('.OneTimeCcs');
 +        oneTimeCcs.toggleClass('hidden');
 +        var hideOrShow = oneTimeCcs.hasClass('hidden') ? toggleSuggestions.data('showLabel') : toggleSuggestions.data('hideLabel');
 +        toggleSuggestions.find('i').html('(' + hideOrShow + ')');
 +    });
 +});
 +</script>
 +%}
  </td></tr>
  <%args>
  $TicketObj

-----------------------------------------------------------------------


More information about the rt-commit mailing list