mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 08:42:41 +01:00
Add "Auth Messages" to support customizing onboarding/welcome flows
Summary: Ref T13222. Long ago, we had a Config option (`welcome.html`) to let you dump HTML onto the login screen, but this was relatively hard to use and not good from a security perspective. In some cases this was obsoleted by Dashboards, but there's at least some remaining set of use cases for actual login instructions on the login screen. For example, WMF has some guidance on //which// SSO mechanism to use based on what types of account you have. On `secure`, users assume they can register by clicking "Log In With GitHub" or whatever, and it might reduce frustration to tell them upfront that registration is closed. Some other types of auth messaging could also either use customization or defaults (e.g., the invite/welcome/approve mail). We could do this with a bunch of Config options, but I'd generally like to move to a world where there's less stuff in Config and more configuration is contextual. I think it tends to be easier to use, and we get a lot of fringe benefits (granular permissions, API, normal transaction logs, more abililty to customize workflows and provide contextual help/hints, etc). Here, for example, we can provide a remarkup preview, which would be trickier with Config. This does not actually do anything yet. Test Plan: {F6137541} Reviewers: amckinley Reviewed By: amckinley Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam Maniphest Tasks: T13222 Differential Revision: https://secure.phabricator.com/D19992
This commit is contained in:
parent
ab7aceaabf
commit
2c713b2d25
22 changed files with 812 additions and 1 deletions
|
@ -0,0 +1,8 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_auth.auth_message (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
phid VARBINARY(64) NOT NULL,
|
||||||
|
messageKey VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
messageText LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT},
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL
|
||||||
|
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
|
|
@ -0,0 +1,19 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_auth.auth_messagetransaction (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
phid VARBINARY(64) NOT NULL,
|
||||||
|
authorPHID VARBINARY(64) NOT NULL,
|
||||||
|
objectPHID VARBINARY(64) NOT NULL,
|
||||||
|
viewPolicy VARBINARY(64) NOT NULL,
|
||||||
|
editPolicy VARBINARY(64) NOT NULL,
|
||||||
|
commentPHID VARBINARY(64) DEFAULT NULL,
|
||||||
|
commentVersion INT UNSIGNED NOT NULL,
|
||||||
|
transactionType VARCHAR(32) NOT NULL,
|
||||||
|
oldValue LONGTEXT NOT NULL,
|
||||||
|
newValue LONGTEXT NOT NULL,
|
||||||
|
contentSource LONGTEXT NOT NULL,
|
||||||
|
metadata LONGTEXT NOT NULL,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_phid` (`phid`),
|
||||||
|
KEY `key_object` (`objectPHID`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};
|
|
@ -2246,6 +2246,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthListController' => 'applications/auth/controller/config/PhabricatorAuthListController.php',
|
'PhabricatorAuthListController' => 'applications/auth/controller/config/PhabricatorAuthListController.php',
|
||||||
'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php',
|
'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php',
|
||||||
'PhabricatorAuthLoginHandler' => 'applications/auth/handler/PhabricatorAuthLoginHandler.php',
|
'PhabricatorAuthLoginHandler' => 'applications/auth/handler/PhabricatorAuthLoginHandler.php',
|
||||||
|
'PhabricatorAuthLoginMessageType' => 'applications/auth/message/PhabricatorAuthLoginMessageType.php',
|
||||||
'PhabricatorAuthLogoutConduitAPIMethod' => 'applications/auth/conduit/PhabricatorAuthLogoutConduitAPIMethod.php',
|
'PhabricatorAuthLogoutConduitAPIMethod' => 'applications/auth/conduit/PhabricatorAuthLogoutConduitAPIMethod.php',
|
||||||
'PhabricatorAuthMFAEditEngineExtension' => 'applications/auth/engineextension/PhabricatorAuthMFAEditEngineExtension.php',
|
'PhabricatorAuthMFAEditEngineExtension' => 'applications/auth/engineextension/PhabricatorAuthMFAEditEngineExtension.php',
|
||||||
'PhabricatorAuthMainMenuBarExtension' => 'applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php',
|
'PhabricatorAuthMainMenuBarExtension' => 'applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php',
|
||||||
|
@ -2261,6 +2262,20 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthManagementUntrustOAuthClientWorkflow' => 'applications/auth/management/PhabricatorAuthManagementUntrustOAuthClientWorkflow.php',
|
'PhabricatorAuthManagementUntrustOAuthClientWorkflow' => 'applications/auth/management/PhabricatorAuthManagementUntrustOAuthClientWorkflow.php',
|
||||||
'PhabricatorAuthManagementVerifyWorkflow' => 'applications/auth/management/PhabricatorAuthManagementVerifyWorkflow.php',
|
'PhabricatorAuthManagementVerifyWorkflow' => 'applications/auth/management/PhabricatorAuthManagementVerifyWorkflow.php',
|
||||||
'PhabricatorAuthManagementWorkflow' => 'applications/auth/management/PhabricatorAuthManagementWorkflow.php',
|
'PhabricatorAuthManagementWorkflow' => 'applications/auth/management/PhabricatorAuthManagementWorkflow.php',
|
||||||
|
'PhabricatorAuthMessage' => 'applications/auth/storage/PhabricatorAuthMessage.php',
|
||||||
|
'PhabricatorAuthMessageController' => 'applications/auth/controller/message/PhabricatorAuthMessageController.php',
|
||||||
|
'PhabricatorAuthMessageEditController' => 'applications/auth/controller/message/PhabricatorAuthMessageEditController.php',
|
||||||
|
'PhabricatorAuthMessageEditEngine' => 'applications/auth/editor/PhabricatorAuthMessageEditEngine.php',
|
||||||
|
'PhabricatorAuthMessageEditor' => 'applications/auth/editor/PhabricatorAuthMessageEditor.php',
|
||||||
|
'PhabricatorAuthMessageListController' => 'applications/auth/controller/message/PhabricatorAuthMessageListController.php',
|
||||||
|
'PhabricatorAuthMessagePHIDType' => 'applications/auth/phid/PhabricatorAuthMessagePHIDType.php',
|
||||||
|
'PhabricatorAuthMessageQuery' => 'applications/auth/query/PhabricatorAuthMessageQuery.php',
|
||||||
|
'PhabricatorAuthMessageTextTransaction' => 'applications/auth/xaction/PhabricatorAuthMessageTextTransaction.php',
|
||||||
|
'PhabricatorAuthMessageTransaction' => 'applications/auth/storage/PhabricatorAuthMessageTransaction.php',
|
||||||
|
'PhabricatorAuthMessageTransactionQuery' => 'applications/auth/query/PhabricatorAuthMessageTransactionQuery.php',
|
||||||
|
'PhabricatorAuthMessageTransactionType' => 'applications/auth/xaction/PhabricatorAuthMessageTransactionType.php',
|
||||||
|
'PhabricatorAuthMessageType' => 'applications/auth/message/PhabricatorAuthMessageType.php',
|
||||||
|
'PhabricatorAuthMessageViewController' => 'applications/auth/controller/message/PhabricatorAuthMessageViewController.php',
|
||||||
'PhabricatorAuthNeedsApprovalController' => 'applications/auth/controller/PhabricatorAuthNeedsApprovalController.php',
|
'PhabricatorAuthNeedsApprovalController' => 'applications/auth/controller/PhabricatorAuthNeedsApprovalController.php',
|
||||||
'PhabricatorAuthNeedsMultiFactorController' => 'applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php',
|
'PhabricatorAuthNeedsMultiFactorController' => 'applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php',
|
||||||
'PhabricatorAuthNewController' => 'applications/auth/controller/config/PhabricatorAuthNewController.php',
|
'PhabricatorAuthNewController' => 'applications/auth/controller/config/PhabricatorAuthNewController.php',
|
||||||
|
@ -2337,6 +2352,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthTryFactorAction' => 'applications/auth/action/PhabricatorAuthTryFactorAction.php',
|
'PhabricatorAuthTryFactorAction' => 'applications/auth/action/PhabricatorAuthTryFactorAction.php',
|
||||||
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
|
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
|
||||||
'PhabricatorAuthValidateController' => 'applications/auth/controller/PhabricatorAuthValidateController.php',
|
'PhabricatorAuthValidateController' => 'applications/auth/controller/PhabricatorAuthValidateController.php',
|
||||||
|
'PhabricatorAuthWelcomeMailMessageType' => 'applications/auth/message/PhabricatorAuthWelcomeMailMessageType.php',
|
||||||
'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php',
|
'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php',
|
||||||
'PhabricatorAutoEventListener' => 'infrastructure/events/PhabricatorAutoEventListener.php',
|
'PhabricatorAutoEventListener' => 'infrastructure/events/PhabricatorAutoEventListener.php',
|
||||||
'PhabricatorBadgesApplication' => 'applications/badges/application/PhabricatorBadgesApplication.php',
|
'PhabricatorBadgesApplication' => 'applications/badges/application/PhabricatorBadgesApplication.php',
|
||||||
|
@ -7920,6 +7936,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthListController' => 'PhabricatorAuthProviderConfigController',
|
'PhabricatorAuthListController' => 'PhabricatorAuthProviderConfigController',
|
||||||
'PhabricatorAuthLoginController' => 'PhabricatorAuthController',
|
'PhabricatorAuthLoginController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthLoginHandler' => 'Phobject',
|
'PhabricatorAuthLoginHandler' => 'Phobject',
|
||||||
|
'PhabricatorAuthLoginMessageType' => 'PhabricatorAuthMessageType',
|
||||||
'PhabricatorAuthLogoutConduitAPIMethod' => 'PhabricatorAuthConduitAPIMethod',
|
'PhabricatorAuthLogoutConduitAPIMethod' => 'PhabricatorAuthConduitAPIMethod',
|
||||||
'PhabricatorAuthMFAEditEngineExtension' => 'PhabricatorEditEngineExtension',
|
'PhabricatorAuthMFAEditEngineExtension' => 'PhabricatorEditEngineExtension',
|
||||||
'PhabricatorAuthMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
'PhabricatorAuthMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||||
|
@ -7935,6 +7952,25 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthManagementUntrustOAuthClientWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
'PhabricatorAuthManagementUntrustOAuthClientWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||||
'PhabricatorAuthManagementVerifyWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
'PhabricatorAuthManagementVerifyWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||||
'PhabricatorAuthManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
'PhabricatorAuthManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||||
|
'PhabricatorAuthMessage' => array(
|
||||||
|
'PhabricatorAuthDAO',
|
||||||
|
'PhabricatorApplicationTransactionInterface',
|
||||||
|
'PhabricatorPolicyInterface',
|
||||||
|
'PhabricatorDestructibleInterface',
|
||||||
|
),
|
||||||
|
'PhabricatorAuthMessageController' => 'PhabricatorAuthProviderController',
|
||||||
|
'PhabricatorAuthMessageEditController' => 'PhabricatorAuthMessageController',
|
||||||
|
'PhabricatorAuthMessageEditEngine' => 'PhabricatorEditEngine',
|
||||||
|
'PhabricatorAuthMessageEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
|
'PhabricatorAuthMessageListController' => 'PhabricatorAuthProviderController',
|
||||||
|
'PhabricatorAuthMessagePHIDType' => 'PhabricatorPHIDType',
|
||||||
|
'PhabricatorAuthMessageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorAuthMessageTextTransaction' => 'PhabricatorAuthMessageTransactionType',
|
||||||
|
'PhabricatorAuthMessageTransaction' => 'PhabricatorModularTransaction',
|
||||||
|
'PhabricatorAuthMessageTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
|
'PhabricatorAuthMessageTransactionType' => 'PhabricatorModularTransactionType',
|
||||||
|
'PhabricatorAuthMessageType' => 'Phobject',
|
||||||
|
'PhabricatorAuthMessageViewController' => 'PhabricatorAuthMessageController',
|
||||||
'PhabricatorAuthNeedsApprovalController' => 'PhabricatorAuthController',
|
'PhabricatorAuthNeedsApprovalController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthNeedsMultiFactorController' => 'PhabricatorAuthController',
|
'PhabricatorAuthNeedsMultiFactorController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthNewController' => 'PhabricatorAuthProviderConfigController',
|
'PhabricatorAuthNewController' => 'PhabricatorAuthProviderConfigController',
|
||||||
|
@ -8030,6 +8066,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthTryFactorAction' => 'PhabricatorSystemAction',
|
'PhabricatorAuthTryFactorAction' => 'PhabricatorSystemAction',
|
||||||
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
|
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthValidateController' => 'PhabricatorAuthController',
|
'PhabricatorAuthValidateController' => 'PhabricatorAuthController',
|
||||||
|
'PhabricatorAuthWelcomeMailMessageType' => 'PhabricatorAuthMessageType',
|
||||||
'PhabricatorAuthenticationConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorAuthenticationConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorAutoEventListener' => 'PhabricatorEventListener',
|
'PhabricatorAutoEventListener' => 'PhabricatorEventListener',
|
||||||
'PhabricatorBadgesApplication' => 'PhabricatorApplication',
|
'PhabricatorBadgesApplication' => 'PhabricatorApplication',
|
||||||
|
|
|
@ -94,6 +94,16 @@ final class PhabricatorAuthApplication extends PhabricatorApplication {
|
||||||
'(?P<id>[1-9]\d*)/' =>
|
'(?P<id>[1-9]\d*)/' =>
|
||||||
'PhabricatorAuthFactorProviderViewController',
|
'PhabricatorAuthFactorProviderViewController',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'message/' => array(
|
||||||
|
$this->getQueryRoutePattern() =>
|
||||||
|
'PhabricatorAuthMessageListController',
|
||||||
|
$this->getEditRoutePattern('edit/') =>
|
||||||
|
'PhabricatorAuthMessageEditController',
|
||||||
|
'(?P<id>[1-9]\d*)/' =>
|
||||||
|
'PhabricatorAuthMessageViewController',
|
||||||
|
),
|
||||||
|
|
||||||
),
|
),
|
||||||
|
|
||||||
'/oauth/(?P<provider>\w+)/login/'
|
'/oauth/(?P<provider>\w+)/login/'
|
||||||
|
|
|
@ -31,6 +31,20 @@ abstract class PhabricatorAuthProviderController
|
||||||
->setHref($this->getApplicationURI('mfa/'))
|
->setHref($this->getApplicationURI('mfa/'))
|
||||||
->setIcon('fa-mobile'));
|
->setIcon('fa-mobile'));
|
||||||
|
|
||||||
|
$nav->addMenuItem(
|
||||||
|
id(new PHUIListItemView())
|
||||||
|
->setName(pht('Onboarding'))
|
||||||
|
->setType(PHUIListItemView::TYPE_LABEL));
|
||||||
|
|
||||||
|
$nav->addMenuItem(
|
||||||
|
id(new PHUIListItemView())
|
||||||
|
->setKey('message')
|
||||||
|
->setName(pht('Customize Messages'))
|
||||||
|
->setType(PHUIListItemView::TYPE_LINK)
|
||||||
|
->setHref($this->getApplicationURI('message/'))
|
||||||
|
->setIcon('fa-commenting-o'));
|
||||||
|
|
||||||
|
|
||||||
$nav->selectFilter(null);
|
$nav->selectFilter(null);
|
||||||
|
|
||||||
return $nav;
|
return $nav;
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorAuthMessageController
|
||||||
|
extends PhabricatorAuthProviderController {
|
||||||
|
|
||||||
|
protected function buildApplicationCrumbs() {
|
||||||
|
return parent::buildApplicationCrumbs()
|
||||||
|
->addTextCrumb(pht('Messages'), $this->getApplicationURI('message/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessageEditController
|
||||||
|
extends PhabricatorAuthMessageController {
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$this->requireApplicationCapability(
|
||||||
|
AuthManageProvidersCapability::CAPABILITY);
|
||||||
|
|
||||||
|
$engine = id(new PhabricatorAuthMessageEditEngine())
|
||||||
|
->setController($this);
|
||||||
|
|
||||||
|
$id = $request->getURIData('id');
|
||||||
|
if (!$id) {
|
||||||
|
$message_key = $request->getStr('messageKey');
|
||||||
|
|
||||||
|
$message_types = PhabricatorAuthMessageType::getAllMessageTypes();
|
||||||
|
$message_type = idx($message_types, $message_key);
|
||||||
|
if (!$message_type) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$engine
|
||||||
|
->addContextParameter('messageKey', $message_key)
|
||||||
|
->setMessageType($message_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $engine->buildResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessageListController
|
||||||
|
extends PhabricatorAuthProviderController {
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$can_manage = $this->hasApplicationCapability(
|
||||||
|
AuthManageProvidersCapability::CAPABILITY);
|
||||||
|
|
||||||
|
$types = PhabricatorAuthMessageType::getAllMessageTypes();
|
||||||
|
|
||||||
|
$messages = id(new PhabricatorAuthMessageQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->execute();
|
||||||
|
$messages = mpull($messages, null, 'getMessageKey');
|
||||||
|
|
||||||
|
$list = new PHUIObjectItemListView();
|
||||||
|
foreach ($types as $type) {
|
||||||
|
$message = idx($messages, $type->getMessageTypeKey());
|
||||||
|
if ($message) {
|
||||||
|
$href = $message->getURI();
|
||||||
|
$name = $message->getMessageTypeDisplayName();
|
||||||
|
} else {
|
||||||
|
$href = '/auth/message/edit/?messageKey='.$type->getMessageTypeKey();
|
||||||
|
$name = $type->getDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
$item = id(new PHUIObjectItemView())
|
||||||
|
->setHeader($name)
|
||||||
|
->setHref($href)
|
||||||
|
->addAttribute($type->getShortDescription());
|
||||||
|
|
||||||
|
if ($message) {
|
||||||
|
$item->addIcon('fa-circle', pht('Customized'));
|
||||||
|
} else {
|
||||||
|
$item->addIcon('fa-circle-o grey', pht('Default'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$list->addItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs()
|
||||||
|
->addTextCrumb(pht('Messages'))
|
||||||
|
->setBorder(true);
|
||||||
|
|
||||||
|
$list->setFlush(true);
|
||||||
|
$list = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText(pht('Auth Messages'))
|
||||||
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||||
|
->appendChild($list);
|
||||||
|
|
||||||
|
$title = pht('Auth Messages');
|
||||||
|
$header = id(new PHUIHeaderView())
|
||||||
|
->setHeader($title)
|
||||||
|
->setHeaderIcon('fa-commenting-o');
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setFooter(
|
||||||
|
array(
|
||||||
|
$list,
|
||||||
|
));
|
||||||
|
|
||||||
|
$nav = $this->newNavigation()
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->appendChild($view);
|
||||||
|
|
||||||
|
$nav->selectFilter('message');
|
||||||
|
|
||||||
|
return $this->newPage()
|
||||||
|
->setTitle($title)
|
||||||
|
->appendChild($nav);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessageViewController
|
||||||
|
extends PhabricatorAuthMessageController {
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$this->requireApplicationCapability(
|
||||||
|
AuthManageProvidersCapability::CAPABILITY);
|
||||||
|
|
||||||
|
$message = id(new PhabricatorAuthMessageQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($request->getURIData('id')))
|
||||||
|
->executeOne();
|
||||||
|
if (!$message) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs()
|
||||||
|
->addTextCrumb($message->getObjectName())
|
||||||
|
->setBorder(true);
|
||||||
|
|
||||||
|
$header = $this->buildHeaderView($message);
|
||||||
|
$properties = $this->buildPropertiesView($message);
|
||||||
|
$curtain = $this->buildCurtain($message);
|
||||||
|
|
||||||
|
$timeline = $this->buildTransactionTimeline(
|
||||||
|
$message,
|
||||||
|
new PhabricatorAuthMessageTransactionQuery());
|
||||||
|
$timeline->setShouldTerminate(true);
|
||||||
|
|
||||||
|
$view = id(new PHUITwoColumnView())
|
||||||
|
->setHeader($header)
|
||||||
|
->setCurtain($curtain)
|
||||||
|
->setMainColumn(
|
||||||
|
array(
|
||||||
|
$timeline,
|
||||||
|
))
|
||||||
|
->addPropertySection(pht('Details'), $properties);
|
||||||
|
|
||||||
|
return $this->newPage()
|
||||||
|
->setTitle($message->getMessageTypeDisplayName())
|
||||||
|
->setCrumbs($crumbs)
|
||||||
|
->setPageObjectPHIDs(
|
||||||
|
array(
|
||||||
|
$message->getPHID(),
|
||||||
|
))
|
||||||
|
->appendChild($view);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildHeaderView(PhabricatorAuthMessage $message) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$view = id(new PHUIHeaderView())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setHeader($message->getMessageTypeDisplayName());
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildPropertiesView(PhabricatorAuthMessage $message) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$view = id(new PHUIPropertyListView())
|
||||||
|
->setViewer($viewer);
|
||||||
|
|
||||||
|
$view->addProperty(
|
||||||
|
pht('Description'),
|
||||||
|
$message->getMessageType()->getShortDescription());
|
||||||
|
|
||||||
|
$view->addSectionHeader(
|
||||||
|
pht('Message Preview'),
|
||||||
|
PHUIPropertyListView::ICON_SUMMARY);
|
||||||
|
|
||||||
|
$view->addTextContent(
|
||||||
|
new PHUIRemarkupView($viewer, $message->getMessageText()));
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildCurtain(PhabricatorAuthMessage $message) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$id = $message->getID();
|
||||||
|
|
||||||
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$viewer,
|
||||||
|
$message,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
|
$curtain = $this->newCurtainView($message);
|
||||||
|
|
||||||
|
$curtain->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setName(pht('Edit Message'))
|
||||||
|
->setIcon('fa-pencil')
|
||||||
|
->setHref($this->getApplicationURI("message/edit/{$id}/"))
|
||||||
|
->setDisabled(!$can_edit)
|
||||||
|
->setWorkflow(!$can_edit));
|
||||||
|
|
||||||
|
return $curtain;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ final class PhabricatorAuthFactorProviderEditController
|
||||||
$engine
|
$engine
|
||||||
->addContextParameter('providerFactorKey', $factor_key)
|
->addContextParameter('providerFactorKey', $factor_key)
|
||||||
->setProviderFactor($factor);
|
->setProviderFactor($factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $engine->buildResponse();
|
return $engine->buildResponse();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessageEditEngine
|
||||||
|
extends PhabricatorEditEngine {
|
||||||
|
|
||||||
|
private $messageType;
|
||||||
|
|
||||||
|
const ENGINECONST = 'auth.message';
|
||||||
|
|
||||||
|
public function isEngineConfigurable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEngineName() {
|
||||||
|
return pht('Auth Messages');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSummaryHeader() {
|
||||||
|
return pht('Edit Auth Messages');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSummaryText() {
|
||||||
|
return pht('This engine is used to edit authentication messages.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEngineApplicationClass() {
|
||||||
|
return 'PhabricatorAuthApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMessageType(PhabricatorAuthMessageType $type) {
|
||||||
|
$this->messageType = $type;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMessageType() {
|
||||||
|
return $this->messageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newEditableObject() {
|
||||||
|
$type = $this->getMessageType();
|
||||||
|
|
||||||
|
if ($type) {
|
||||||
|
$message = PhabricatorAuthMessage::initializeNewMessage($type);
|
||||||
|
} else {
|
||||||
|
$message = new PhabricatorAuthMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newObjectQuery() {
|
||||||
|
return new PhabricatorAuthMessageQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateTitleText($object) {
|
||||||
|
return pht('Create Auth Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateButtonText($object) {
|
||||||
|
return pht('Create Auth Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectEditTitleText($object) {
|
||||||
|
return pht('Edit Auth Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectEditShortText($object) {
|
||||||
|
return $object->getObjectName();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateShortText() {
|
||||||
|
return pht('Create Auth Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectName() {
|
||||||
|
return pht('Auth Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getEditorURI() {
|
||||||
|
return '/auth/message/edit/';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectCreateCancelURI($object) {
|
||||||
|
return '/auth/message/';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjectViewURI($object) {
|
||||||
|
return $object->getURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCreateNewObjectPolicy() {
|
||||||
|
return $this->getApplication()->getPolicy(
|
||||||
|
AuthManageProvidersCapability::CAPABILITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildCustomEditFields($object) {
|
||||||
|
return array(
|
||||||
|
id(new PhabricatorRemarkupEditField())
|
||||||
|
->setKey('messageText')
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorAuthMessageTextTransaction::TRANSACTIONTYPE)
|
||||||
|
->setLabel(pht('Message Text'))
|
||||||
|
->setDescription(pht('Custom text for the message.'))
|
||||||
|
->setValue($object->getMessageText()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessageEditor
|
||||||
|
extends PhabricatorApplicationTransactionEditor {
|
||||||
|
|
||||||
|
public function getEditorApplicationClass() {
|
||||||
|
return 'PhabricatorAuthApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEditorObjectsDescription() {
|
||||||
|
return pht('Auth Messages');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreateObjectTitle($author, $object) {
|
||||||
|
return pht('%s created this message.', $author);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreateObjectTitleForFeed($author, $object) {
|
||||||
|
return pht('%s created %s.', $author, $object);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthLoginMessageType
|
||||||
|
extends PhabricatorAuthMessageType {
|
||||||
|
|
||||||
|
const MESSAGEKEY = 'auth.login';
|
||||||
|
|
||||||
|
public function getDisplayName() {
|
||||||
|
return pht('Login Screen Instructions');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShortDescription() {
|
||||||
|
return pht(
|
||||||
|
'Guidance shown on the main login screen before users log in or '.
|
||||||
|
'register.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
src/applications/auth/message/PhabricatorAuthMessageType.php
Normal file
32
src/applications/auth/message/PhabricatorAuthMessageType.php
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorAuthMessageType
|
||||||
|
extends Phobject {
|
||||||
|
|
||||||
|
final public function getMessageTypeKey() {
|
||||||
|
return $this->getPhobjectClassConstant('MESSAGEKEY', 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function getAllMessageTypes() {
|
||||||
|
return id(new PhutilClassMapQuery())
|
||||||
|
->setAncestorClass(__CLASS__)
|
||||||
|
->setUniqueMethod('getMessageTypeKey')
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
final public static function newFromKey($key) {
|
||||||
|
$types = self::getAllMessageTypes();
|
||||||
|
|
||||||
|
if (empty($types[$key])) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'No message type exists with key "%s".',
|
||||||
|
$key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone $types[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function getDisplayName();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthWelcomeMailMessageType
|
||||||
|
extends PhabricatorAuthMessageType {
|
||||||
|
|
||||||
|
const MESSAGEKEY = 'mail.welcome';
|
||||||
|
|
||||||
|
public function getDisplayName() {
|
||||||
|
return pht('Welcome Email Body');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShortDescription() {
|
||||||
|
return pht(
|
||||||
|
'Custom instructions included in "Welcome" mail when an '.
|
||||||
|
'administrator creates a user account.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessagePHIDType extends PhabricatorPHIDType {
|
||||||
|
|
||||||
|
const TYPECONST = 'AMSG';
|
||||||
|
|
||||||
|
public function getTypeName() {
|
||||||
|
return pht('Auth Message');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newObject() {
|
||||||
|
return new PhabricatorAuthMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPHIDTypeApplicationClass() {
|
||||||
|
return 'PhabricatorAuthApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildQueryForObjects(
|
||||||
|
PhabricatorObjectQuery $query,
|
||||||
|
array $phids) {
|
||||||
|
return new PhabricatorAuthMessageQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadHandles(
|
||||||
|
PhabricatorHandleQuery $query,
|
||||||
|
array $handles,
|
||||||
|
array $objects) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
83
src/applications/auth/query/PhabricatorAuthMessageQuery.php
Normal file
83
src/applications/auth/query/PhabricatorAuthMessageQuery.php
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessageQuery
|
||||||
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
|
private $ids;
|
||||||
|
private $phids;
|
||||||
|
private $messageKeys;
|
||||||
|
|
||||||
|
public function withIDs(array $ids) {
|
||||||
|
$this->ids = $ids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withPHIDs(array $phids) {
|
||||||
|
$this->phids = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withMessageKeys(array $keys) {
|
||||||
|
$this->messageKeys = $keys;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newResultObject() {
|
||||||
|
return new PhabricatorAuthMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadPage() {
|
||||||
|
return $this->loadStandardPage($this->newResultObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
|
if ($this->ids !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'id IN (%Ld)',
|
||||||
|
$this->ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->phids !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'phid IN (%Ls)',
|
||||||
|
$this->phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->messageKeys !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'messageKey IN (%Ls)',
|
||||||
|
$this->messageKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $where;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function willFilterPage(array $messages) {
|
||||||
|
$message_types = PhabricatorAuthMessageType::getAllMessageTypes();
|
||||||
|
|
||||||
|
foreach ($messages as $key => $message) {
|
||||||
|
$message_key = $message->getMessageKey();
|
||||||
|
|
||||||
|
$message_type = idx($message_types, $message_key);
|
||||||
|
if (!$message_type) {
|
||||||
|
unset($messages[$key]);
|
||||||
|
$this->didRejectResult($message);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$message->attachMessageType($message_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQueryApplicationClass() {
|
||||||
|
return 'PhabricatorAuthApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessageTransactionQuery
|
||||||
|
extends PhabricatorApplicationTransactionQuery {
|
||||||
|
|
||||||
|
public function getTemplateApplicationTransaction() {
|
||||||
|
return new PhabricatorAuthMessageTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
116
src/applications/auth/storage/PhabricatorAuthMessage.php
Normal file
116
src/applications/auth/storage/PhabricatorAuthMessage.php
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessage
|
||||||
|
extends PhabricatorAuthDAO
|
||||||
|
implements
|
||||||
|
PhabricatorApplicationTransactionInterface,
|
||||||
|
PhabricatorPolicyInterface,
|
||||||
|
PhabricatorDestructibleInterface {
|
||||||
|
|
||||||
|
protected $messageKey;
|
||||||
|
protected $messageText;
|
||||||
|
|
||||||
|
private $messageType = self::ATTACHABLE;
|
||||||
|
|
||||||
|
public static function initializeNewMessage(
|
||||||
|
PhabricatorAuthMessageType $type) {
|
||||||
|
|
||||||
|
return id(new self())
|
||||||
|
->setMessageKey($type->getMessageTypeKey())
|
||||||
|
->attachMessageType($type);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getConfiguration() {
|
||||||
|
return array(
|
||||||
|
self::CONFIG_AUX_PHID => true,
|
||||||
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
|
'messageKey' => 'text64',
|
||||||
|
'messageText' => 'text',
|
||||||
|
),
|
||||||
|
self::CONFIG_KEY_SCHEMA => array(
|
||||||
|
'key_type' => array(
|
||||||
|
'columns' => array('messageKey'),
|
||||||
|
'unique' => true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) + parent::getConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPHIDType() {
|
||||||
|
return PhabricatorAuthMessagePHIDType::TYPECONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObjectName() {
|
||||||
|
return pht('Auth Message %d', $this->getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getURI() {
|
||||||
|
return urisprintf('/auth/message/%s', $this->getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attachMessageType(PhabricatorAuthMessageType $type) {
|
||||||
|
$this->messageType = $type;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMessageType() {
|
||||||
|
return $this->assertAttached($this->messageType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMessageTypeDisplayName() {
|
||||||
|
return $this->getMessageType()->getDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getCapabilities() {
|
||||||
|
return array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPolicy($capability) {
|
||||||
|
switch ($capability) {
|
||||||
|
case PhabricatorPolicyCapability::CAN_VIEW:
|
||||||
|
return PhabricatorPolicies::getMostOpenPolicy();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||||
|
switch ($capability) {
|
||||||
|
case PhabricatorPolicyCapability::CAN_VIEW:
|
||||||
|
// Even if an install doesn't allow public users, you can still view
|
||||||
|
// auth messages: otherwise, we can't do things like show you
|
||||||
|
// guidance on the login screen.
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getApplicationTransactionEditor() {
|
||||||
|
return new PhabricatorAuthMessageEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionTemplate() {
|
||||||
|
return new PhabricatorAuthMessageTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function destroyObjectPermanently(
|
||||||
|
PhabricatorDestructionEngine $engine) {
|
||||||
|
$this->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessageTransaction
|
||||||
|
extends PhabricatorModularTransaction {
|
||||||
|
|
||||||
|
public function getApplicationName() {
|
||||||
|
return 'auth';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationTransactionType() {
|
||||||
|
return PhabricatorAuthMessagePHIDType::TYPECONST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBaseTransactionClass() {
|
||||||
|
return 'PhabricatorAuthMessageTransactionType';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthMessageTextTransaction
|
||||||
|
extends PhabricatorAuthMessageTransactionType {
|
||||||
|
|
||||||
|
const TRANSACTIONTYPE = 'text';
|
||||||
|
|
||||||
|
public function generateOldValue($object) {
|
||||||
|
return $object->getMessageText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyInternalEffects($object, $value) {
|
||||||
|
$object->setMessageText($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
return pht(
|
||||||
|
'%s updated the message text.',
|
||||||
|
$this->renderAuthor());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasChangeDetailView() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMailDiffSectionHeader() {
|
||||||
|
return pht('CHANGES TO MESSAGE');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newChangeDetailView() {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setOldText($this->getOldValue())
|
||||||
|
->setNewText($this->getNewValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class PhabricatorAuthMessageTransactionType
|
||||||
|
extends PhabricatorModularTransactionType {}
|
Loading…
Reference in a new issue