diff --git a/.travis.yml b/.travis.yml index 2f0f46725d65..7a3863439bad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -78,7 +78,7 @@ before_script: script: - php ./vendor/bin/phpunit --debug --verbose --coverage-clover=coverage.xml # php artisan dusk - - npm test + #- npm test after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/app/Http/Controllers/Auth/ContactLoginController.php b/app/Http/Controllers/Auth/ContactLoginController.php index 90a3d4bd4341..812d09bef742 100644 --- a/app/Http/Controllers/Auth/ContactLoginController.php +++ b/app/Http/Controllers/Auth/ContactLoginController.php @@ -31,33 +31,36 @@ class ContactLoginController extends Controller public function showLoginForm() { - return view('auth.contact_login'); + + return view('portal.default.auth.login'); + } + public function login(Request $request) { - - Auth::shouldUse('contact'); + Auth::shouldUse('contact'); $this->validateLogin($request); - - if ($this->hasTooManyLoginAttempts($request)) { + // If the class is using the ThrottlesLogins trait, we can automatically throttle + // the login attempts for this application. We'll key this by the username and + // the IP address of the client making these requests into this application. + if (method_exists($this, 'hasTooManyLoginAttempts') && + $this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); - - return response()->json(['message' => 'Too many login attempts, you are being throttled']); + return $this->sendLockoutResponse($request); } - - if ($this->attemptLogin($request)) - return redirect()->intended(route('client.dashboard')); - else { - - $this->incrementLoginAttempts($request); - - return redirect()->back()->withInput($request->only('email', 'remember')); + if ($this->attemptLogin($request)) { + return $this->sendLoginResponse($request); } - - + // If the login attempt was unsuccessful we will increment the number of attempts + // to login and redirect the user back to the login form. Of course, when this + // user surpasses their maximum number of attempts they will get locked out. + $this->incrementLoginAttempts($request); + return $this->sendFailedLoginResponse($request); } + + public function logout() { diff --git a/app/Http/Controllers/BaseController.php b/app/Http/Controllers/BaseController.php index bef3e03bbb78..84b1fceed658 100644 --- a/app/Http/Controllers/BaseController.php +++ b/app/Http/Controllers/BaseController.php @@ -108,7 +108,7 @@ class BaseController extends Controller public function notFound() { return response()->json([ - 'message' => 'Nothing to see here!'], 404); + 'message' => '404 | Nothing to see here!'], 404); } public function notFoundClient() diff --git a/app/Listeners/Contact/UpdateContactLastLogin.php b/app/Listeners/Contact/UpdateContactLastLogin.php new file mode 100644 index 000000000000..b7fa2d17097d --- /dev/null +++ b/app/Listeners/Contact/UpdateContactLastLogin.php @@ -0,0 +1,45 @@ +client_contact; + + $client_contact->last_login = now(); + $client_contact->save(); + + } +} diff --git a/package.json b/package.json index aa57d6838813..b19ba5d7eace 100644 --- a/package.json +++ b/package.json @@ -7,54 +7,20 @@ "watch-poll": "npm run watch -- --watch-poll", "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", "prod": "npm run production", - "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", - "test": "jest" - }, - "devDependencies": { - "@coreui/coreui": "^2.0.12", - "@coreui/coreui-plugin-chartjs-custom-tooltips": "1.2.0", - "@coreui/icons": "^0.3.0", - "@types/bluebird": "^3.5.25", - "@types/core-js": "^0.9.36", - "@types/jest": "^23.3.9", - "axios": "^0.18", - "babel-preset-stage-2": "^6.24.1", - "bootstrap": "^4.0.0", - "chart.js": "^2.7.3", - "cross-env": "^5.1", - "flag-icon-css": "3.2.0", - "font-awesome": "^4.7", - "jest": "^23.6.0", - "jquery": "^3.2", - "laravel-mix": "^2.0", - "pace-progress": "1.0.2", - "perfect-scrollbar": "1.4.0", - "popper.js": "^1.12", - "simple-line-icons": "2.4.1", - "ts-jest": "^23.10.5", - "vue": "^2.5.17", - "vuetable-2": "^1.7.5" + "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" }, + "devDependencies": {}, "dependencies": { - "@types/lodash": "^4.14.118", - "@types/node": "^10.12.10", - "axios-progress-bar": "^1.2.0", - "chalk": "^2.4.2", - "hashids": "^1.2.2", - "laravel-echo": "^1.4.0", - "lodash.get": "^4.4.2", - "puppeteer": "^1.18.1", - "quill": "^1.3.6", - "socket.io-client": "^2.1.1", - "ts-loader": "3.5.0", - "typescript": "^3.1.6", - "vue-affix": "^0.4.0", - "vue-chartjs": "^3.4.0", - "vue-events": "^3.1.0", - "vue-multiselect": "^2.1.3", - "vue-scrollactive": "^0.8.0", - "vue-select": "^2.5.1", - "vue-toastr": "^2.0.16", - "vuex": "^3.1.0" + "@coreui/coreui": "^2.1.12", + "@coreui/icons": "^0.3.0", + "bootstrap": "^4.3.1", + "font-awesome": "^4.7.0", + "laravel-mix": "^4.1.2", + "puppeteer": "^1.18.1" + }, + "peerDependencies": { + "jquery": "1.9.1 - 3", + "perfect-scrollbar": "^1.3.0", + "popper.js": "^1.14.3" } } diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 5f8512c7a104..309e9ff94e65 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,17 +1,11 @@ { - "/js/client_list.js": "/js/client_list.js?id=497dadf330d671d77df2", - "/js/client_edit.js": "/js/client_edit.js?id=4af6b4f5e15167bbc24d", - "/js/client_show.js": "/js/client_show.js?id=d1fa3c09614c73dc4b7e", - "/js/client_create.js": "/js/client_create.js?id=d5acb9e9a827386a517c", - "/js/localization.js": "/js/localization.js?id=054592ec61c720b458de", - "/js/coreui.js": "/js/coreui.js?id=3c7e911851224f97523e", - "/js/ninja.min.js": "/js/ninja.min.js?id=d41d8cd98f00b204e980", - "/js/coreui.min.js": "/js/coreui.min.js?id=3c7e911851224f97523e", - "/js/client_show.min.js": "/js/client_show.min.js?id=d1fa3c09614c73dc4b7e", - "/js/client_edit.min.js": "/js/client_edit.min.js?id=4af6b4f5e15167bbc24d", - "/js/client_create.min.js": "/js/client_create.min.js?id=d5acb9e9a827386a517c", - "/js/client_list.min.js": "/js/client_list.min.js?id=497dadf330d671d77df2", - "/js/localization.min.js": "/js/localization.min.js?id=054592ec61c720b458de", - "/css/ninja.css": "/css/ninja.css?id=28421bc494c5086ac359", - "/css/ninja.min.css": "/css/ninja.min.css?id=28421bc494c5086ac359" + "/vendors/css/coreui.min.css": "/vendors/css/coreui.min.css?id=cc8e626c1902d53ee805", + "/vendors/css/coreui-icons.min.css": "/vendors/css/coreui-icons.min.css?id=23447e24a210c12e4559", + "/vendors/css/bootstrap.min.css": "/vendors/css/bootstrap.min.css?id=6f27def50398084c3b22", + "/vendors/css/font-awesome.min.css": "/vendors/css/font-awesome.min.css?id=269550530cc127b6aa5a", + "/vendors/js/coreui.min.js": "/vendors/js/coreui.min.js?id=0fa9ac379e62c48d26e6", + "/vendors/js/bootstrap.min.js": "/vendors/js/bootstrap.min.js?id=e1d98d47689e00f8ecbc", + "/vendors/js/jquery.min.js": "/vendors/js/jquery.min.js?id=220afd743d9e9643852e", + "/vendors/js/popper.min.js": "/vendors/js/popper.min.js?id=61b9b07b83557d9325c3", + "/vendors/js/perfect-scrollbar.min.js": "/vendors/js/perfect-scrollbar.min.js?id=4a10bcfa0a9c9fa9d503" } diff --git a/resources/views/portal/default/auth/login.blade.php b/resources/views/portal/default/auth/login.blade.php new file mode 100644 index 000000000000..74dce7f11cf6 --- /dev/null +++ b/resources/views/portal/default/auth/login.blade.php @@ -0,0 +1,103 @@ +@extends('portal.default.layouts.guest') + +@section('body') + +
+
+
+
+
+
+ @if (session('info')) +
+
+
+ + {{ session('info') }} +
+
+
+ @elseif (session('error')) +
+
+
+ + {{ session('error') }} +
+
+
+ @endif +
+ @csrf +

