mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-15 01:50:55 +01:00
(stable) Promote 2017 Week 51
This commit is contained in:
commit
e620f8d930
13 changed files with 297 additions and 113 deletions
|
@ -2112,6 +2112,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuthSessionGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthSessionGarbageCollector.php',
|
||||
'PhabricatorAuthSessionInfo' => 'applications/auth/data/PhabricatorAuthSessionInfo.php',
|
||||
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
|
||||
'PhabricatorAuthSetPasswordController' => 'applications/auth/controller/PhabricatorAuthSetPasswordController.php',
|
||||
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
|
||||
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
|
||||
'PhabricatorAuthTOTPKeyTemporaryTokenType' => 'applications/auth/factor/PhabricatorAuthTOTPKeyTemporaryTokenType.php',
|
||||
|
@ -7377,6 +7378,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuthSessionGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||
'PhabricatorAuthSessionInfo' => 'Phobject',
|
||||
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorAuthSetPasswordController' => 'PhabricatorAuthController',
|
||||
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
|
||||
'PhabricatorAuthTOTPKeyTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||
|
|
|
@ -84,6 +84,7 @@ final class PhabricatorAuthApplication extends PhabricatorApplication {
|
|||
=> 'PhabricatorAuthSSHKeyDeactivateController',
|
||||
'view/(?P<id>\d+)/' => 'PhabricatorAuthSSHKeyViewController',
|
||||
),
|
||||
'password/' => 'PhabricatorAuthSetPasswordController',
|
||||
),
|
||||
|
||||
'/oauth/(?P<provider>\w+)/login/'
|
||||
|
|
|
@ -139,8 +139,7 @@ final class PhabricatorAuthOneTimeLoginController
|
|||
->save();
|
||||
unset($unguarded);
|
||||
|
||||
$username = $target_user->getUsername();
|
||||
$panel_uri = "/settings/user/{$username}/page/password/";
|
||||
$panel_uri = '/auth/password/';
|
||||
|
||||
$next = (string)id(new PhutilURI($panel_uri))
|
||||
->setQueryParams(
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorAuthSetPasswordController
|
||||
extends PhabricatorAuthController {
|
||||
|
||||
public function shouldAllowPartialSessions() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldAllowLegallyNonCompliantUsers() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if (!PhabricatorPasswordAuthProvider::getPasswordProvider()) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
|
||||
$viewer,
|
||||
$request,
|
||||
'/');
|
||||
|
||||
$key = $request->getStr('key');
|
||||
$password_type = PhabricatorAuthPasswordResetTemporaryTokenType::TOKENTYPE;
|
||||
if (!$key) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$auth_token = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||
->setViewer($viewer)
|
||||
->withTokenResources(array($viewer->getPHID()))
|
||||
->withTokenTypes(array($password_type))
|
||||
->withTokenCodes(array(PhabricatorHash::weakDigest($key)))
|
||||
->withExpired(false)
|
||||
->executeOne();
|
||||
if (!$auth_token) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length');
|
||||
$min_len = (int)$min_len;
|
||||
|
||||
$e_password = true;
|
||||
$e_confirm = true;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
$password = $request->getStr('password');
|
||||
$confirm = $request->getStr('confirm');
|
||||
|
||||
$e_password = null;
|
||||
$e_confirm = null;
|
||||
|
||||
if (!strlen($password)) {
|
||||
$errors[] = pht('You must choose a password or skip this step.');
|
||||
$e_password = pht('Required');
|
||||
} else if (strlen($password) < $min_len) {
|
||||
$errors[] = pht(
|
||||
'The selected password is too short. Passwords must be a minimum '.
|
||||
'of %s characters.',
|
||||
new PhutilNumber($min_len));
|
||||
$e_password = pht('Too Short');
|
||||
} else if (!strlen($confirm)) {
|
||||
$errors[] = pht('You must confirm the selecetd password.');
|
||||
$e_confirm = pht('Required');
|
||||
} else if ($password !== $confirm) {
|
||||
$errors[] = pht('The password and confirmation do not match.');
|
||||
$e_password = pht('Invalid');
|
||||
$e_confirm = pht('Invalid');
|
||||
} else if (PhabricatorCommonPasswords::isCommonPassword($password)) {
|
||||
$e_password = pht('Very Weak');
|
||||
$errors[] = pht(
|
||||
'The selected password is very weak: it is one of the most common '.
|
||||
'passwords in use. Choose a stronger password.');
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$envelope = new PhutilOpaqueEnvelope($password);
|
||||
|
||||
// This write is unguarded because the CSRF token has already
|
||||
// been checked in the call to $request->isFormPost() and
|
||||
// the CSRF token depends on the password hash, so when it
|
||||
// is changed here the CSRF token check will fail.
|
||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
|
||||
id(new PhabricatorUserEditor())
|
||||
->setActor($viewer)
|
||||
->changePassword($viewer, $envelope);
|
||||
|
||||
unset($unguarded);
|
||||
|
||||
// Destroy the token.
|
||||
$auth_token->delete();
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI('/');
|
||||
}
|
||||
}
|
||||
|
||||
$len_caption = null;
|
||||
if ($min_len) {
|
||||
$len_caption = pht('Minimum password length: %d characters.', $min_len);
|
||||
}
|
||||
|
||||
if ($viewer->hasPassword()) {
|
||||
$title = pht('Reset Password');
|
||||
$crumb = pht('Reset Password');
|
||||
$submit = pht('Reset Password');
|
||||
} else {
|
||||
$title = pht('Set Password');
|
||||
$crumb = pht('Set Password');
|
||||
$submit = pht('Set Account Password');
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setViewer($viewer)
|
||||
->addHiddenInput('key', $key)
|
||||
->appendChild(
|
||||
id(new AphrontFormPasswordControl())
|
||||
->setDisableAutocomplete(true)
|
||||
->setLabel(pht('New Password'))
|
||||
->setError($e_password)
|
||||
->setName('password'))
|
||||
->appendChild(
|
||||
id(new AphrontFormPasswordControl())
|
||||
->setDisableAutocomplete(true)
|
||||
->setLabel(pht('Confirm Password'))
|
||||
->setCaption($len_caption)
|
||||
->setError($e_confirm)
|
||||
->setName('confirm'))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->addCancelButton('/', pht('Skip This Step'))
|
||||
->setValue($submit));
|
||||
|
||||
$form_box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($title)
|
||||
->setFormErrors($errors)
|
||||
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
|
||||
->setForm($form);
|
||||
|
||||
$main_view = id(new PHUITwoColumnView())
|
||||
->setFooter($form_box);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb($crumb)
|
||||
->setBorder(true);
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($main_view);
|
||||
}
|
||||
}
|
|
@ -100,10 +100,11 @@ final class PhabricatorCalendarNotificationEngine
|
|||
}
|
||||
$notifiable_phids[] = $invitee->getInviteePHID();
|
||||
}
|
||||
if (!$notifiable_phids) {
|
||||
if ($notifiable_phids) {
|
||||
$attendee_map[$key] = array_fuse($notifiable_phids);
|
||||
} else {
|
||||
unset($events[$key]);
|
||||
}
|
||||
$attendee_map[$key] = array_fuse($notifiable_phids);
|
||||
}
|
||||
if (!$attendee_map) {
|
||||
// None of the events have any notifiable attendees, so there is no
|
||||
|
|
|
@ -65,6 +65,16 @@ final class HarbormasterQueryBuildsConduitAPIMethod
|
|||
$fields = idx($build_data, 'fields', array());
|
||||
unset($build_data['fields']);
|
||||
unset($build_data['attachments']);
|
||||
|
||||
// To retain backward compatibility, remove newer keys from the
|
||||
// result array.
|
||||
$fields['buildStatus'] = array_select_keys(
|
||||
$fields['buildStatus'],
|
||||
array(
|
||||
'value',
|
||||
'name',
|
||||
));
|
||||
|
||||
$data[] = array_mergev(array($build_data, $querybuilds, $fields));
|
||||
}
|
||||
|
||||
|
|
|
@ -55,67 +55,28 @@ final class HarbormasterBuildStatus extends Phobject {
|
|||
* @return string Human-readable name.
|
||||
*/
|
||||
public static function getBuildStatusName($status) {
|
||||
$map = self::getBuildStatusMap();
|
||||
return idx($map, $status, pht('Unknown ("%s")', $status));
|
||||
$spec = self::getBuildStatusSpec($status);
|
||||
return idx($spec, 'name', pht('Unknown ("%s")', $status));
|
||||
}
|
||||
|
||||
public static function getBuildStatusMap() {
|
||||
return array(
|
||||
self::STATUS_INACTIVE => pht('Inactive'),
|
||||
self::STATUS_PENDING => pht('Pending'),
|
||||
self::STATUS_BUILDING => pht('Building'),
|
||||
self::STATUS_PASSED => pht('Passed'),
|
||||
self::STATUS_FAILED => pht('Failed'),
|
||||
self::STATUS_ABORTED => pht('Aborted'),
|
||||
self::STATUS_ERROR => pht('Unexpected Error'),
|
||||
self::STATUS_PAUSED => pht('Paused'),
|
||||
self::STATUS_DEADLOCKED => pht('Deadlocked'),
|
||||
);
|
||||
$specs = self::getBuildStatusSpecMap();
|
||||
return ipull($specs, 'name');
|
||||
}
|
||||
|
||||
public static function getBuildStatusIcon($status) {
|
||||
switch ($status) {
|
||||
case self::STATUS_INACTIVE:
|
||||
case self::STATUS_PENDING:
|
||||
return PHUIStatusItemView::ICON_OPEN;
|
||||
case self::STATUS_BUILDING:
|
||||
return PHUIStatusItemView::ICON_RIGHT;
|
||||
case self::STATUS_PASSED:
|
||||
return PHUIStatusItemView::ICON_ACCEPT;
|
||||
case self::STATUS_FAILED:
|
||||
return PHUIStatusItemView::ICON_REJECT;
|
||||
case self::STATUS_ABORTED:
|
||||
return PHUIStatusItemView::ICON_MINUS;
|
||||
case self::STATUS_ERROR:
|
||||
return PHUIStatusItemView::ICON_MINUS;
|
||||
case self::STATUS_PAUSED:
|
||||
return PHUIStatusItemView::ICON_MINUS;
|
||||
case self::STATUS_DEADLOCKED:
|
||||
return PHUIStatusItemView::ICON_WARNING;
|
||||
default:
|
||||
return PHUIStatusItemView::ICON_QUESTION;
|
||||
}
|
||||
$spec = self::getBuildStatusSpec($status);
|
||||
return idx($spec, 'icon', 'fa-question-circle');
|
||||
}
|
||||
|
||||
public static function getBuildStatusColor($status) {
|
||||
switch ($status) {
|
||||
case self::STATUS_INACTIVE:
|
||||
return 'dark';
|
||||
case self::STATUS_PENDING:
|
||||
case self::STATUS_BUILDING:
|
||||
return 'blue';
|
||||
case self::STATUS_PASSED:
|
||||
return 'green';
|
||||
case self::STATUS_FAILED:
|
||||
case self::STATUS_ABORTED:
|
||||
case self::STATUS_ERROR:
|
||||
case self::STATUS_DEADLOCKED:
|
||||
return 'red';
|
||||
case self::STATUS_PAUSED:
|
||||
return 'dark';
|
||||
default:
|
||||
return 'bluegrey';
|
||||
}
|
||||
$spec = self::getBuildStatusSpec($status);
|
||||
return idx($spec, 'color', 'bluegrey');
|
||||
}
|
||||
|
||||
public static function getBuildStatusANSIColor($status) {
|
||||
$spec = self::getBuildStatusSpec($status);
|
||||
return idx($spec, 'color.ansi', 'magenta');
|
||||
}
|
||||
|
||||
public static function getWaitingStatusConstants() {
|
||||
|
@ -142,4 +103,67 @@ final class HarbormasterBuildStatus extends Phobject {
|
|||
);
|
||||
}
|
||||
|
||||
private static function getBuildStatusSpecMap() {
|
||||
return array(
|
||||
self::STATUS_INACTIVE => array(
|
||||
'name' => pht('Inactive'),
|
||||
'icon' => 'fa-circle-o',
|
||||
'color' => 'dark',
|
||||
'color.ansi' => 'yellow',
|
||||
),
|
||||
self::STATUS_PENDING => array(
|
||||
'name' => pht('Pending'),
|
||||
'icon' => 'fa-circle-o',
|
||||
'color' => 'blue',
|
||||
'color.ansi' => 'yellow',
|
||||
),
|
||||
self::STATUS_BUILDING => array(
|
||||
'name' => pht('Building'),
|
||||
'icon' => 'fa-chevron-circle-right',
|
||||
'color' => 'blue',
|
||||
'color.ansi' => 'yellow',
|
||||
),
|
||||
self::STATUS_PASSED => array(
|
||||
'name' => pht('Passed'),
|
||||
'icon' => 'fa-check-circle',
|
||||
'color' => 'green',
|
||||
'color.ansi' => 'green',
|
||||
),
|
||||
self::STATUS_FAILED => array(
|
||||
'name' => pht('Failed'),
|
||||
'icon' => 'fa-times-circle',
|
||||
'color' => 'red',
|
||||
'color.ansi' => 'red',
|
||||
),
|
||||
self::STATUS_ABORTED => array(
|
||||
'name' => pht('Aborted'),
|
||||
'icon' => 'fa-minus-circle',
|
||||
'color' => 'red',
|
||||
'color.ansi' => 'red',
|
||||
),
|
||||
self::STATUS_ERROR => array(
|
||||
'name' => pht('Unexpected Error'),
|
||||
'icon' => 'fa-minus-circle',
|
||||
'color' => 'red',
|
||||
'color.ansi' => 'red',
|
||||
),
|
||||
self::STATUS_PAUSED => array(
|
||||
'name' => pht('Paused'),
|
||||
'icon' => 'fa-minus-circle',
|
||||
'color' => 'dark',
|
||||
'color.ansi' => 'yellow',
|
||||
),
|
||||
self::STATUS_DEADLOCKED => array(
|
||||
'name' => pht('Deadlocked'),
|
||||
'icon' => 'fa-exclamation-circle',
|
||||
'color' => 'red',
|
||||
'color.ansi' => 'red',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private static function getBuildStatusSpec($status) {
|
||||
return idx(self::getBuildStatusSpecMap(), $status, array());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -435,6 +435,8 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
'buildStatus' => array(
|
||||
'value' => $status,
|
||||
'name' => HarbormasterBuildStatus::getBuildStatusName($status),
|
||||
'color.ansi' =>
|
||||
HarbormasterBuildStatus::getBuildStatusANSIColor($status),
|
||||
),
|
||||
'initiatorPHID' => nonempty($this->getInitiatorPHID(), null),
|
||||
'name' => $this->getName(),
|
||||
|
|
|
@ -262,6 +262,10 @@ final class PhabricatorUser
|
|||
PhabricatorPeopleUserPHIDType::TYPECONST);
|
||||
}
|
||||
|
||||
public function hasPassword() {
|
||||
return (bool)strlen($this->passwordHash);
|
||||
}
|
||||
|
||||
public function setPassword(PhutilOpaqueEnvelope $envelope) {
|
||||
if (!$this->getPHID()) {
|
||||
throw new Exception(
|
||||
|
|
|
@ -20,6 +20,14 @@ final class PhabricatorProjectViewController
|
|||
$engine = $this->getProfileMenuEngine();
|
||||
$default = $engine->getDefaultItem();
|
||||
|
||||
// If defaults are broken somehow, serve the manage page. See T13033 for
|
||||
// discussion.
|
||||
if ($default) {
|
||||
$default_key = $default->getBuiltinKey();
|
||||
} else {
|
||||
$default_key = PhabricatorProject::ITEM_MANAGE;
|
||||
}
|
||||
|
||||
switch ($default->getBuiltinKey()) {
|
||||
case PhabricatorProject::ITEM_WORKBOARD:
|
||||
$controller_object = new PhabricatorProjectBoardViewController();
|
||||
|
@ -27,6 +35,9 @@ final class PhabricatorProjectViewController
|
|||
case PhabricatorProject::ITEM_PROFILE:
|
||||
$controller_object = new PhabricatorProjectProfileController();
|
||||
break;
|
||||
case PhabricatorProject::ITEM_MANAGE:
|
||||
$controller_object = new PhabricatorProjectManageController();
|
||||
break;
|
||||
default:
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,11 @@ final class PhabricatorProjectDetailsProfileMenuItem
|
|||
return pht('Project Details');
|
||||
}
|
||||
|
||||
public function canHideMenuItem(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canMakeDefault(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return true;
|
||||
|
|
|
@ -18,6 +18,11 @@ final class PhabricatorProjectManageProfileMenuItem
|
|||
return false;
|
||||
}
|
||||
|
||||
public function canMakeDefault(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDisplayName(
|
||||
PhabricatorProfileMenuItemConfiguration $config) {
|
||||
$name = $config->getMenuItemProperty('name');
|
||||
|
|
|
@ -35,23 +35,10 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel {
|
|||
$min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length');
|
||||
$min_len = (int)$min_len;
|
||||
|
||||
// NOTE: To change your password, you need to prove you own the account,
|
||||
// either by providing the old password or by carrying a token to
|
||||
// the workflow from a password reset email.
|
||||
|
||||
$key = $request->getStr('key');
|
||||
$password_type = PhabricatorAuthPasswordResetTemporaryTokenType::TOKENTYPE;
|
||||
|
||||
$token = null;
|
||||
if ($key) {
|
||||
$token = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||
->setViewer($user)
|
||||
->withTokenResources(array($user->getPHID()))
|
||||
->withTokenTypes(array($password_type))
|
||||
->withTokenCodes(array(PhabricatorHash::weakDigest($key)))
|
||||
->withExpired(false)
|
||||
->executeOne();
|
||||
}
|
||||
// NOTE: Users can also change passwords through the separate "set/reset"
|
||||
// interface which is reached by logging in with a one-time token after
|
||||
// registration or password reset. If this flow changes, that flow may
|
||||
// also need to change.
|
||||
|
||||
$e_old = true;
|
||||
$e_new = true;
|
||||
|
@ -59,12 +46,10 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel {
|
|||
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
if (!$token) {
|
||||
$envelope = new PhutilOpaqueEnvelope($request->getStr('old_pw'));
|
||||
if (!$user->comparePassword($envelope)) {
|
||||
$errors[] = pht('The old password you entered is incorrect.');
|
||||
$e_old = pht('Invalid');
|
||||
}
|
||||
$envelope = new PhutilOpaqueEnvelope($request->getStr('old_pw'));
|
||||
if (!$user->comparePassword($envelope)) {
|
||||
$errors[] = pht('The old password you entered is incorrect.');
|
||||
$e_old = pht('Invalid');
|
||||
}
|
||||
|
||||
$pass = $request->getStr('new_pw');
|
||||
|
@ -98,16 +83,7 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel {
|
|||
|
||||
unset($unguarded);
|
||||
|
||||
if ($token) {
|
||||
// Destroy the token.
|
||||
$token->delete();
|
||||
|
||||
// If this is a password set/reset, kick the user to the home page
|
||||
// after we update their account.
|
||||
$next = '/';
|
||||
} else {
|
||||
$next = $this->getPanelURI('?saved=true');
|
||||
}
|
||||
$next = $this->getPanelURI('?saved=true');
|
||||
|
||||
id(new PhabricatorAuthSessionEngine())->terminateLoginSessions(
|
||||
$user,
|
||||
|
@ -125,19 +101,15 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel {
|
|||
} catch (PhabricatorPasswordHasherUnavailableException $ex) {
|
||||
$can_upgrade = false;
|
||||
|
||||
// Only show this stuff if we aren't on the reset workflow. We can
|
||||
// do resets regardless of the old hasher's availability.
|
||||
if (!$token) {
|
||||
$errors[] = pht(
|
||||
'Your password is currently hashed using an algorithm which is '.
|
||||
'no longer available on this install.');
|
||||
$errors[] = pht(
|
||||
'Because the algorithm implementation is missing, your password '.
|
||||
'can not be used or updated.');
|
||||
$errors[] = pht(
|
||||
'To set a new password, request a password reset link from the '.
|
||||
'login screen and then follow the instructions.');
|
||||
}
|
||||
$errors[] = pht(
|
||||
'Your password is currently hashed using an algorithm which is '.
|
||||
'no longer available on this install.');
|
||||
$errors[] = pht(
|
||||
'Because the algorithm implementation is missing, your password '.
|
||||
'can not be used or updated.');
|
||||
$errors[] = pht(
|
||||
'To set a new password, request a password reset link from the '.
|
||||
'login screen and then follow the instructions.');
|
||||
}
|
||||
|
||||
if ($can_upgrade) {
|
||||
|
@ -153,20 +125,13 @@ final class PhabricatorPasswordSettingsPanel extends PhabricatorSettingsPanel {
|
|||
$len_caption = pht('Minimum password length: %d characters.', $min_len);
|
||||
}
|
||||
|
||||
$form = new AphrontFormView();
|
||||
$form
|
||||
->setUser($user)
|
||||
->addHiddenInput('key', $key);
|
||||
|
||||
if (!$token) {
|
||||
$form->appendChild(
|
||||
$form = id(new AphrontFormView())
|
||||
->setViewer($user)
|
||||
->appendChild(
|
||||
id(new AphrontFormPasswordControl())
|
||||
->setLabel(pht('Old Password'))
|
||||
->setError($e_old)
|
||||
->setName('old_pw'));
|
||||
}
|
||||
|
||||
$form
|
||||
->setName('old_pw'))
|
||||
->appendChild(
|
||||
id(new AphrontFormPasswordControl())
|
||||
->setDisableAutocomplete(true)
|
||||
|
|
Loading…
Reference in a new issue