3 namespace Friendica\Model\User;
6 use Friendica\Core\Config\Configuration;
9 * Interacting with the Friendica Cookie of a user
13 /** @var int Default expire duration in days */
14 const DEFAULT_EXPIRE = 7;
15 /** @var string The name of the Friendica cookie */
16 const NAME = 'Friendica';
18 /** @var string The remote address of this node */
19 private $remoteAddr = '0.0.0.0';
20 /** @var bool True, if the connection is ssl enabled */
21 private $sslEnabled = false;
22 /** @var string The private key of this Friendica node */
23 private $sitePrivateKey;
24 /** @var int The default cookie lifetime */
25 private $lifetime = self::DEFAULT_EXPIRE * 24 * 60 * 60;
26 /** @var array The $_COOKIE array */
29 public function __construct(Configuration $config, array $server = [], array $cookie = [])
31 if (!empty($server['REMOTE_ADDR'])) {
32 $this->remoteAddr = $server['REMOTE_ADDR'];
35 $this->sslEnabled = $config->get('system', 'ssl_policy') === App\BaseURL::SSL_POLICY_FULL;
36 $this->sitePrivateKey = $config->get('system', 'site_prvkey');
38 $authCookieDays = $config->get('system', 'auth_cookie_lifetime',
39 self::DEFAULT_EXPIRE);
40 $this->lifetime = $authCookieDays * 24 * 60 * 60;
41 $this->cookie = $cookie;
45 * Checks if the Friendica cookie is set for a user
47 * @param string $hash The cookie hash
48 * @param string $password The user password
49 * @param string $privateKey The private Key of the user
51 * @return boolean True, if the cookie is set
54 public function check(string $hash, string $password, string $privateKey)
57 $this->getHash($password, $privateKey),
63 * Set the Friendica cookie for a user
65 * @param int $uid The user id
66 * @param string $password The user password
67 * @param string $privateKey The user private key
68 * @param int|null $seconds optional the seconds
72 public function set(int $uid, string $password, string $privateKey, int $seconds = null)
74 if (!isset($seconds)) {
75 $seconds = $this->lifetime;
76 } elseif (isset($seconds) && $seconds != 0) {
77 $seconds = $seconds + time();
80 $value = json_encode([
82 'hash' => $this->getHash($password, $privateKey),
83 'ip' => $this->remoteAddr,
86 return $this->setCookie(self::NAME, $value, $seconds,
87 '/', '', $this->sslEnabled, true);
91 * Returns the data of the Friendicas user cookie
93 * @return mixed|null The JSON data, null if not set
95 public function getData()
97 // When the "Friendica" cookie is set, take the value to authenticate and renew the cookie.
98 if (isset($this->cookie[self::NAME])) {
99 $data = json_decode($this->cookie[self::NAME]);
109 * Clears the Friendica cookie of this user after leaving the page
111 public function clear()
113 // make sure cookie is deleted on browser close, as a security measure
114 return $this->setCookie(self::NAME, '', -3600,
115 '/', '', $this->sslEnabled, true);
119 * Calculate the hash that is needed for the Friendica cookie
121 * @param string $password The user password
122 * @param string $privateKey The private key of the user
124 * @return string Hashed data
126 private function getHash(string $password, string $privateKey)
130 hash_hmac('sha256', $password, $privateKey),
131 $this->sitePrivateKey
136 * Send a cookie - protected, internal function for test-mocking possibility
138 * @link https://php.net/manual/en/function.setcookie.php
140 * @param string $name
141 * @param string $value [optional]
142 * @param int $expire [optional]
143 * @param string $path [optional]
144 * @param string $domain [optional]
145 * @param bool $secure [optional]
146 * @param bool $httponly [optional]
148 * @return bool If output exists prior to calling this function,
151 protected function setCookie(string $name, string $value = null, int $expire = null,
152 string $path = null, string $domain = null,
153 bool $secure = null, bool $httponly = null)
155 return setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);