/** * Sends a message to an email address supposed to be added to the * identity. * * A message is send to this address containing a time-sensitive link to * confirm that the address really belongs to that user. * * @param integer $id The identity's ID. * @param string $old_addr The old From: address. * * @throws Horde_Mime_Exception */ public function verifyIdentity($id, $old_addr) { global $injector, $notification, $registry; $hash = strval(new Horde_Support_Randomid()); $pref = $this->_confirmEmail(); $pref[$hash] = $this->get($id); $pref[$hash][self::EXPIRE] = time() + self::EXPIRE_SECS; $this->_confirmEmail($pref); $new_addr = $this->getValue($this->_prefnames['from_addr'], $id); $confirm = Horde::url($registry->getServiceLink('emailconfirm')->add('h', $hash)->setRaw(true), true); $message = sprintf(Horde_Core_Translation::t("You have requested to add the email address \"%s\" to the list of your personal email addresses.\n\nGo to the following link to confirm that this is really your address:\n%s\n\nIf you don't know what this message means, you can delete it."), $new_addr, $confirm); $msg_headers = new Horde_Mime_Headers(); $msg_headers->addMessageIdHeader(); $msg_headers->addUserAgentHeader(); $msg_headers->addHeader('Date', date('r')); $msg_headers->addHeader('To', $new_addr); $msg_headers->addHeader('From', $old_addr); $msg_headers->addHeader('Subject', Horde_Core_Translation::t("Confirm new email address")); $body = new Horde_Mime_Part(); $body->setType('text/plain'); $body->setContents(Horde_String::wrap($message, 76)); $body->setCharset('UTF-8'); $body->send($new_addr, $msg_headers, $injector->getInstance('Horde_Mail')); $notification->push(sprintf(Horde_Core_Translation::t("A message has been sent to \"%s\" to verify that this is really your address. The new email address is activated as soon as you confirm this message."), $new_addr), 'horde.message'); }
/** * Sends this message. * * @param Mail $mailer A Mail object. * @param boolean $resend If true, the message id and date are re-used; * If false, they will be updated. * @param boolean $flowed Send message in flowed text format. * * @throws Horde_Mime_Exception */ public function send($mailer, $resend = false, $flowed = true) { /* Add mandatory headers if missing. */ $has_header = $this->_headers->getValue('Message-ID'); if (!$resend || !$has_header) { if ($has_header) { $this->_headers->removeHeader('Message-ID'); } $this->_headers->addMessageIdHeader(); } if (!$this->_headers->getValue('User-Agent')) { $this->_headers->addUserAgentHeader(); } $has_header = $this->_headers->getValue('Date'); if (!$resend || !$has_header) { if ($has_header) { $this->_headers->removeHeader('Date'); } $this->_headers->addHeader('Date', date('r')); } if (isset($this->_base)) { $basepart = $this->_base; } else { /* Send in flowed format. */ if ($flowed && !empty($this->_body)) { $flowed = new Horde_Text_Flowed($this->_body->getContents(), $this->_body->getCharset()); $flowed->setDelSp(true); $this->_body->setContentTypeParameter('format', 'flowed'); $this->_body->setContentTypeParameter('DelSp', 'Yes'); $this->_body->setContents($flowed->toFlowed()); } /* Build mime message. */ $body = new Horde_Mime_Part(); if (!empty($this->_body) && !empty($this->_htmlBody)) { $body->setType('multipart/alternative'); $this->_body->setDescription(Horde_Mime_Translation::t("Plaintext Version of Message")); $body->addPart($this->_body); $this->_htmlBody->setDescription(Horde_Mime_Translation::t("HTML Version of Message")); $body->addPart($this->_htmlBody); } elseif (!empty($this->_htmlBody)) { $body = $this->_htmlBody; } elseif (!empty($this->_body)) { $body = $this->_body; } if (count($this->_parts)) { $basepart = new Horde_Mime_Part(); $basepart->setType('multipart/mixed'); $basepart->isBasePart(true); if ($body) { $basepart->addPart($body); } foreach ($this->_parts as $mime_part) { $basepart->addPart($mime_part); } } else { $basepart = $body; $basepart->isBasePart(true); } } $basepart->setHeaderCharset($this->_charset); /* Build recipients. */ $recipients = clone $this->_recipients; foreach (array('to', 'cc') as $header) { $recipients->add($this->_headers->getOb($header)); } if ($this->_bcc) { $recipients->add($this->_bcc); } /* Trick Horde_Mime_Part into re-generating the message headers. */ $this->_headers->removeHeader('MIME-Version'); /* Send message. */ $recipients->unique(); $basepart->send($recipients->writeAddress(), $this->_headers, $mailer); /* Remember the basepart */ $this->_base = $basepart; }
/** * Send notification to attachment owner. */ public function sendNotification() { global $conf, $injector, $registry; if (empty($conf['compose']['link_attachments_notify'])) { return; } try { $identity = $injector->getInstance('Horde_Core_Factory_Identity')->create($this->_user); $address = $identity->getDefaultFromAddress(); /* Ignore missing addresses, which are returned as <>. */ if (strlen($address) < 3 || $this->_getDeleteToken()) { return; } $address_full = $identity->getDefaultFromAddress(true); /* Load user prefs to correctly translate gettext strings. */ if (!$registry->getAuth()) { $prefs = $injector->getInstance('Horde_Core_Factory_Prefs')->create('imp', array('user' => $this->_user)); $registry->setLanguageEnvironment($prefs->getValue('language')); } $h = new Horde_Mime_Headers(); $h->addReceivedHeader(array('dns' => $injector->getInstance('Net_DNS2_Resolver'), 'server' => $conf['server']['name'])); $h->addMessageIdHeader(); $h->addUserAgentHeader(); $h->addHeader('Date', date('r')); $h->addHeader('From', $address_full); $h->addHeader('To', $address_full); $h->addHeader('Subject', _("Notification: Linked attachment downloaded")); $h->addHeader('Auto-Submitted', 'auto-generated'); $msg = new Horde_Mime_Part(); $msg->setType('text/plain'); $msg->setCharset('UTF-8'); $md = $this->_atc->getMetadata(); $msg->setContents(Horde_String::wrap(_("Your linked attachment has been downloaded by at least one user.") . "\n\n" . sprintf(_("Name: %s"), $md->filename) . "\n" . sprintf(_("Type: %s"), $md->type) . "\n" . sprintf(_("Sent Date: %s"), date('r', $md->time)) . "\n\n" . _("Click on the following link to permanently delete the attachment:") . "\n" . strval($this->_atc->link_url->add('d', $this->_getDeleteToken(true))))); $msg->send($address, $h, $injector->getInstance('Horde_Mail')); } catch (Exception $e) { Horde::log($e, 'ERR'); } }
/** * Generate the MDN according to the specifications listed in RFC * 3798 [3]. * * @param boolean $action Was this MDN type a result of a manual * action on part of the user? * @param boolean $sending Was this MDN sent as a result of a manual * action on part of the user? * @param string $type The type of action performed by the user. * Per RFC 3798 [3.2.6.2] the following types are * valid: * - deleted * - displayed * @param string $name The name of the local server. * @param Mail $mailer A Mail driver. * @param array $opts Additional options: * - charset: (string) Default charset. * DEFAULT: NONE * - from_addr: (string) From address. * DEFAULT: NONE * @param array $mod The list of modifications. Per RFC 3798 * [3.2.6.3] the following modifications are * valid: * - error * @param array $err If $mod is 'error', the additional * information to provide. Key is the type of * modification, value is the text. * * @throws Horde_Mime_Exception */ public function generate($action, $sending, $type, $name, $mailer, array $opts = array(), array $mod = array(), array $err = array()) { $opts = array_merge(array('charset' => null, 'from_addr' => null), $opts); $to = $this->getMdnReturnAddr(); $ua = $this->_headers->getUserAgent(); $orig_recip = $this->_headers->getValue('Original-Recipient'); if (!empty($orig_recip) && is_array($orig_recip)) { $orig_recip = $orig_recip[0]; } $msg_id = $this->_headers->getValue('Message-ID'); /* Create the Disposition field now (RFC 3798 [3.2.6]). */ $dispo = 'Disposition: ' . ($action ? 'manual-action' : 'automatic-action') . '/' . ($sending ? 'MDN-sent-manually' : 'MDN-sent-automatically') . '; ' . $type; if (!empty($mod)) { $dispo .= '/' . implode(', ', $mod); } /* Set up the mail headers. */ $msg_headers = new Horde_Mime_Headers(); $msg_headers->addMessageIdHeader(); $msg_headers->addUserAgentHeader($ua); $msg_headers->addHeader('Date', date('r')); if ($opts['from_addr']) { $msg_headers->addHeader('From', $opts['from_addr']); } $msg_headers->addHeader('To', $this->getMdnReturnAddr()); $msg_headers->addHeader('Subject', Horde_Mime_Translation::t("Disposition Notification")); /* MDNs are a subtype of 'multipart/report'. */ $msg = new Horde_Mime_Part(); $msg->setType('multipart/report'); $msg->setContentTypeParameter('report-type', 'disposition-notification'); /* The first part is a human readable message. */ $part_one = new Horde_Mime_Part(); $part_one->setType('text/plain'); $part_one->setCharset($opts['charset']); if ($type == 'displayed') { $contents = sprintf(Horde_Mime_Translation::t("The message sent on %s to %s with subject \"%s\" has been displayed.\n\nThis is no guarantee that the message has been read or understood."), $this->_headers->getValue('Date'), $this->_headers->getValue('To'), $this->_headers->getValue('Subject')); $flowed = new Horde_Text_Flowed($contents, $opts['charset']); $flowed->setDelSp(true); $part_one->setContentTypeParameter('format', 'flowed'); $part_one->setContentTypeParameter('DelSp', 'Yes'); $part_one->setContents($flowed->toFlowed()); } // TODO: Messages for other notification types. $msg->addPart($part_one); /* The second part is a machine-parseable description. */ $part_two = new Horde_Mime_Part(); $part_two->setType('message/disposition-notification'); $part_two_text = array('Reporting-UA: ' . $name . '; ' . $ua . "\n"); if (!empty($orig_recip)) { $part_two_text[] = 'Original-Recipient: rfc822;' . $orig_recip . "\n"; } if ($opts['from_addr']) { $part_two_text[] = 'Final-Recipient: rfc822;' . $opts['from_addr'] . "\n"; } if (!empty($msg_id)) { $part_two_text[] = 'Original-Message-ID: rfc822;' . $msg_id . "\n"; } $part_two_text[] = $dispo . "\n"; if (in_array('error', $mod) && isset($err['error'])) { $part_two_text[] = 'Error: ' . $err['error'] . "\n"; } $part_two->setContents($part_two_text); $msg->addPart($part_two); /* The third part is the text of the original message. RFC 3798 [3] * allows us to return only a portion of the entire message - this * is left up to the user. */ $part_three = new Horde_Mime_Part(); $part_three->setType('message/rfc822'); $part_three_text = array($this->_headers->toString()); if (!empty($this->_msgtext)) { $part_three_text[] = $part_three->getEOL() . $this->_msgtext; } $part_three->setContents($part_three_text); $msg->addPart($part_three); return $msg->send($to, $msg_headers, $mailer); }