@lang('texts.account_login')

+ @if (Session::has('error')) +
+
  • {!! Session::get('error') !!}
  • +
    + @endif +

    +
    +
    + + + +
    + + + @if ($errors->has('email')) + + {{ $errors->first('email') }} + + @endif + +
    +
    +
    + + + +
    + + + @if ($errors->has('password')) + + {{ $errors->first('password') }} + + @endif +
    + +
    +
    + +
    + +
    + + +
    +
    +
    + @env('hosted') + + @endenv +
    +
    +
    +
    + +@endsection + + diff --git a/resources/views/portal/default/footer.blade.php b/resources/views/portal/default/footer.blade.php new file mode 100644 index 000000000000..be99f01c64eb --- /dev/null +++ b/resources/views/portal/default/footer.blade.php @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/resources/views/portal/default/header.blade.php b/resources/views/portal/default/header.blade.php new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/resources/views/portal/default/layouts/guest.blade.php b/resources/views/portal/default/layouts/guest.blade.php new file mode 100644 index 000000000000..d182340244a3 --- /dev/null +++ b/resources/views/portal/default/layouts/guest.blade.php @@ -0,0 +1,57 @@ + + + + + + + + @if (config('services.analytics.tracking_id')) + + + + @else + + @endif + + + @yield('meta_title', 'Invoice Ninja') | {{ config('app.name') }} + + + + + + + + + + + + + + + + @yield('head') + + +@include('portal.default.header', $header) +@yield('header') + +@include('portal.default.sidebar') +@yield('sidebar') + +@section('body') +@yield('body') + + \ No newline at end of file diff --git a/resources/views/portal/default/layouts/master.blade.php b/resources/views/portal/default/layouts/master.blade.php new file mode 100644 index 000000000000..79b0cd316d2f --- /dev/null +++ b/resources/views/portal/default/layouts/master.blade.php @@ -0,0 +1,59 @@ + + + + + + + + @if (config('services.analytics.tracking_id')) + + + + @else + + @endif + + + @yield('meta_title', 'Invoice Ninja') | {{ config('app.name') }} + + + + + + + + + + + + + + + + @yield('head') + + +@include('portal.default.header', $header) +@yield('header') + +@include('portal.default.sidebar') +@yield('sidebar') + +@section('body') +@yield('body') + +@include('portal.default.footer') +@yield('footer') + \ No newline at end of file diff --git a/resources/views/portal/default/sidebar.blade.php b/resources/views/portal/default/sidebar.blade.php new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/webpack.mix.js b/webpack.mix.js index 90ad4bdcd83e..0acf4c8f2257 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -11,50 +11,16 @@ const mix = require('laravel-mix'); | */ -mix.webpackConfig({ - resolve: { - extensions: ['.ts'] - }, - module: { - rules: [ - { - test: /\.ts$/, - loader: 'ts-loader', - options: { appendTsSuffixTo: [/\.vue$/] }, - exclude: /node_modules/, - } - ] - } - }); -mix.js('resources/js/src/client/client_show.ts', 'public/js'); -mix.js('resources/js/src/client/client_edit.ts', 'public/js'); -mix.js('resources/js/src/client/client_create.ts', 'public/js'); -mix.js('resources/js/src/client/client_list.ts', 'public/js'); -mix.js('resources/js/src/settings/localization.ts', 'public/js'); -mix.js('node_modules/@coreui/coreui/dist/js/coreui.js', 'public/js'); - -/* -mix.scripts([ - 'js/src/bootstrap.js' -], 'public/js/ninja.js'); -*/ - -mix.minify('public/js/ninja.js'); -mix.minify('public/js/coreui.js'); -mix.minify('public/js/client_show.js'); -mix.minify('public/js/client_edit.js'); -mix.minify('public/js/client_create.js'); -mix.minify('public/js/client_list.js'); -mix.minify('public/js/localization.js'); - -mix.styles([ - 'node_modules/@coreui/coreui/dist/css/coreui.css', - 'node_modules/@coreui/icons/css/coreui-icons.css', - 'node_modules/font-awesome/css/font-awesome.css' -], 'public/css/ninja.css'); - -mix.minify('public/css/ninja.css'); +mix.copyDirectory('node_modules/@coreui/coreui/dist/css/coreui.min.css', 'public/vendors/css/coreui.min.css'); +mix.copyDirectory('node_modules/@coreui/icons/css/coreui-icons.min.css', 'public/vendors/css/coreui-icons.min.css'); +mix.copyDirectory('node_modules/@coreui/coreui/dist/css/bootstrap.min.css', 'public/vendors/css/bootstrap.min.css'); +mix.copyDirectory('node_modules/font-awesome/css/font-awesome.min.css', 'public/vendors/css/font-awesome.min.css'); +mix.copyDirectory('node_modules/@coreui/coreui/dist/js/coreui.min.js', 'public/vendors/js/coreui.min.js'); +mix.copyDirectory('node_modules/bootstrap/dist/js/bootstrap.min.js', 'public/vendors/js/bootstrap.min.js'); +mix.copyDirectory('node_modules/jquery/dist/jquery.min.js', 'public/vendors/js/jquery.min.js'); +mix.copyDirectory('node_modules/popper.js/dist/popper.min.js', 'public/vendors/js/popper.min.js'); +mix.copyDirectory('node_modules/perfect-scrollbar/dist/perfect-scrollbar.min.js', 'public/vendors/js/perfect-scrollbar.min.js'); mix.copyDirectory('node_modules/font-awesome/fonts', 'public/fonts');