mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 08:42:41 +01:00
Raise an "Account Setup Issue" if your primary address is unverified
Summary: Ref T12237. This adds a UI cue for users who have unverified primary addresses, since we no longer send them mail. Also adds a new `bin/mail unverify` to unverify an address (for example, because mail is bouncing). Test Plan: - Unverified my address, saw setup issue. - Verified my address, no more setup issue. {F2861820} Reviewers: chad Reviewed By: chad Maniphest Tasks: T12237 Differential Revision: https://secure.phabricator.com/D17344
This commit is contained in:
parent
037c749ef3
commit
3cf6f746f0
5 changed files with 283 additions and 0 deletions
|
@ -2947,6 +2947,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMailManagementSendTestWorkflow' => 'applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php',
|
||||
'PhabricatorMailManagementShowInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowInboundWorkflow.php',
|
||||
'PhabricatorMailManagementShowOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php',
|
||||
'PhabricatorMailManagementUnverifyWorkflow' => 'applications/metamta/management/PhabricatorMailManagementUnverifyWorkflow.php',
|
||||
'PhabricatorMailManagementVolumeWorkflow' => 'applications/metamta/management/PhabricatorMailManagementVolumeWorkflow.php',
|
||||
'PhabricatorMailManagementWorkflow' => 'applications/metamta/management/PhabricatorMailManagementWorkflow.php',
|
||||
'PhabricatorMailOutboundMailHeraldAdapter' => 'applications/metamta/herald/PhabricatorMailOutboundMailHeraldAdapter.php',
|
||||
|
@ -3772,6 +3773,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSettingsDeveloperPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsDeveloperPanelGroup.php',
|
||||
'PhabricatorSettingsEditEngine' => 'applications/settings/editor/PhabricatorSettingsEditEngine.php',
|
||||
'PhabricatorSettingsEmailPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsEmailPanelGroup.php',
|
||||
'PhabricatorSettingsIssueController' => 'applications/settings/controller/PhabricatorSettingsIssueController.php',
|
||||
'PhabricatorSettingsListController' => 'applications/settings/controller/PhabricatorSettingsListController.php',
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsLogsPanelGroup.php',
|
||||
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
|
||||
|
@ -8009,6 +8011,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMailManagementSendTestWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementShowInboundWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementUnverifyWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementVolumeWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||
'PhabricatorMailOutboundMailHeraldAdapter' => 'HeraldAdapter',
|
||||
|
@ -9021,6 +9024,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSettingsDeveloperPanelGroup' => 'PhabricatorSettingsPanelGroup',
|
||||
'PhabricatorSettingsEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorSettingsEmailPanelGroup' => 'PhabricatorSettingsPanelGroup',
|
||||
'PhabricatorSettingsIssueController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsListController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'PhabricatorSettingsPanelGroup',
|
||||
'PhabricatorSettingsMainController' => 'PhabricatorController',
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorMailManagementUnverifyWorkflow
|
||||
extends PhabricatorMailManagementWorkflow {
|
||||
|
||||
protected function didConstruct() {
|
||||
$this
|
||||
->setName('unverify')
|
||||
->setSynopsis(
|
||||
pht('Unverify an email address so it no longer receives mail.'))
|
||||
->setExamples('**unverify** __address__ ...')
|
||||
->setArguments(
|
||||
array(
|
||||
array(
|
||||
'name' => 'addresses',
|
||||
'wildcard' => true,
|
||||
'help' => pht('Address (or addresses) to unverify.'),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$console = PhutilConsole::getConsole();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$addresses = $args->getArg('addresses');
|
||||
if (!$addresses) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht('Specify one or more email addresses to unverify.'));
|
||||
}
|
||||
|
||||
foreach ($addresses as $address) {
|
||||
$email = id(new PhabricatorUserEmail())->loadOneWhere(
|
||||
'address = %s',
|
||||
$address);
|
||||
if (!$email) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Address "%s" is unknown.',
|
||||
$address));
|
||||
continue;
|
||||
}
|
||||
|
||||
$user_phid = $email->getUserPHID();
|
||||
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($user_phid))
|
||||
->executeOne();
|
||||
|
||||
if (!$user) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Address "%s" belongs to invalid user "%s".',
|
||||
$address,
|
||||
$user_phid));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$email->getIsVerified()) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Address "%s" (owned by "%s") is already unveriifed.',
|
||||
$address,
|
||||
$user->getUsername()));
|
||||
continue;
|
||||
}
|
||||
|
||||
$email->openTransaction();
|
||||
|
||||
$email
|
||||
->setIsVerified(0)
|
||||
->save();
|
||||
|
||||
if ($email->getIsPrimary()) {
|
||||
$user
|
||||
->setIsEmailVerified(0)
|
||||
->save();
|
||||
}
|
||||
|
||||
$email->saveTransaction();
|
||||
|
||||
if ($email->getIsPrimary()) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Unverified "%s", the primary address for "%s".',
|
||||
$address,
|
||||
$user->getUsername()));
|
||||
} else {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Unverified "%s", an address for "%s".',
|
||||
$address,
|
||||
$user->getUsername()));
|
||||
}
|
||||
}
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht('Done.'));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -41,6 +41,7 @@ final class PhabricatorSettingsApplication extends PhabricatorApplication {
|
|||
'adjust/' => 'PhabricatorSettingsAdjustController',
|
||||
'timezone/(?P<offset>[^/]+)/'
|
||||
=> 'PhabricatorSettingsTimezoneController',
|
||||
'issue/' => 'PhabricatorSettingsIssueController',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSettingsIssueController
|
||||
extends PhabricatorController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$setup_uri = id(new PhabricatorEmailAddressesSettingsPanel())
|
||||
->setViewer($viewer)
|
||||
->setUser($viewer)
|
||||
->getPanelURI();
|
||||
|
||||
$issues = array();
|
||||
if (!$viewer->getIsEmailVerified()) {
|
||||
// We could specifically detect that the user has missed email because
|
||||
// their address is unverified here and point them at Mail so they can
|
||||
// look at messages they missed.
|
||||
|
||||
// We could also detect that an administrator unverified their address
|
||||
// and let that come with a message.
|
||||
|
||||
// For now, just make sure the unverified address does not escape notice.
|
||||
$issues[] = array(
|
||||
'title' => pht('Primary Email Unverified'),
|
||||
'summary' => pht(
|
||||
'Your primary email address is unverified. You will not be able '.
|
||||
'to receive email until you verify it.'),
|
||||
'uri' => $setup_uri,
|
||||
);
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
require_celerity_resource('phabricator-notification-menu-css');
|
||||
|
||||
$items = array();
|
||||
foreach ($issues as $issue) {
|
||||
$classes = array();
|
||||
$classes[] = 'phabricator-notification';
|
||||
$classes[] = 'phabricator-notification-unread';
|
||||
|
||||
$uri = $issue['uri'];
|
||||
$title = $issue['title'];
|
||||
$summary = $issue['summary'];
|
||||
|
||||
$items[] = javelin_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' =>
|
||||
'phabricator-notification phabricator-notification-unread',
|
||||
'sigil' => 'notification',
|
||||
'meta' => array(
|
||||
'href' => $uri,
|
||||
),
|
||||
),
|
||||
array(
|
||||
phutil_tag('strong', array(), pht('%s:', $title)),
|
||||
' ',
|
||||
$summary,
|
||||
));
|
||||
}
|
||||
|
||||
$content = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'setup-issue-menu',
|
||||
),
|
||||
$items);
|
||||
} else {
|
||||
$content = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phabricator-notification no-notifications',
|
||||
),
|
||||
pht('You have no account setup issues.'));
|
||||
}
|
||||
|
||||
$header = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'phabricator-notification-header',
|
||||
),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $setup_uri,
|
||||
),
|
||||
pht('Account Setup Issues')));
|
||||
|
||||
$content = array(
|
||||
$header,
|
||||
$content,
|
||||
);
|
||||
|
||||
$json = array(
|
||||
'content' => hsprintf('%s', $content),
|
||||
'number' => count($issues),
|
||||
);
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent($json);
|
||||
}
|
||||
|
||||
}
|
|
@ -595,10 +595,74 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
}
|
||||
}
|
||||
|
||||
$user_dropdown = null;
|
||||
$user_tag = null;
|
||||
if ($viewer->isLoggedIn()) {
|
||||
if (!$viewer->getIsEmailVerified()) {
|
||||
$bubble_id = celerity_generate_unique_node_id();
|
||||
$count_id = celerity_generate_unique_node_id();
|
||||
$dropdown_id = celerity_generate_unique_node_id();
|
||||
|
||||
$settings_uri = id(new PhabricatorEmailAddressesSettingsPanel())
|
||||
->setViewer($viewer)
|
||||
->setUser($viewer)
|
||||
->getPanelURI();
|
||||
|
||||
$user_icon = javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'phabricator-main-menu-setup-icon phui-icon-view '.
|
||||
'phui-font-fa fa-user',
|
||||
'sigil' => 'menu-icon',
|
||||
));
|
||||
|
||||
$user_count = javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'phabricator-main-menu-setup-count',
|
||||
'id' => $count_id,
|
||||
),
|
||||
1);
|
||||
|
||||
$user_tag = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $settings_uri,
|
||||
'class' => 'setup-unread',
|
||||
'id' => $bubble_id,
|
||||
),
|
||||
array(
|
||||
$user_icon,
|
||||
$user_count,
|
||||
));
|
||||
|
||||
Javelin::initBehavior(
|
||||
'aphlict-dropdown',
|
||||
array(
|
||||
'bubbleID' => $bubble_id,
|
||||
'countID' => $count_id,
|
||||
'dropdownID' => $dropdown_id,
|
||||
'loadingText' => pht('Loading...'),
|
||||
'uri' => '/settings/issue/',
|
||||
'unreadClass' => 'setup-unread',
|
||||
));
|
||||
|
||||
$user_dropdown = javelin_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => $dropdown_id,
|
||||
'class' => 'phabricator-notification-menu',
|
||||
'sigil' => 'phabricator-notification-menu',
|
||||
'style' => 'display: none;',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$dropdowns = array(
|
||||
$notification_dropdown,
|
||||
$message_notification_dropdown,
|
||||
$setup_notification_dropdown,
|
||||
$user_dropdown,
|
||||
);
|
||||
|
||||
return array(
|
||||
|
@ -606,6 +670,7 @@ final class PhabricatorMainMenuView extends AphrontView {
|
|||
$bubble_tag,
|
||||
$message_tag,
|
||||
$setup_tag,
|
||||
$user_tag,
|
||||
),
|
||||
$dropdowns,
|
||||
$aural,
|
||||
|
|
Loading…
Reference in a new issue