/** * Respond with JavaScript to inform the Flarum app about the user's * authentication status. * * An array of identification attributes must be passed as the first * argument. These are checked against existing user accounts; if a match is * found, then the user is authenticated and logged into that account via * cookie. The Flarum app will then simply refresh the page. * * If no matching account is found, then an AuthToken will be generated to * store the identification attributes. This token, along with an optional * array of suggestions, will be passed into the Flarum app's sign up modal. * This results in the user not having to choose a password. When they * complete their registration, the identification attributes will be * set on their new user account. * * @param array $identification * @param array $suggestions * @return HtmlResponse */ protected function authenticated(array $identification, array $suggestions = []) { $user = User::where($identification)->first(); // If a user with these attributes already exists, then we will log them // in by generating an access token. Otherwise, we will generate a // unique token for these attributes and add it to the response, along // with the suggested account information. if ($user) { $accessToken = $this->bus->dispatch(new GenerateAccessToken($user->id)); $payload = ['authenticated' => true]; } else { $token = AuthToken::generate($identification); $token->save(); $payload = array_merge($identification, $suggestions, ['token' => $token->id]); } $content = sprintf('<script> window.opener.app.authenticationComplete(%s); window.close(); </script>', json_encode($payload)); $response = new HtmlResponse($content); if (isset($accessToken)) { // Extend the token's expiry to 2 weeks so that we can set a // remember cookie $accessToken::unguard(); $accessToken->update(['expires_at' => new DateTime('+2 weeks')]); $response = $this->withRememberCookie($response, $accessToken->id); } return $response; }
protected function sync(Post $post, array $mentioned) { $post->mentionsUsers()->sync($mentioned); $users = User::whereIn('id', $mentioned)->get()->filter(function ($user) use($post) { return $user->id !== $post->user->id; })->all(); $this->notifications->sync(new UserMentionedBlueprint($post), $users); }
/** * Register notification types. * * @return void */ public function registerNotificationTypes() { $blueprints = ['Flarum\\Core\\Notifications\\DiscussionRenamedBlueprint' => ['alert']]; event(new RegisterNotificationTypes($blueprints)); foreach ($blueprints as $blueprint => $enabled) { Notification::setSubjectModel($type = $blueprint::getType(), $blueprint::getSubjectModel()); User::addPreference(User::getNotificationPreferenceKey($type, 'alert'), 'boolval', in_array('alert', $enabled)); if ((new ReflectionClass($blueprint))->implementsInterface('Flarum\\Core\\Notifications\\MailableBlueprint')) { User::addPreference(User::getNotificationPreferenceKey($type, 'email'), 'boolval', in_array('email', $enabled)); } } }
/** * @param RegisterUser $command * @return User * @throws PermissionDeniedException */ public function handle(RegisterUser $command) { if (!$this->settings->get('allow_sign_up')) { throw new PermissionDeniedException(); } $actor = $command->actor; $data = $command->data; $user = User::register(array_get($data, 'attributes.username'), array_get($data, 'attributes.email'), array_get($data, 'attributes.password')); event(new UserWillBeSaved($user, $actor, $data)); $user->save(); $this->dispatchEventsFor($user); return $user; }
/** * {@inheritdoc} */ public function __invoke(Request $request, Response $response, callable $out = null) { $header = $request->getHeaderLine('authorization'); $parts = explode(';', $header); if (isset($parts[0]) && starts_with($parts[0], $this->prefix)) { $token = substr($parts[0], strlen($this->prefix)); if ($accessToken = AccessToken::valid($token)) { $this->app->instance('flarum.actor', $user = $accessToken->user); $user->updateLastSeen()->save(); } elseif (isset($parts[1]) && ($apiKey = ApiKey::valid($token))) { $userParts = explode('=', trim($parts[1])); if (isset($userParts[0]) && $userParts[0] === 'userId') { $this->app->instance('flarum.actor', $user = User::find($userParts[1])); } } } return $out ? $out($request, $response) : $response; }
/** * Bootstrap the application events. * * @return void */ public function boot() { User::setHasher($this->app->make('hash')); User::setValidator($this->app->make('validator')); $events = $this->app->make('events'); $events->listen(RegisterUserPreferences::class, function (RegisterUserPreferences $event) { $event->register('discloseOnline', 'boolval', true); $event->register('indexProfile', 'boolval', true); $event->register('locale'); }); $events->listen(ModelAllow::class, function (ModelAllow $event) { if ($event->model instanceof User) { if ($event->actor->hasPermission('user.' . $event->action)) { return true; } } }); $events->subscribe('Flarum\\Core\\Users\\Listeners\\UserMetadataUpdater'); $events->subscribe('Flarum\\Core\\Users\\Listeners\\EmailConfirmationMailer'); }
/** * @param RegisterUser $command * * @throws PermissionDeniedException if signup is closed and the actor is * not an administrator. * @throws \Flarum\Core\Exceptions\InvalidConfirmationTokenException if an * email confirmation token is provided but is invalid. * * @return User */ public function handle(RegisterUser $command) { $actor = $command->actor; $data = $command->data; if (!$this->settings->get('allow_sign_up') && !$actor->isAdmin()) { throw new PermissionDeniedException(); } $username = array_get($data, 'attributes.username'); $email = array_get($data, 'attributes.email'); $password = array_get($data, 'attributes.password'); // If a valid authentication token was provided as an attribute, // then we won't require the user to choose a password. if (isset($data['attributes']['token'])) { $token = AuthToken::validOrFail($data['attributes']['token']); $password = $password ?: str_random(20); } $user = User::register($username, $email, $password); // If a valid authentication token was provided, then we will assign // the attributes associated with it to the user's account. If this // includes an email address, then we will activate the user's account // from the get-go. if (isset($token)) { foreach ($token->payload as $k => $v) { $user->{$k} = $v; } if (isset($token->payload['email'])) { $user->activate(); } } event(new UserWillBeSaved($user, $actor, $data)); $user->save(); if (isset($token)) { $token->delete(); } $this->dispatchEventsFor($user); return $user; }
/** * Get a new query builder for the groups table. * * @return Builder */ public function query() { return User::query(); }
/** * Find users by matching a string of words against their username, * optionally making sure they are visible to a certain user. * * @param string $string * @param User|null $actor * @return array */ public function getIdsForUsername($string, User $actor = null) { $query = User::where('username', 'like', '%' . $string . '%')->orderByRaw('username = ? desc', [$string])->orderByRaw('username like ? desc', [$string . '%']); return $this->scopeVisibleTo($query, $actor)->lists('id'); }
/** * @param User $user * @param int $amount */ protected function updateDiscussionsCount(User $user, $amount) { $user->discussions_count += $amount; $user->save(); }
protected function createAdminUser() { $admin = $this->adminUser; if ($admin['password'] !== $admin['password_confirmation']) { throw new Exception('The password did not match its confirmation.'); } $this->info('Creating admin user ' . $admin['username']); $user = User::register($admin['username'], $admin['email'], $admin['password']); $user->is_activated = 1; $user->save(); $user->groups()->sync([1]); }
protected function createAdminUser() { $admin = $this->dataSource->getAdminUser(); $this->info('Creating admin user ' . $admin['username']); User::unguard(); $user = new User($admin); $user->is_activated = 1; $user->join_time = time(); $user->save(); $user->groups()->sync([1]); }
/** * Query the discussion's participants (a list of unique users who have * posted in the discussion). * * @return \Illuminate\Database\Eloquent\Builder */ public function participants() { return User::join('posts', 'posts.user_id', '=', 'users.id')->where('posts.discussion_id', $this->id)->select('users.*')->distinct(); }
protected function importUsers($from, $to) { $this->info('Importing users...'); $to->table('users')->truncate(); $to->table('email_tokens')->truncate(); $to->table('password_tokens')->truncate(); $to->table('access_tokens')->truncate(); $to->table('users_groups')->truncate(); $members = $from->table('member')->get(); $progress = new ProgressBar($this->output, count($members)); foreach ($members as $m) { $preferences = unserialize($m->preferences); $user = new User(); $user->id = $m->memberId; $user->username = $m->username; $user->email = $m->email; $user->is_activated = true; $user->password = ''; $user->join_time = $m->joinTime; $user->last_seen_time = $m->lastActionTime; $user->avatar_path = $m->avatarFormat ? $m->memberId . '.' . $m->avatarFormat : null; $user->username = $m->username; $user->read_time = array_get($preferences, 'markedAllConversationsAsRead'); $user->notification_read_time = array_get($preferences, 'notificationCheckTime'); $user->preferences = ['discloseOnline' => !array_get($preferences, 'hideOnline')]; $user->discussions_count = $m->countConversations; $user->comments_count = $m->countPosts; $user->save(); $this->app->make('Flarum\\Core\\Activity\\ActivitySyncer')->sync(new JoinedActivity($user), [$user]); $progress->advance(); } $progress->finish(); $this->info("\n"); }
/** * Get the name of the locale to use. * * @param User $actor * @param Request $request * @return string */ protected function getLocale(User $actor, Request $request) { if ($actor->exists) { $locale = $actor->getPreference('locale'); } else { $locale = array_get($request->getCookieParams(), 'locale'); } if (!$locale || !$this->locales->hasLocale($locale)) { $locale = $this->settings->get('default_locale', 'en'); } if ($this->locales->hasLocale($locale)) { return $locale; } }
public function register($key, callable $transformer = null, $default = null) { User::addPreference($key, $transformer, $default); }
/** * Find a user's notifications. * * @param User $user * @param int|null $limit * @param int $offset * @return \Illuminate\Database\Eloquent\Collection */ public function findByUser(User $user, $limit = null, $offset = 0) { $primaries = Notification::select(app('flarum.db')->raw('MAX(id) AS id'), app('flarum.db')->raw('SUM(is_read = 0) AS unread_count'))->where('user_id', $user->id)->whereIn('type', $user->getAlertableNotificationTypes())->where('is_deleted', false)->groupBy('type', 'subject_id')->orderByRaw('MAX(time) DESC')->skip($offset)->take($limit); return Notification::select('notifications.*', app('flarum.db')->raw('p.unread_count'))->mergeBindings($primaries->getQuery())->join(app('flarum.db')->raw('(' . $primaries->toSql() . ') p'), 'notifications.id', '=', app('flarum.db')->raw('p.id'))->latest('time')->get(); }
/** * @param EditUser $command * @return User * @throws \Flarum\Core\Exceptions\PermissionDeniedException */ public function handle(EditUser $command) { $actor = $command->actor; $data = $command->data; $user = $this->users->findOrFail($command->userId, $actor); $isSelf = $actor->id === $user->id; $attributes = array_get($data, 'attributes', []); $relationships = array_get($data, 'relationships', []); if (isset($attributes['username'])) { $user->assertCan($actor, 'edit'); $user->rename($attributes['username']); } if (isset($attributes['email'])) { if ($isSelf) { $user->requestEmailChange($attributes['email']); } else { $user->assertCan($actor, 'edit'); $user->changeEmail($attributes['email']); } } if (isset($attributes['password'])) { $user->assertCan($actor, 'edit'); $user->changePassword($attributes['password']); } if (isset($attributes['bio'])) { if (!$isSelf) { $user->assertCan($actor, 'edit'); } $user->changeBio($attributes['bio']); } if (!empty($attributes['readTime'])) { $this->assert($isSelf); $user->markAllAsRead(); } if (!empty($attributes['preferences'])) { $this->assert($isSelf); foreach ($attributes['preferences'] as $k => $v) { $user->setPreference($k, $v); } } if (isset($relationships['groups']['data']) && is_array($relationships['groups']['data'])) { $user->assertCan($actor, 'edit'); $newGroupIds = []; foreach ($relationships['groups']['data'] as $group) { if ($id = array_get($group, 'id')) { $newGroupIds[] = $id; } } $user->raise(new UserGroupsWereChanged($user, $user->groups()->get()->all())); User::saved(function ($user) use($newGroupIds) { $user->groups()->sync($newGroupIds); }); } event(new UserWillBeSaved($user, $actor, $data)); $user->save(); $this->dispatchEventsFor($user); return $user; }