[ 'title' => 'Instagram', 'icon_svg' => '', 'placeholder' => 'instagram @username', 'domain' => 'https://instagram.com/', ], 'twitter' => [ 'title' => 'Twitter/X', 'icon_svg' => '', 'placeholder' => 'twitter/X @username', 'domain' => 'https://x.com/', ], 'youtube' => [ 'title' => 'YouTube', 'icon_svg' => '', 'placeholder' => 'youtube @username', 'domain' => 'https://youtube.com/', ], 'linkedin' => [ 'title' => 'LinkedIn', 'icon_svg' => '', 'placeholder' => 'linkedin username', 'domain' => 'https://linkedin.com/in/', ], 'fb' => [ 'title' => 'Facebook', 'icon_svg' => '', 'placeholder' => 'fb username', 'domain' => 'https://facebook.com/', ], ]); } public static function getReservedUserNames() { return [ 'admin', 'administrator', 'me', 'moderator', 'mod', 'superuser', 'root', 'system', 'official', 'staff', 'support', 'helpdesk', 'user', 'guest', 'anonymous', 'everyone', 'anybody', 'someone', 'webmaster', 'postmaster', 'hostmaster', 'abuse', 'security', 'ssl', 'firewall', 'no-reply', 'noreply', 'mail', 'email', 'mailer', 'smtp', 'pop', 'imap', 'ftp', 'sftp', 'ssh', 'ceo', 'cfo', 'cto', 'founder', 'cofounder', 'owner', 'president', 'vicepresident', 'director', 'manager', 'supervisor', 'executive', 'info', 'contact', 'sales', 'marketing', 'support', 'billing', 'accounting', 'finance', 'hr', 'humanresources', 'legal', 'compliance', 'it', 'itsupport', 'customerservice', 'customersupport', 'dev', 'developer', 'api', 'sdk', 'app', 'bot', 'chatbot', 'sysadmin', 'devops', 'infosec', 'security', 'test', 'testing', 'beta', 'alpha', 'staging', 'production', 'development', 'home', 'about', 'contact', 'faq', 'help', 'news', 'blog', 'forum', 'community', 'events', 'calendar', 'shop', 'store', 'cart', 'checkout', 'social', 'follow', 'like', 'share', 'tweet', 'post', 'status', 'privacy', 'terms', 'copyright', 'trademark', 'legal', 'policy', 'all', 'none', 'null', 'undefined', 'true', 'false', 'default', 'example', 'sample', 'demo', 'temporary', 'delete', 'remove', 'profanity', 'explicit', 'offensive', 'yourappname', 'yourbrandname', 'yourdomain', ]; } public static function isUsernameAvailable($userName) { $userName = strtolower($userName); $reservedUserNames = self::getReservedUserNames(); if (in_array($userName, $reservedUserNames)) { return false; } $user = get_user_by('login', $userName); if ($user) { return false; } $xProfile = XProfile::where('username', $userName)->exists(); if ($xProfile) { return false; } return true; } public static function generateUserName($user) { if (!$user instanceof \WP_User) { $user = get_user_by('ID', $user); } $firstName = $user->first_name; if (!$firstName || strlen($firstName) < 3) { $firstName = $user->last_name; } if (!$firstName || strlen($firstName) < 3) { $firstName = $user->user_nicename; } if (!$firstName) { $firstName = $user->display_name; } $userName = strtolower($firstName); $userName = CustomSanitizer::sanitizeUserName($userName); $userName = substr($userName, 0, 20); if (!$userName) { $userName = 'user' . '-' . $user->ID; } $finalUserName = $userName; // loop until we find a unique username $counter = 2; while (!self::isUsernameAvailable($userName)) { $userName = $finalUserName . $counter; $counter++; if ($counter % 100 === 0) { $finalUserName = $finalUserName . $user->ID . '-'; } } return $userName; } public static function getUserAuthHash($userId = null) { if (!$userId) { return ''; } static $cached = []; if (isset($cached[$userId])) { return $cached[$userId]; } $exist = Meta::byType('user') ->byMetaKey('auth_hash') ->byObjectId($userId) ->first(); $validTil = strtotime('+1 day'); if ($exist) { $hashes = (array)$exist->value; $validHashes = array_filter($hashes, function ($hash) use ($validTil) { return $hash['valid_til'] > $validTil; }); if ($validHashes) { $lastHash = end($validHashes); return $lastHash['hash'] . '__' . $exist->id; } $newHash = md5(wp_generate_uuid4() . '_' . $userId . '_' . '_' . time() . '__' . $userId); $hashes[] = [ 'hash' => $newHash, 'valid_til' => strtotime('+2 days') ]; // remove expired hashes $hashes = array_filter($hashes, function ($hash) use ($validTil) { return $hash['valid_til'] > time(); }); $exist->value = array_values($hashes); $exist->save(); $cached[$userId] = $newHash . '__' . $exist->id; return $cached[$userId]; } $newHash = md5(wp_generate_uuid4() . '_' . $userId . '_' . '_' . time() . '__' . $userId); $meta = Meta::create([ 'object_type' => 'user', 'object_id' => $userId, 'meta_key' => 'auth_hash', 'value' => [ [ 'hash' => $newHash, 'valid_til' => strtotime('+2 days') ] ] ]); $cached[$userId] = $newHash . '__' . $meta->id; return $cached[$userId]; } public static function signUserUrlWithAuthHash($url, $userId = null) { $hash = self::getUserAuthHash($userId); if (!$hash) { return $url; } return add_query_arg([ 'fcom_action' => 'signed_url', 'fcom_url_hash' => $hash ], $url); } public static function getSignedNotificationPrefUrl($userId) { $notificationPref = Helper::baseUrl('fcom_route?route=user_notification_settings&auth=yes'); return self::signUserUrlWithAuthHash($notificationPref, $userId); } /* * Get WP User by URL Hash * @param string $hash * @return \WP_User|null */ public static function getUserByUrlHash($hash) { $hashParts = explode('__', $hash); if (count($hashParts) !== 2) { return null; } $metaId = $hashParts[1]; $meta = Meta::where('object_type', 'user') ->where('meta_key', 'auth_hash') ->where('id', $metaId) ->first(); if (!$meta) { return null; } $hashes = (array)$meta->value; $hash = $hashParts[0]; $validHash = array_filter($hashes, function ($hashData) use ($hash) { return $hashData['hash'] == $hash; }); if (!$validHash) { return null; } return get_user_by('ID', $meta->object_id); } }