@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PhabricatorAuthSetPasswordController
4 extends PhabricatorAuthController {
5
6 public function shouldAllowPartialSessions() {
7 return true;
8 }
9
10 public function shouldAllowLegallyNonCompliantUsers() {
11 return true;
12 }
13
14 public function handleRequest(AphrontRequest $request) {
15 $viewer = $this->getViewer();
16
17 if (!PhabricatorPasswordAuthProvider::getPasswordProvider()) {
18 return new Aphront404Response();
19 }
20
21 $token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
22 $viewer,
23 $request,
24 '/');
25
26 $key = $request->getStr('key');
27 $password_type = PhabricatorAuthPasswordResetTemporaryTokenType::TOKENTYPE;
28 if (!$key) {
29 return new Aphront404Response();
30 }
31
32 $auth_token = id(new PhabricatorAuthTemporaryTokenQuery())
33 ->setViewer($viewer)
34 ->withTokenResources(array($viewer->getPHID()))
35 ->withTokenTypes(array($password_type))
36 ->withTokenCodes(array(PhabricatorHash::weakDigest($key)))
37 ->withExpired(false)
38 ->executeOne();
39 if (!$auth_token) {
40 return new Aphront404Response();
41 }
42
43 $content_source = PhabricatorContentSource::newFromRequest($request);
44 $account_type = PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT;
45
46 $password_objects = id(new PhabricatorAuthPasswordQuery())
47 ->setViewer($viewer)
48 ->withObjectPHIDs(array($viewer->getPHID()))
49 ->withPasswordTypes(array($account_type))
50 ->withIsRevoked(false)
51 ->execute();
52 if ($password_objects) {
53 $password_object = head($password_objects);
54 $has_password = true;
55 } else {
56 $password_object = PhabricatorAuthPassword::initializeNewPassword(
57 $viewer,
58 $account_type);
59 $has_password = false;
60 }
61
62 $engine = id(new PhabricatorAuthPasswordEngine())
63 ->setViewer($viewer)
64 ->setContentSource($content_source)
65 ->setPasswordType($account_type)
66 ->setObject($viewer);
67
68 $e_password = true;
69 $e_confirm = true;
70 $errors = array();
71 if ($request->isFormPost()) {
72 $password = $request->getStr('password');
73 $confirm = $request->getStr('confirm');
74
75 $password_envelope = new PhutilOpaqueEnvelope($password);
76 $confirm_envelope = new PhutilOpaqueEnvelope($confirm);
77
78 try {
79 $engine->checkNewPassword($password_envelope, $confirm_envelope, true);
80 $e_password = null;
81 $e_confirm = null;
82 } catch (PhabricatorAuthPasswordException $ex) {
83 $errors[] = $ex->getMessage();
84 $e_password = $ex->getPasswordError();
85 $e_confirm = $ex->getConfirmError();
86 }
87
88 if (!$errors) {
89 $password_object
90 ->setPassword($password_envelope, $viewer)
91 ->save();
92
93 // Destroy the token.
94 $auth_token->delete();
95
96 return id(new AphrontRedirectResponse())->setURI('/');
97 }
98 }
99
100 $min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length');
101 $min_len = (int)$min_len;
102
103 $len_caption = null;
104 if ($min_len) {
105 $len_caption = pht('Minimum password length: %d characters.', $min_len);
106 }
107
108 if ($has_password) {
109 $title = pht('Reset Password');
110 $crumb = pht('Reset Password');
111 $submit = pht('Reset Password');
112 } else {
113 $title = pht('Set Password');
114 $crumb = pht('Set Password');
115 $submit = pht('Set Account Password');
116 }
117
118 $form = id(new AphrontFormView())
119 ->setViewer($viewer)
120 ->addHiddenInput('key', $key)
121 ->appendChild(
122 id(new AphrontFormPasswordControl())
123 ->setDisableAutocomplete(true)
124 ->setLabel(pht('New Password'))
125 ->setError($e_password)
126 ->setName('password'))
127 ->appendChild(
128 id(new AphrontFormPasswordControl())
129 ->setDisableAutocomplete(true)
130 ->setLabel(pht('Confirm Password'))
131 ->setCaption($len_caption)
132 ->setError($e_confirm)
133 ->setName('confirm'))
134 ->appendChild(
135 id(new AphrontFormSubmitControl())
136 ->addCancelButton('/', pht('Skip This Step'))
137 ->setValue($submit));
138
139 $form_box = id(new PHUIObjectBoxView())
140 ->setHeaderText($title)
141 ->setFormErrors($errors)
142 ->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
143 ->setForm($form);
144
145 $main_view = id(new PHUITwoColumnView())
146 ->setFooter($form_box);
147
148 $crumbs = $this->buildApplicationCrumbs()
149 ->addTextCrumb($crumb)
150 ->setBorder(true);
151
152 return $this->newPage()
153 ->setTitle($title)
154 ->setCrumbs($crumbs)
155 ->appendChild($main_view);
156 }
157}