- $confirm = Confirm_address::staticGet($code);
- if ($confirm && $confirm->type == 'recover') {
- $user = User::staticGet($confirm->user_id);
- if ($user) {
- $result = $confirm->delete();
- if (!$result) {
- common_log_db_error($confirm, 'DELETE', __FILE__);
- common_server_error(_t('Error with confirmation code.'));
- return;
- }
- $this->set_temp_user($user);
- $this->show_password_form();
+ $confirm = Confirm_address::staticGet('code', $code);
+
+ if (!$confirm) {
+ $this->client_error(_('No such recovery code.'));
+ return;
+ }
+ if ($confirm->address_type != 'recover') {
+ $this->client_error(_('Not a recovery code.'));
+ return;
+ }
+
+ $user = User::staticGet($confirm->user_id);
+
+ if (!$user) {
+ $this->server_error(_('Recovery code for unknown user.'));
+ return;
+ }
+
+ $touched = strtotime($confirm->modified);
+ $email = $confirm->address;
+
+ # Burn this code
+
+ $result = $confirm->delete();
+
+ if (!$result) {
+ common_log_db_error($confirm, 'DELETE', __FILE__);
+ common_server_error(_('Error with confirmation code.'));
+ return;
+ }
+
+ # These should be reaped, but for now we just check mod time
+ # Note: it's still deleted; let's avoid a second attempt!
+
+ if ((time() - $touched) > MAX_RECOVERY_TIME) {
+ common_log(LOG_WARNING,
+ 'Attempted redemption on recovery code ' .
+ 'that is ' . $touched . ' seconds old. ');
+ $this->client_error(_('This confirmation code is too old. ' .
+ 'Please start again.'));
+ return;
+ }
+
+ # If we used an outstanding confirmation to send the email,
+ # it's been confirmed at this point.
+
+ if (!$user->email) {
+ $orig = clone($user);
+ $user->email = $email;
+ $result = $user->updateKeys($orig);
+ if (!$result) {
+ common_log_db_error($user, 'UPDATE', __FILE__);
+ $this->server_error(_('Could not update user with confirmed email address.'));
+ return;