diff --git a/app/Handlers/Events/VersionCheckEventHandler.php b/app/Handlers/Events/VersionCheckEventHandler.php
new file mode 100644
index 0000000000..e22655c65c
--- /dev/null
+++ b/app/Handlers/Events/VersionCheckEventHandler.php
@@ -0,0 +1,71 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Handlers\Events;
+
+use FireflyIII\User;
+use Illuminate\Auth\Events\Login;
+use Log;
+use Preferences;
+
+/**
+ * Class VersionCheckEventHandler
+ */
+class VersionCheckEventHandler
+{
+ /**
+ * @param Login $event
+ */
+ public function checkForUpdates(Login $event)
+ {
+ // in Sandstorm, cannot check for updates:
+ $sandstorm = 1 === intval(getenv('SANDSTORM'));
+ if ($sandstorm === true) {
+ return;
+ }
+
+ /** @var User $user */
+ $user = $event->user;
+ $permission = Preferences::getForUser($user, 'permission_update_check', -1);
+ $lastCheckTime = Preferences::getForUser($user, 'last_update_check', time());
+ $now = time();
+ if ($now - $lastCheckTime->data < 604800) {
+ Log::debug('Checked for updates less than a week ago.');
+
+ return;
+
+ }
+ // last check time was more than a week ago.
+ Log::debug('Have not checked for a new version in a week!');
+
+ // have actual permission?
+ if ($permission->data === -1) {
+ // never asked before.
+ session()->flash('info', strval(trans('firefly.check_for_updates_permission', ['link' => route('admin.update-check')])));
+
+ return;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/Http/Controllers/Admin/UpdateController.php b/app/Http/Controllers/Admin/UpdateController.php
new file mode 100644
index 0000000000..28127c4530
--- /dev/null
+++ b/app/Http/Controllers/Admin/UpdateController.php
@@ -0,0 +1,135 @@
+.
+ */
+declare(strict_types=1);
+
+namespace FireflyIII\Http\Controllers\Admin;
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Http\Middleware\IsDemoUser;
+use FireflyIII\Http\Middleware\IsSandStormUser;
+use FireflyIII\Services\Github\Object\Release;
+use FireflyIII\Services\Github\Request\UpdateRequest;
+use Illuminate\Http\Request;
+use Log;
+use Preferences;
+use Response;
+use Session;
+
+/**
+ * Class HomeController.
+ */
+class UpdateController extends Controller
+{
+
+
+ /**
+ * ConfigurationController constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ $this->middleware(
+ function ($request, $next) {
+ app('view')->share('title', strval(trans('firefly.administration')));
+ app('view')->share('mainTitleIcon', 'fa-hand-spock-o');
+
+ return $next($request);
+ }
+ );
+ $this->middleware(IsDemoUser::class)->except(['index']);
+ $this->middleware(IsSandStormUser::class)->except(['index']);
+ }
+
+ /**
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ * @throws \Illuminate\Container\EntryNotFoundException
+ */
+ public function index()
+ {
+ $subTitle = trans('firefly.update_check_title');
+ $subTitleIcon = 'fa-star';
+ $permission = app('preferences')->get('permission_update_check', -1);
+ $selected = $permission->data;
+ $options = [
+ '-1' => trans('firefly.updates_ask_me_later'),
+ '0' => trans('firefly.updates_do_not_check'),
+ '1' => trans('firefly.updates_enable_check'),
+ ];
+
+ return view('admin.update.index', compact('subTitle', 'subTitleIcon', 'selected', 'options'));
+ }
+
+ /**
+ * @param Request $request
+ *
+ * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+ */
+ public function post(Request $request)
+ {
+ $checkForUpdates = intval($request->get('check_for_updates'));
+ Preferences::set('permission_update_check', $checkForUpdates);
+ Session::flash('success', strval(trans('firefly.configuration_updated')));
+ Preferences::mark();
+
+ return redirect(route('admin.update-check'));
+ }
+
+ /**
+ * Does a manual update check.
+ */
+ public function updateCheck()
+ {
+ $current = config('firefly.version');
+ $request = new UpdateRequest();
+ $check = -2;
+ try {
+ $request->call();
+ $releases = $request->getReleases();
+ // first entry should be the latest entry:
+ /** @var Release $first */
+ $first = reset($releases);
+ $string = '';
+ $check = version_compare($current, $first->getTitle());
+ Preferences::set('last_update_check', time());
+ } catch (FireflyException $e) {
+ Log::error(sprintf('Could not check for updates: %s', $e->getMessage()));
+ }
+ if ($check === -2) {
+ $string = strval(trans('firefly.update_check_error'));
+ }
+
+ if ($check === -1) {
+ // there is a new FF version!
+ $string = strval(trans('firefly.update_new_version_alert', ['your_version' => $current, 'new_version' => $first->getTitle()]));
+ }
+ if ($check === 0) {
+ // you are running the current version!
+ $string = strval(trans('firefly.update_current_version_alert', ['version' => $current]));
+ }
+ if ($check === 1) {
+ // you are running a newer version!
+ $string = strval(trans('firefly.update_newer_version_alert', ['your_version' => $current, 'new_version' => $first->getTitle()]));
+ }
+
+ return Response::json(['result' => $string]);
+ }
+}
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index e803f11f69..3ad80238f7 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -54,6 +54,7 @@ class EventServiceProvider extends ServiceProvider
// is a User related event.
Login::class => [
'FireflyIII\Handlers\Events\UserEventHandler@checkSingleUserIsAdmin',
+ 'FireflyIII\Handlers\Events\VersionCheckEventHandler@checkForUpdates',
],
// is a User related event.
diff --git a/app/Services/Github/Object/GithubObject.php b/app/Services/Github/Object/GithubObject.php
new file mode 100644
index 0000000000..c3f13ab04c
--- /dev/null
+++ b/app/Services/Github/Object/GithubObject.php
@@ -0,0 +1,30 @@
+.
+ */
+declare(strict_types=1);
+
+namespace FireflyIII\Services\Github\Object;
+
+/**
+ * Class SpectreObject
+ */
+class GithubObject
+{
+}
diff --git a/app/Services/Github/Object/Release.php b/app/Services/Github/Object/Release.php
new file mode 100644
index 0000000000..e8d6789b8b
--- /dev/null
+++ b/app/Services/Github/Object/Release.php
@@ -0,0 +1,89 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Services\Github\Object;
+
+use Carbon\Carbon;
+
+
+/**
+ * Class Release
+ */
+class Release extends GithubObject
+{
+ /** @var string */
+ private $content;
+ /** @var string */
+ private $id;
+ /** @var string */
+ private $title;
+ /** @var Carbon */
+ private $updated;
+
+ /**
+ * Release constructor.
+ *
+ * @param array $data
+ */
+ public function __construct(array $data)
+ {
+ $this->id = $data['id'];
+ $this->updated = new Carbon($data['updated']);
+ $this->title = $data['title'];
+ $this->content = $data['content'];
+ }
+
+ /**
+ * @return string
+ */
+ public function getContent(): string
+ {
+ return $this->content;
+ }
+
+ /**
+ * @return string
+ */
+ public function getId(): string
+ {
+ return $this->id;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTitle(): string
+ {
+ return $this->title;
+ }
+
+ /**
+ * @return Carbon
+ */
+ public function getUpdated(): Carbon
+ {
+ return $this->updated;
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/Services/Github/Request/GithubRequest.php b/app/Services/Github/Request/GithubRequest.php
new file mode 100644
index 0000000000..49ca47f0ed
--- /dev/null
+++ b/app/Services/Github/Request/GithubRequest.php
@@ -0,0 +1,35 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Services\Github\Request;
+
+/**
+ * Interface GithubRequest
+ *
+ * @package FireflyIII\Services\Github\Request
+ */
+interface GithubRequest
+{
+ public function call();
+
+}
\ No newline at end of file
diff --git a/app/Services/Github/Request/UpdateRequest.php b/app/Services/Github/Request/UpdateRequest.php
new file mode 100644
index 0000000000..5182b75d10
--- /dev/null
+++ b/app/Services/Github/Request/UpdateRequest.php
@@ -0,0 +1,82 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Services\Github\Request;
+
+use Exception;
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Services\Github\Object\Release;
+use Requests;
+use SimpleXMLElement;
+
+/**
+ * Class UpdateRequest
+ */
+class UpdateRequest implements GitHubRequest
+{
+ /** @var array */
+ private $releases = [];
+
+ /**
+ *
+ * @throws FireflyException
+ */
+ public function call()
+ {
+ $uri = 'https://github.com/firefly-iii/firefly-iii/releases.atom';
+ try {
+ $response = Requests::get($uri);
+ } catch (Exception $e) {
+ throw new FireflyException(sprintf('Response error from Github: %s', $e->getMessage()));
+ }
+
+ if ($response->status_code !== 200) {
+ throw new FireflyException(sprintf('Returned code %d, error: %s', $response->status_code, $response->body));
+ }
+
+ $releaseXml = new SimpleXMLElement($response->body, LIBXML_NOCDATA);
+
+ //fetch the products for each category
+ if (isset($releaseXml->entry)) {
+ foreach ($releaseXml->entry as $entry) {
+ $array = [
+ 'id' => strval($entry->id),
+ 'updated' => strval($entry->updated),
+ 'title' => strval($entry->title),
+ 'content' => strval($entry->content),
+ ];
+ $this->releases[] = new Release($array);
+ }
+ }
+ }
+
+ /**
+ * @return array
+ */
+ public function getReleases(): array
+ {
+ return $this->releases;
+ }
+
+
+}
\ No newline at end of file
diff --git a/public/js/ff/admin/update/index.js b/public/js/ff/admin/update/index.js
new file mode 100644
index 0000000000..39a427e77e
--- /dev/null
+++ b/public/js/ff/admin/update/index.js
@@ -0,0 +1,40 @@
+/*
+ * index.js
+ * Copyright (c) 2017 thegrumpydictator@gmail.com
+ *
+ * This file is part of Firefly III.
+ *
+ * Firefly III is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Firefly III is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Firefly III. If not, see