├── .env-example
├── .gitignore
├── LICENSE
├── README.md
├── app
├── App
│ ├── App.php
│ ├── Auth
│ │ └── Auth.php
│ ├── Console
│ │ ├── Command.php
│ │ ├── Commands
│ │ │ └── Generator
│ │ │ │ ├── ControllerGeneratorCommand.php
│ │ │ │ └── MiddlewareGeneratorCommand.php
│ │ ├── Console.php
│ │ ├── Kernel.php
│ │ ├── Traits
│ │ │ └── Generatable.php
│ │ └── stubs
│ │ │ ├── controller.stub
│ │ │ └── middleware.stub
│ ├── Database
│ │ ├── Permission.php
│ │ ├── Role.php
│ │ ├── User.php
│ │ └── UserRole.php
│ ├── Http
│ │ ├── Controllers
│ │ │ ├── Admin
│ │ │ │ ├── AdminController.php
│ │ │ │ ├── AdminPermissionController.php
│ │ │ │ ├── AdminRoleController.php
│ │ │ │ └── AdminUserController.php
│ │ │ ├── Auth
│ │ │ │ ├── ActivationController.php
│ │ │ │ ├── LoginController.php
│ │ │ │ ├── PasswordResetController.php
│ │ │ │ ├── RegisterController.php
│ │ │ │ └── SettingsController.php
│ │ │ ├── Controller.php
│ │ │ └── HomeController.php
│ │ └── Middleware
│ │ │ ├── AdminMiddleware.php
│ │ │ ├── AuthMiddleware.php
│ │ │ ├── CsrfMiddleware.php
│ │ │ ├── GuestMiddleware.php
│ │ │ ├── Middleware.php
│ │ │ ├── OldInputMiddleware.php
│ │ │ ├── Pagination.php
│ │ │ ├── RememberMiddleware.php
│ │ │ └── RequiresSecureRequestMiddleware.php
│ ├── Lib
│ │ ├── Cookie.php
│ │ ├── Flash.php
│ │ ├── Hash.php
│ │ └── Session.php
│ ├── Mail
│ │ ├── Mailer.php
│ │ └── Mailtrap
│ │ │ └── Message.php
│ ├── Traits
│ │ └── HasPermissionsTrait.php
│ ├── Twig
│ │ └── TwigExtension.php
│ └── Validation
│ │ ├── Validator.php
│ │ └── Violin
│ │ ├── Contracts
│ │ ├── MessageBagContract.php
│ │ ├── RuleContract.php
│ │ └── ValidatorContract.php
│ │ ├── Rules
│ │ ├── AlnumDashRule.php
│ │ ├── AlnumRule.php
│ │ ├── AlphaRule.php
│ │ ├── ArrayRule.php
│ │ ├── BetweenRule.php
│ │ ├── BoolRule.php
│ │ ├── CheckedRule.php
│ │ ├── DateRule.php
│ │ ├── EmailRule.php
│ │ ├── IntRule.php
│ │ ├── IpRule.php
│ │ ├── MatchesRule.php
│ │ ├── MaxRule.php
│ │ ├── MinRule.php
│ │ ├── NumberRule.php
│ │ ├── RegexRule.php
│ │ ├── RequiredRule.php
│ │ └── UrlRule.php
│ │ ├── Support
│ │ └── MessageBag.php
│ │ └── Violin.php
├── Migration
│ └── Migration.php
└── helpers.php
├── auth.sql
├── bootstrap
├── app.php
└── container.php
├── composer.json
├── config
├── app.php
├── database.php
├── lang.php
├── mail.php
└── plugins.php
├── database
├── migrations
│ ├── 20190527142257_permissions.php
│ ├── 20190527142308_roles.php
│ ├── 20190527142321_roles_permissions.php
│ ├── 20190527142334_users.php
│ ├── 20190527142340_users_permissions.php
│ └── 20190527142344_users_roles.php
└── seeds
│ ├── PermissionSeeder.php
│ ├── RolePermissionSeeder.php
│ └── RoleSeeder.php
├── forge
├── gulpfile.js
├── package.json
├── phinx
├── phinx.php
├── public
├── .htaccess
├── css
│ └── app.css
├── index.php
└── js
│ ├── app.min.js
│ └── jquery.min.js
├── resources
├── assets
│ ├── js
│ │ ├── app.js
│ │ └── bootstrap.js
│ └── sass
│ │ ├── app.scss
│ │ └── components
│ │ ├── _base.scss
│ │ └── bootstrap
│ │ └── _custom.scss
├── phinx
│ └── Migration.template.php.dist
└── views
│ ├── admin
│ ├── home.twig
│ ├── permission
│ │ ├── create.twig
│ │ ├── delete.twig
│ │ ├── edit.twig
│ │ └── list.twig
│ ├── role
│ │ ├── create.twig
│ │ ├── delete.twig
│ │ ├── edit.twig
│ │ └── list.twig
│ ├── templates
│ │ ├── admin.twig
│ │ └── partials
│ │ │ └── _menu.twig
│ └── user
│ │ ├── adminlist.twig
│ │ ├── delete.twig
│ │ ├── edit.twig
│ │ └── list.twig
│ ├── auth
│ ├── account
│ │ └── settings.twig
│ ├── login.twig
│ ├── password
│ │ ├── forgot.twig
│ │ └── reset.twig
│ └── register.twig
│ ├── errors
│ ├── 404.twig
│ ├── 405.twig
│ └── 500.twig
│ ├── home.twig
│ ├── mail
│ ├── auth
│ │ └── activate.twig
│ └── password
│ │ └── forgot.twig
│ ├── pagination.twig
│ └── templates
│ ├── app.twig
│ └── partials
│ ├── alerts.twig
│ └── nav.twig
└── routes
├── admin.php
└── web.php
/.env-example:
--------------------------------------------------------------------------------
1 | APP_ENV=development
2 | APP_NAME="My App"
3 | APP_URL=http://127.0.0.1
4 | APP_AUTH_ID=user_id
5 | APP_ACTIVATION_METHOD=mail
6 |
7 | DB_CONNECTION=mysql
8 | DB_HOST=127.0.0.1
9 | DB_PORT=3306
10 | DB_DATABASE=auth
11 | DB_USERNAME=root
12 | DB_PASSWORD=
13 |
14 | MAIL_HOST=smtp.mailtrap.io
15 | MAIL_PORT=2525
16 | MAIL_USERNAME=
17 | MAIL_PASSWORD=
18 | MAIL_FROM=
19 |
20 | RECAPTCHA_PUBLIC=
21 | RECAPTCHA_SECRET=
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.lock
2 | /vendor
3 | .env
4 | /node_modules
5 | .phpintel
6 | /.idea
7 | 1.IDEIAS.txt
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Savage
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Slim 3 Authentication
2 | A very easy to use Slim 3 authentication system.
3 |
4 | [](https://packagist.org/packages/devsavage/slim-3-authentication)
5 | [](https://packagist.org/packages/devsavage/slim-3-authentication)
6 |
7 | If you stumble upon any vulnerabilities within this package, more importantly with the role/permission system, please send your findings to: **savage@savagedev.io**.
8 |
9 | ## Getting Started
10 |
11 | ### Prerequisites
12 |
13 | You will need the following to get started:
14 |
15 | * A web server with URL rewriting
16 | - PHP 5.5 or newer
17 | - A SSL certificate will be required in production environments! Check out [HTTPS Is Easy](https://httpsiseasy.com/) for help setting this up!
18 | * [Composer](https://getcomposer.org/)
19 | * [Yarn](https://yarnpkg.com/) or [npm](https://www.npmjs.com/)
20 |
21 | ### Installing
22 | #### Clone the project:
23 | ```
24 | git clone https://github.com/devsavage/slim-3-authentication.git your-project-name
25 | ```
26 |
27 | #### Install the composer dependencies:
28 | ```bash
29 | $ cd your-project-name && composer install
30 | ```
31 |
32 | #### Inside your project folder, install the node dependencies using yarn or npm:
33 | ```bash
34 | $ yarn install
35 | ```
36 |
37 | #### Rename *_.env-example_* to *_.env_*
38 |
39 | #### Update *_.env_* to your project's configuration
40 | ```bash
41 | APP_ENV=development
42 | ```
43 | You will need to update the **APP_ENV** variable to "production" when serving your application outside of a local environment!
44 |
45 | #### Build assets (prodution or development)
46 | ```bash
47 | $ yarn prod
48 | ```
49 |
50 | ```bash
51 | $ yarn dev
52 | ```
53 | #### Database and Admin
54 | 1. Import auth.sql file to your database.
55 | 2. Open your site, register a new user and click on activation link sent to your email
56 | 3. Go to **phpMyAdmin**, select **user_roles** table and insert a new record. Select your user on **user_id** field, select "superadmin" on **role_id** field and confirm.
57 | 4. Login on site to see "Admin Dashboard" on header menu
58 |
59 | #### Migrations and Seeds
60 | Create migration file
61 | ```bash
62 | php phinx create MigrationName
63 | ```
64 | Create seed file
65 | ```bash
66 | php phinx seed:create SeedName
67 | ```
68 | Run migrations
69 | ```bash
70 | php phinx migrate
71 | ```
72 | Run seeds
73 | ```bash
74 | php phinx seed:run
75 | ```
76 | Use `php phinx` on terminal to see all available command list.
77 |
78 | #### You will also need Google reCAPTCHA API keys. Get them [here](https://www.google.com/recaptcha).
79 |
80 | *If you would like to completely disable reCAPTCHA, see this [page](https://github.com/devsavage/slim-3-authentication/wiki/Completely-remove-reCAPTCHA)*
81 |
82 | ### Check out the [wiki](https://github.com/devsavage/slim-3-authentication/wiki/) for more information and details on how to add new controllers, routes and more.
83 |
84 | ## License
85 |
86 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
87 |
--------------------------------------------------------------------------------
/app/App/App.php:
--------------------------------------------------------------------------------
1 | map($methods, $uri, function($request, $response, $args) use ($methods, $uri, $controller, $func) {
16 | $callable = new $controller($request, $response, $args, $this);
17 | return call_user_func_array([$callable, $request->getMethod() . ucfirst($func)], $args);
18 | });
19 | }
20 |
21 | return $this->map($methods, $uri, function($request, $response, $args) use ($controller, $uri) {
22 | $callable = new $controller($request, $response, $args, $this);
23 | return call_user_func_array([$callable, $request->getMethod()], $args);
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/App/Auth/Auth.php:
--------------------------------------------------------------------------------
1 | ci = $ci;
22 | }
23 |
24 | protected function configure()
25 | {
26 | $this->setName($this->command)->setDescription($this->description);
27 |
28 | $this->addArguments();
29 | $this->addOptions();
30 | }
31 |
32 | protected function execute(InputInterface $input, OutputInterface $output)
33 | {
34 | $this->input = $input;
35 | $this->output = $output;
36 |
37 | return $this->handle($input, $output);
38 | }
39 |
40 | protected function argument($name)
41 | {
42 | return $this->input->getArgument($name);
43 | }
44 |
45 | protected function option($name)
46 | {
47 | return $this->input->getOption($name);
48 | }
49 |
50 | protected function addArguments()
51 | {
52 | foreach ($this->arguments() as $argument) {
53 | $this->addArgument($argument[0], $argument[1], $argument[2]);
54 | }
55 | }
56 |
57 | protected function addOptions()
58 | {
59 | foreach ($this->options() as $option) {
60 | $this->addOption($option[0], $option[1], $option[2], $option[3], $option[4]);
61 | }
62 | }
63 |
64 | protected function info($value)
65 | {
66 | return $this->output->writeln('' . $value . ' ');
67 | }
68 |
69 | protected function error($value)
70 | {
71 | return $this->output->writeln('' . $value . ' ');
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/App/Console/Commands/Generator/ControllerGeneratorCommand.php:
--------------------------------------------------------------------------------
1 | argument('name')));
27 |
28 | $fileName = array_pop($fileParts);
29 |
30 | $cleanPath = implode('/', $fileParts);
31 |
32 | if (count($fileParts) >= 1) {
33 | $path = $path . $cleanPath;
34 |
35 | $namespace = $namespace . '\\' . str_replace('/', '\\', $cleanPath);
36 |
37 | if (!is_dir($path)) {
38 | mkdir($path, 0777, true);
39 | }
40 | }
41 |
42 | $target = $path . '/' . $fileName . '.php';
43 |
44 | if (file_exists($target)) {
45 | return $this->error('Controller already exists!');
46 | }
47 |
48 | $stub = $this->generateStub('controller', [
49 | 'DummyClass' => $fileName,
50 | 'DummyNamespace' => $namespace,
51 | ]);
52 |
53 | file_put_contents($target, $stub);
54 |
55 | return $this->info('Controller generated!');
56 | }
57 |
58 | protected function arguments()
59 | {
60 | return [
61 | ['name', InputArgument::REQUIRED, 'The name of the controller to generate.']
62 | ];
63 | }
64 |
65 | protected function options()
66 | {
67 | return [
68 |
69 | ];
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/App/Console/Commands/Generator/MiddlewareGeneratorCommand.php:
--------------------------------------------------------------------------------
1 | argument('name')));
27 |
28 | $fileName = array_pop($fileParts);
29 |
30 | $cleanPath = implode('/', $fileParts);
31 |
32 | if (count($fileParts) >= 1) {
33 | $path = $path . $cleanPath;
34 |
35 | $namespace = $namespace . '\\' . str_replace('/', '\\', $cleanPath);
36 |
37 | if (!is_dir($path)) {
38 | mkdir($path, 0777, true);
39 | }
40 | }
41 |
42 | $target = $path . '/' . $fileName . '.php';
43 |
44 | if (file_exists($target)) {
45 | return $this->error('Middleware already exists!');
46 | }
47 |
48 | $stub = $this->generateStub('middleware', [
49 | 'DummyClass' => $fileName,
50 | 'DummyNamespace' => $namespace,
51 | ]);
52 |
53 | file_put_contents($target, $stub);
54 |
55 | return $this->info('Middleware generated!');
56 | }
57 |
58 | protected function arguments()
59 | {
60 | return [
61 | ['name', InputArgument::REQUIRED, 'The name of the middleware to generate.']
62 | ];
63 | }
64 |
65 | protected function options()
66 | {
67 | return [
68 |
69 | ];
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/App/Console/Console.php:
--------------------------------------------------------------------------------
1 | slim = $slim;
16 | }
17 |
18 | public function boot(Kernel $kernel)
19 | {
20 | foreach ($kernel->getCommands() as $command) {
21 | $this->add(new $command($this->getSlim()->getContainer()));
22 | }
23 | }
24 |
25 | protected function getSlim()
26 | {
27 | return $this->slim;
28 | }
29 | }
--------------------------------------------------------------------------------
/app/App/Console/Kernel.php:
--------------------------------------------------------------------------------
1 | commands, $this->defaultCommands);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/App/Console/Traits/Generatable.php:
--------------------------------------------------------------------------------
1 | stubDirectory . '/' . $name . '.stub')
15 | );
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/App/Console/stubs/controller.stub:
--------------------------------------------------------------------------------
1 | belongsToMany(Role::class, 'roles_permissions');
16 | }
17 | }
--------------------------------------------------------------------------------
/app/App/Database/Role.php:
--------------------------------------------------------------------------------
1 | belongsToMany(Permission::class,'roles_permissions');
18 | }
19 |
20 | public function givePermissionTo(Permission $permission)
21 | {
22 | return $this->permissions()->save($permission);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/App/Database/User.php:
--------------------------------------------------------------------------------
1 | update([
19 | 'remember_identifier' => $identifier,
20 | 'remember_token' => $token,
21 | ]);
22 | }
23 |
24 | public function removeRememberCredentials()
25 | {
26 | $this->updateRememberCredentials(null, null);
27 | }
28 |
29 | public function revokeRecoveryHash()
30 | {
31 | $this->update([
32 | 'recover_hash' => null,
33 | ]);
34 | }
35 |
36 | public function activate($value = true, $hash = null)
37 | {
38 | $this->update([
39 | 'active' => $value,
40 | 'active_hash' => $hash
41 | ]);
42 | }
43 |
44 | public function deactivate($hash = null)
45 | {
46 | $this->activate(false, $hash);
47 | }
48 |
49 | public function userRoles()
50 | {
51 | return $this->hasMany(UserRole::class, 'user_id');
52 | }
53 |
54 | public function isAdmin()
55 | {
56 | return $this->hasRole('admin');
57 | }
58 |
59 | public function isSuperAdmin()
60 | {
61 | return $this->hasRole('superadmin');
62 | }
63 |
64 | /**
65 | * Make this functionality better.
66 | */
67 |
68 | public function giveRole($title)
69 | {
70 | $role = Role::where('title', $title)->first();
71 |
72 | if(!$role) {
73 | return false;
74 | }
75 |
76 | $userRoles = $this->userRoles();
77 |
78 | if($userRoles->where('role_id', $role->id)->first()) {
79 | return true;
80 | }
81 |
82 | return $this->userRoles()->create([
83 | 'role_id' => $role->id,
84 | ]);
85 | }
86 |
87 | /**
88 | * Make this functionality better.
89 | */
90 |
91 | public function removeRole($title)
92 | {
93 | $role = Role::where('title', $title)->first();
94 |
95 | if(!$role) {
96 | return false;
97 | }
98 |
99 | $userRole = $this->userRoles()->where('role_id', $role->id)->first();
100 |
101 | if($userRole) {
102 | return $userRole->delete();
103 | }
104 |
105 | return true;
106 | }
107 |
108 | public function can($action)
109 | {
110 | $permission = Permission::where('name', $action)->first();
111 |
112 | if(!$permission) {
113 | return false;
114 | }
115 |
116 | return $this->hasPermissionTo($permission);
117 | }
118 |
119 | public function canEdit(User $user)
120 | {
121 | if($this->isSuperAdmin() && $user->isSuperAdmin()) {
122 | return false;
123 | }
124 |
125 | if($user->isAdmin() && $this->can('edit admins') || !$user->isAdmin() && $this->can('edit users') && !$user->isSuperAdmin()) {
126 | return true;
127 | }
128 |
129 | return false;
130 | }
131 | }
--------------------------------------------------------------------------------
/app/App/Database/UserRole.php:
--------------------------------------------------------------------------------
1 | belongsTo(User::class, 'user_id','id');
16 | }
17 | }
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Admin/AdminController.php:
--------------------------------------------------------------------------------
1 | render('admin/home');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Admin/AdminPermissionController.php:
--------------------------------------------------------------------------------
1 | render('admin/permission/list', [
13 | 'permissions' => Permission::paginate(),
14 | ]);
15 | }
16 |
17 | public function getEdit($permissionId)
18 | {
19 | $permission = Permission::where('id', $permissionId)->first();
20 |
21 | if(!$this->auth()->user()->can('edit permission') && !$this->auth()->user()->isSuperAdmin()) {
22 | $this->flash('error', $this->lang('admin.permission.general.cant_edit'));
23 | return $this->redirect('admin.permissions.list');
24 | }
25 |
26 | return $this->render('admin/permission/edit', [
27 | 'permission' => $permission,
28 | ]);
29 | }
30 |
31 | public function postEdit($permissionId)
32 | {
33 | $name = $this->param('name');
34 |
35 | $permission = Permission::where('id', $permissionId)->first();
36 |
37 | if(!$this->user()->can('edit permission') && !$this->auth()->user()->isSuperAdmin()) {
38 | $this->flash("error", $this->lang('admin.permission.general.not_authorized'));
39 | return $this->redirect('admin.permissions.list');
40 | }
41 |
42 | $validator = $this->validator()->validate([
43 | 'name|Name' => [$name, "required|adminUniqueName({$name},{$permission->id})"],
44 | ]);
45 |
46 | if(!$validator->passes()) {
47 | $this->flashNow('error', $this->lang('admin.general.fail'));
48 | return $this->render('admin/permission/edit', [
49 | 'permission' => $permission,
50 | 'errors' => $validator->errors(),
51 | ]);
52 | }
53 |
54 | $permission->update([
55 | 'name' => $name
56 | ]);
57 |
58 | $this->flash('success', $this->lang('admin.general.success'));
59 | return $this->redirect('admin.permissions.edit', [
60 | 'permissionId' => $permissionId,
61 | ]);
62 | }
63 |
64 | public function getCreate()
65 | {
66 |
67 | if(!$this->auth()->user()->can('create permission') && !$this->auth()->user()->isSuperAdmin()) {
68 | $this->flash('error', $this->lang('admin.permission.general.cant_create'));
69 | return $this->redirect('admin.permissions.list');
70 | }
71 |
72 | return $this->render('admin/permission/create');
73 | }
74 |
75 | public function postCreate()
76 | {
77 | $name = $this->param('name');
78 |
79 | if(!$this->user()->can('edit permission') && !$this->auth()->user()->isSuperAdmin()) {
80 | $this->flash("error", $this->lang('admin.permission.general.not_authorized'));
81 | return $this->redirect('admin.permissions.list');
82 | }
83 |
84 | $validator = $this->validator()->validate([
85 | 'name|Title' => [$name, "required|adminUniqueTitle()"],
86 | ]);
87 |
88 | if(!$validator->passes()) {
89 | $this->flashNow('error', $this->lang('admin.general.fail'));
90 | return $this->render('admin/permission/create', [
91 | 'errors' => $validator->errors(),
92 | ]);
93 | }
94 |
95 | Permission::create([
96 | 'name' => $name
97 | ]);
98 |
99 | $this->flash('success', $this->lang('admin.general.created'));
100 | return $this->redirect('admin.permissions.list');
101 | }
102 |
103 | public function getDelete($permissionId)
104 | {
105 | $permission = Permission::where('id', $permissionId)->first();
106 |
107 | if(!$this->user()->can('edit permission') && !$this->auth()->user()->isSuperAdmin()) {
108 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
109 | return $this->redirect('admin.permissions.list');
110 | }
111 |
112 | return $this->render('admin/permission/delete', [
113 | 'permission' => $permission,
114 | ]);
115 | }
116 |
117 | public function postDelete($permissionId)
118 | {
119 | $permission = Permission::where('id', $permissionId)->first();
120 |
121 | if(!$this->user()->can('delete permission') && !$this->auth()->user()->isSuperAdmin()) {
122 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
123 | return $this->redirect('admin.permissions.list');
124 | }
125 |
126 | $delete = $this->param('delete');
127 |
128 | if(!$delete) {
129 | return $this->redirect('admin.home');
130 | }
131 |
132 | if($delete === "true") {
133 | $permission->delete();
134 | $this->flash('success', $this->lang('admin.general.deleted'));
135 | return $this->redirect('admin.permissions.list');
136 | }
137 |
138 | $this->flash('info', $this->lang('admin.general.not_deleted'));
139 | return $this->redirect('admin.permissions.edit', [
140 | 'permissionId' => $permissionId
141 | ]);
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Admin/AdminRoleController.php:
--------------------------------------------------------------------------------
1 | render('admin/role/list', [
14 | 'roles' => Role::where("hidden", false)->paginate(),
15 | ]);
16 | }
17 |
18 | public function getEdit($roleId)
19 | {
20 | $role = Role::with('permissions')->where('id', $roleId)->first();
21 |
22 | if((bool)$role->hidden) {
23 | $this->flash('error', $this->lang('admin.role.general.cant_edit'));
24 | return $this->redirect('admin.roles.list');
25 | }
26 |
27 | $permissions = Permission::all();
28 |
29 | if(!$this->auth()->user()->can('edit role') && !$this->auth()->user()->isSuperAdmin()) {
30 | $this->flash('error', $this->lang('admin.role.general.cant_edit'));
31 | return $this->redirect('admin.roles.list');
32 | }
33 |
34 | return $this->render('admin/role/edit', [
35 | 'role' => $role,
36 | 'permissions' => $permissions,
37 | ]);
38 | }
39 |
40 | public function postEdit($roleId)
41 | {
42 | $title = $this->param('title');
43 | $permissions = $this->param('permissions');
44 |
45 | $role = Role::where('id', $roleId)->where("hidden", false)->first();
46 |
47 | if(!$this->user()->can('edit role') && !$this->auth()->user()->isSuperAdmin()) {
48 | $this->flash("error", $this->lang('admin.role.general.not_authorized'));
49 | return $this->redirect('admin.roles.list');
50 | }
51 |
52 | $validator = $this->validator()->validate([
53 | 'title|Title' => [$title, "required|adminUniqueTitle({$title},{$role->id})"],
54 | 'permissions|Permissions' => [$permissions, "array"]
55 | ]);
56 |
57 | if(!$validator->passes()) {
58 | $this->flashNow('error', $this->lang('admin.general.fail'));
59 | return $this->render('admin/role/edit', [
60 | 'role' => $role,
61 | 'errors' => $validator->errors(),
62 | ]);
63 | }
64 |
65 | $role->update([
66 | 'title' => $title
67 | ]);
68 |
69 | $role->permissions()->detach();
70 |
71 | if($permissions){
72 | foreach ($permissions as $permission_name) {
73 | $permission = Permission::where('id',$permission_name)->first();
74 | $role->givePermissionTo($permission);
75 | }
76 | }
77 |
78 | $this->flash('success', $this->lang('admin.general.success'));
79 | return $this->redirect('admin.roles.edit', [
80 | 'roleId' => $roleId,
81 | ]);
82 | }
83 |
84 | public function getCreate()
85 | {
86 | $permissions = Permission::all();
87 |
88 | if(!$this->auth()->user()->can('create role') && !$this->auth()->user()->isSuperAdmin()) {
89 | $this->flash('error', $this->lang('admin.role.general.cant_create'));
90 | return $this->redirect('admin.roles.list');
91 | }
92 |
93 | return $this->render('admin/role/create',[
94 | 'permissions' => $permissions,
95 | ]);
96 | }
97 |
98 | public function postCreate()
99 | {
100 | $title = $this->param('title');
101 | $permissions = $this->param('permissions');
102 |
103 | if(!$this->user()->can('edit role') && !$this->auth()->user()->isSuperAdmin()) {
104 | $this->flash("error", $this->lang('admin.role.general.not_authorized'));
105 | return $this->redirect('admin.roles.list');
106 | }
107 |
108 | $validator = $this->validator()->validate([
109 | 'title|Title' => [$title, "required|adminUniqueTitle()"],
110 | ]);
111 |
112 | if(!$validator->passes()) {
113 | $this->flashNow('error', $this->lang('admin.general.fail'));
114 | return $this->render('admin/role/create', [
115 | 'errors' => $validator->errors(),
116 | ]);
117 | }
118 |
119 | $role = Role::create([
120 | 'title' => $title
121 | ]);
122 |
123 | $role->permissions()->detach();
124 | if($permissions){
125 | foreach ($permissions as $permission_name) {
126 | $permission = Permission::where('id',$permission_name)->first();
127 | $role->givePermissionTo($permission);
128 | }
129 | }
130 |
131 | $this->flash('success', $this->lang('admin.general.created'));
132 | return $this->redirect('admin.roles.list');
133 | }
134 |
135 | public function getDelete($roleId)
136 | {
137 | $role = Role::where('id', $roleId)->where("hidden", false)->first();
138 |
139 | if(!$this->user()->can('edit role') && !$this->auth()->user()->isSuperAdmin()) {
140 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
141 | return $this->redirect('admin.roles.list');
142 | }
143 |
144 | return $this->render('admin/role/delete', [
145 | 'role' => $role,
146 | ]);
147 | }
148 |
149 | public function postDelete($roleId)
150 | {
151 | $role = Role::where('id', $roleId)->where("hidden", false)->first();
152 |
153 | if(!$this->user()->can('delete role') && !$this->auth()->user()->isSuperAdmin()) {
154 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
155 | return $this->redirect('admin.roles.list');
156 | }
157 |
158 | $delete = $this->param('delete');
159 |
160 | if(!$delete) {
161 | return $this->redirect('admin.home');
162 | }
163 |
164 | if($delete === "true") {
165 | $role->delete();
166 | $this->flash('success', $this->lang('admin.general.deleted'));
167 | return $this->redirect('admin.roles.list');
168 | }
169 |
170 | $this->flash('info', $this->lang('admin.general.not_deleted'));
171 | return $this->redirect('admin.roles.edit', [
172 | 'roleId' => $roleId
173 | ]);
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Admin/AdminUserController.php:
--------------------------------------------------------------------------------
1 | render('admin/user/list', [
16 | 'users' => User::whereNotIn('id',$user_roles)->paginate(),
17 | ]);
18 | }
19 | public function getAdmins()
20 | {
21 | $user_roles = UserRole::get('user_id')->except($this->user()->id);
22 |
23 | return $this->render('admin/user/adminlist', [
24 | 'users' => User::whereIn('id',$user_roles)->paginate(),
25 | ]);
26 | }
27 |
28 | public function getEdit($userId)
29 | {
30 | $user = User::where('id', $userId)->first();
31 |
32 | if(!$this->authorize($user)) {
33 | return $this->redirect('admin.users.list');
34 | }
35 |
36 | if(!$this->user()->can('edit users')) {
37 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
38 | return $this->redirect('admin.users.list');
39 | }
40 |
41 | if($this->param('revoke')) {
42 | $revoke = $this->param('revoke');
43 | switch ($revoke) {
44 | case 'remember':
45 | $user->removeRememberCredentials();
46 | $this->flash('success', $this->lang('admin.user.revoke.remember'));
47 | return $this->redirect('admin.users.edit', [
48 | 'userId' => $user->id,
49 | ]);
50 | break;
51 | case 'recovery':
52 | $user->revokeRecoveryHash();
53 | $this->flash('success', $this->lang('admin.user.revoke.recovery'));
54 | return $this->redirect('admin.users.edit', [
55 | 'userId' => $user->id,
56 | ]);
57 | break;
58 | default:
59 | break;
60 | }
61 | }
62 |
63 | return $this->render('admin/user/edit', [
64 | 'user' => $user,
65 | ]);
66 | }
67 |
68 | public function getEditProfile($userId)
69 | {
70 | return $this->getEdit($userId);
71 | }
72 |
73 | public function postEditProfile($userId)
74 | {
75 | $username = $this->param('username');
76 | $email = $this->param('email');
77 |
78 | $user = User::where('id', $userId)->first();
79 |
80 | if(!$this->authorize($user)) {
81 | return $this->redirect('admin.users.list');
82 | }
83 |
84 | if(!$this->user()->can('edit users')) {
85 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
86 | return $this->redirect('admin.users.list');
87 | }
88 |
89 | $validator = $this->validator()->validate([
90 | 'username|Username' => [$username, "required|adminUniqueUsername({$user->username})"],
91 | 'email|E-Mail' => [$email, "required|email|adminUniqueEmail({$user->email})"],
92 | ]);
93 |
94 | if(!$validator->passes()) {
95 | $this->flashNow('error', $this->lang('admin.user.update.profile.fail'));
96 | return $this->render('admin/user/edit', [
97 | 'user' => $user,
98 | 'errors' => $validator->errors(),
99 | ]);
100 | }
101 |
102 | $user->update([
103 | 'username' => $username,
104 | 'email' => $email
105 | ]);
106 |
107 | $this->flash('success', $this->lang('admin.user.update.profile.success'));
108 | return $this->redirect('admin.users.edit', [
109 | 'userId' => $userId,
110 | ]);
111 | }
112 |
113 | public function getEditSettings()
114 | {
115 | return $this->getEdit($userId);
116 | }
117 |
118 | public function postEditSettings($userId)
119 | {
120 | $user = User::where('id', $userId)->first();
121 |
122 | if(!$this->authorize($user)) {
123 | return $this->redirect('admin.users.list');
124 | }
125 |
126 | if(!$this->user()->can('edit users')) {
127 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
128 | return $this->redirect('admin.users.list');
129 | }
130 |
131 | $active = $this->param('active');
132 |
133 | switch ($active) {
134 | case 'yes':
135 | $user->activate();
136 | $this->flash('success', $this->lang('admin.user.update.settings.active.yes'));
137 | return $this->redirect('admin.users.edit', [
138 | 'userId' => $user->id,
139 | ]);
140 | break;
141 | case 'resend':
142 | $activeHash = $this->hash->generate(128);
143 | $user->deactivate($activeHash);
144 | $this->mail->send('/mail/auth/activate.twig', ['hash' => $activeHash, 'user' => $user], function($message) use ($user) {
145 | $message->to($user->email);
146 | $message->subject($this->lang('mail.activation.subject'));
147 | });
148 | $this->flash('success', $this->lang('admin.user.update.settings.active.resend'));
149 | return $this->redirect('admin.users.edit', [
150 | 'userId' => $user->id,
151 | ]);
152 | break;
153 | case 'no':
154 | $user->deactivate();
155 | $this->flash('success', $this->lang('admin.user.update.settings.active.no'));
156 | return $this->redirect('admin.users.edit', [
157 | 'userId' => $user->id,
158 | ]);
159 | break;
160 | default:
161 | break;
162 | }
163 | }
164 |
165 | public function getDelete($userId)
166 | {
167 | $user = User::where('id', $userId)->first();
168 |
169 | if(!$this->authorize($user)) {
170 | return $this->redirect('admin.users.list');
171 | }
172 |
173 | if(!$this->user()->can('edit users')) {
174 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
175 | return $this->redirect('admin.users.list');
176 | }
177 |
178 | return $this->render('admin/user/delete', [
179 | 'user' => $user,
180 | ]);
181 | }
182 |
183 | public function postDelete($userId)
184 | {
185 | $user = User::where('id', $userId)->first();
186 |
187 | if(!$this->authorize($user)) {
188 | return $this->redirect('admin.users.list');
189 | }
190 |
191 | if(!$this->user()->can('delete users')) {
192 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
193 | return $this->redirect('admin.users.list');
194 | }
195 |
196 | $delete = $this->param('delete');
197 |
198 | if(!$delete) {
199 | return $this->redirect('admin.home');
200 | }
201 |
202 | if($delete === "true") {
203 | $user->delete();
204 | $this->flash('success', $this->lang('admin.user.general.user_deleted'));
205 | return $this->redirect('admin.users.list');
206 | }
207 |
208 | $this->flash('info', $this->lang('admin.user.general.user_not_deleted'));
209 | return $this->redirect('admin.users.edit', [
210 | 'userId' => $userId
211 | ]);
212 | }
213 |
214 | public function postUpdateRole($userId, $role, $action)
215 | {
216 | $user = User::where('id', $userId)->first();
217 |
218 | if(!$this->authorize($user)) {
219 | return $this->redirect('admin.users.list');
220 | }
221 |
222 | if(!$this->user()->can('manage roles') || $role == "admin" && !$this->user()->can('make admin')) {
223 | $this->flash("error", $this->lang('admin.user.general.not_authorized'));
224 | return $this->redirect('admin.users.list');
225 | }
226 |
227 | switch ($action) {
228 | case 'set':
229 | $user->giveRole($role);
230 | $this->flash("raw_success", "You have set the role to {$role} for {$user->username} .");
231 | break;
232 | case 'remove':
233 | $user->removeRole($role);
234 | $this->flash("raw_success", "You have removed the role {$role} from {$user->username} .");
235 | break;
236 | default:
237 | break;
238 | }
239 |
240 | return $this->redirect('admin.users.edit', [
241 | 'userId' => $userId
242 | ]);
243 | }
244 |
245 | protected function authorize($user)
246 | {
247 | if(!$user) {
248 | $this->flash('error', $this->lang('admin.user.general.user_not_found'));
249 | return false;
250 | }
251 |
252 | if($user->id === $this->user()->id) {
253 | $this->flash('error', $this->lang('admin.user.general.user_edit_from_settings'));
254 | return false;
255 | }
256 |
257 | if(!$this->user()->canEdit($user)) {
258 | $this->flash('error', $this->lang('admin.user.general.cant_edit_user'));
259 | return false;
260 | }
261 |
262 | return true;
263 | }
264 | }
265 |
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Auth/ActivationController.php:
--------------------------------------------------------------------------------
1 | param('identifier');
14 |
15 | // Make sure we check for an identifier first.
16 | if(!$identifier) {
17 | return $this->redirect('home');
18 | }
19 |
20 | $user = User::where('active_hash', $identifier)->first();
21 |
22 | if(!$user) {
23 | $this->flash('error', $this->lang('alerts.account.invalid_active_hash'));
24 | return $this->redirect('auth.login');
25 | }
26 |
27 | if($user->active) {
28 | $this->flash("info", $this->lang('alerts.account.already_activated'));
29 |
30 | $user->update([
31 | 'active_hash' => null
32 | ]);
33 |
34 | return $this->redirect('auth.login');
35 | }
36 |
37 | if(!$user->active) {
38 | $user->update([
39 | 'active' => true,
40 | 'active_hash' => null,
41 | ]);
42 |
43 | $this->flash("success", $this->lang('alerts.account.activated'));
44 |
45 | return $this->redirect('auth.login');
46 | }
47 | }
48 |
49 | public function getResend()
50 | {
51 | if(Session::exists('temp_user_id')) {
52 | $user = User::where('id', Session::get('temp_user_id'))->first();
53 |
54 | if(!$user) {
55 | return $this->redirect('home');
56 | }
57 |
58 | $activeHash = $this->hash->generate(128);
59 |
60 | $user->update([
61 | 'active_hash' => $activeHash
62 | ]);
63 |
64 | $this->mail->send('/mail/auth/activate.twig', ['hash' => $activeHash, 'user' => $user], function($message) use ($user) {
65 | $message->to($user->email);
66 | $message->subject($this->lang('mail.activation.subject'));
67 | });
68 |
69 | Session::destroy('temp_user_id');
70 |
71 | $this->flash('info', $this->lang('alerts.login.resend_activation'));
72 | return $this->redirect('auth.login');
73 | }
74 |
75 | return $this->redirect('auth.login');
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Auth/LoginController.php:
--------------------------------------------------------------------------------
1 | render('auth/login');
17 | }
18 |
19 | public function post()
20 | {
21 | $username = $this->param('username');
22 | $password = $this->param('password');
23 | $remember = $this->param('remember');
24 |
25 | $validator = $this->validator()->validate([
26 | 'username|Username' => [$username, 'required'],
27 | 'password|Password' => [$password, 'required'],
28 | ]);
29 |
30 | if($validator->passes()) {
31 | $user = User::where('username', $username)->orWhere('email', $username)->first();
32 |
33 | if(!$user || !$this->hash->verifyPassword($password, $user->password)) {
34 | $this->flash("error", $this->lang('alerts.login.invalid'));
35 | return $this->redirect('auth.login');
36 | } else if($user && !(bool)$user->active) {
37 | Session::set('temp_user_id', $user->id);
38 | $this->flash("raw_warning", "The account you are trying to access has not been activated. Resend activation link ");
39 | return $this->redirect('auth.login');
40 | } else if($user && $this->hash->verifyPassword($password, $user->password)) {
41 | Session::set($this->config('app.auth_id'), $user->id);
42 |
43 | if(Session::exists('temp_user_id')) {
44 | Session::destroy('temp_user_id');
45 | }
46 |
47 | if($remember === "on") {
48 | $rememberIdentifier = $this->hash->generate(128);
49 | $rememberToken = $this->hash->generate(128);
50 |
51 | $user->updateRememberCredentials($rememberIdentifier, $this->hash->hash($rememberToken));
52 |
53 | Cookie::set($this->config('app.remember_id'),
54 | "{$rememberIdentifier}.{$rememberToken}",
55 | Carbon::now()->addWeek(2)->timestamp
56 | );
57 | }
58 |
59 | return $this->redirect('home');
60 | }
61 | }
62 |
63 | $this->flashNow("error", $this->lang('alerts.login.error'));
64 | return $this->render('auth/login', [
65 | 'errors' => $validator->errors(),
66 | ]);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Auth/PasswordResetController.php:
--------------------------------------------------------------------------------
1 | render('auth/password/forgot');
12 | }
13 |
14 | public function postForgot()
15 | {
16 | $email = $this->param('email');
17 | $response = $this->recaptcha->verify($this->param('g-recaptcha-response'));
18 |
19 | if(!$response->isSuccess()) {
20 | $this->flash('warning', $this->lang('alerts.recaptcha_failed'));
21 | return $this->redirect('auth.password.forgot');
22 | }
23 |
24 | $validator = $this->validator()->validate([
25 | 'email|E-Mail' => [$email, 'required|email'],
26 | ]);
27 |
28 | if($validator->passes()) {
29 | $user = $this->auth->where('email', $email)->first();
30 |
31 | if($user) {
32 | $identifier = $this->hash->generate();
33 |
34 | $user->update([
35 | 'recover_hash' => $this->hash->hash($identifier),
36 | ]);
37 |
38 | $this->mail->send('/mail/password/forgot.twig', ['identifier' => $identifier, 'date' => \Carbon\Carbon::now()->toFormattedDateString(), 'user' => $user], function($message) use ($user) {
39 | $message->to($user->email);
40 | $message->subject($this->lang('mail.password.forgot.subject'));
41 | });
42 | }
43 |
44 | $this->flash("info", $this->lang('alerts.forgot_password_success'));
45 | return $this->redirect('auth.login');
46 | }
47 |
48 | $this->flash('error', $this->lang('alerts.forgot_password_failed'));
49 | return $this->redirect('auth.password.forgot');
50 | }
51 |
52 | public function getReset()
53 | {
54 | $identifier = $this->param('identifier');
55 |
56 | if(!$identifier) {
57 | return $this->redirect('auth.login');
58 | }
59 |
60 | return $this->render('auth/password/reset', [
61 | 'identifier' => $identifier,
62 | ]);
63 | }
64 |
65 | public function postReset()
66 | {
67 | $email = $this->param('email');
68 | $identifier = $this->param('identifier');
69 | $newPassword = $this->param('new_password');
70 | $confirmNewPassword = $this->param('confirm_new_password');
71 |
72 | if(!$email) {
73 | $this->flash('error', $this->lang('alerts.reset_password_no_email'));
74 | return $this->redirect('auth.password.reset', [], [
75 | 'identifier' => $identifier,
76 | ]);
77 | }
78 |
79 | $user = $this->auth->where('email', $email)->first();
80 |
81 | if(!$user) {
82 | return $this->redirect('auth.login');
83 | }
84 |
85 | $knownIdentifier = $user->recover_hash;
86 | $userHash = $this->hash->hash($identifier);
87 |
88 | if(!$knownIdentifier || !$this->hash->verifyHash($knownIdentifier, $userHash)) {
89 | $user->update([
90 | 'recover_hash' => null,
91 | ]);
92 |
93 | $this->flash('error', $this->lang('alerts.reset_password_invalid'));
94 | return $this->redirect('auth.password.forgot');
95 | }
96 |
97 | $validator = $this->validator()->validate([
98 | 'new_password|New Password' => [$newPassword, 'required|min(6)'],
99 | 'confirm_new_password|Confirm New Password' => [$confirmNewPassword, 'required|matches(new_password)']
100 | ]);
101 |
102 | if($validator->passes()) {
103 | $user->update([
104 | 'recover_hash' => null,
105 | 'password' => $this->hash->password($newPassword),
106 | ]);
107 |
108 | $this->flash('success', $this->lang('alerts.reset_password_success'));
109 | return $this->redirect('auth.login');
110 | }
111 |
112 | $this->flashNow('error', $this->lang('alerts.reset_password_failed'));
113 | return $this->render('auth/password/reset', [
114 | 'identifier' => $identifier,
115 | 'errors' => $validator->errors(),
116 | ]);
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Auth/RegisterController.php:
--------------------------------------------------------------------------------
1 | render('auth/register');
14 | }
15 |
16 | public function post()
17 | {
18 | $username = $this->param('username');
19 | $email = $this->param('email');
20 | $password = $this->param('password');
21 | $confirm_password = $this->param('confirm_password');
22 |
23 | if($this->config('app.activation.method') === 'recaptcha') {
24 | $recaptcha = $this->param('g-recaptcha-response');
25 |
26 | if(!$this->recaptcha->verify($recaptcha)->isSuccess()) {
27 | $this->flash('warning', $this->lang('alerts.recaptcha_failed'));
28 | return $this->redirect('auth.register');
29 | }
30 | }
31 |
32 | $validator = $this->validator()->validate([
33 | 'username|Username' => [$username, 'required|min(3)|alnumDash|uniqueUsername'],
34 | 'email|E-Mail' => [$email, 'required|email|uniqueEmail'],
35 | 'password|Password' => [$password, 'required|min(6)'],
36 | 'confirm_password|Confirm Password' => [$confirm_password, 'required|matches(password)'],
37 | ]);
38 |
39 | if($validator->passes()) {
40 | $activeHash = $this->hash->generate(128);
41 |
42 | $user = User::create([
43 | 'username' => $username,
44 | 'email' => $email,
45 | 'password' => $this->hash->password($password),
46 | 'active_hash' => $activeHash,
47 | 'active' => false,
48 | ]);
49 |
50 | if($this->config('app.activation.method') === 'mail') {
51 | $this->flash('info', $this->lang('alerts.registration.requires_mail_activation'));
52 | $this->mail->send('/mail/auth/activate.twig', ['hash' => $activeHash, 'user' => $user], function($message) use ($user) {
53 | $message->to($user->email);
54 | $message->subject($this->lang('mail.activation.subject'));
55 | });
56 | } else {
57 | $user->update([
58 | 'active' => true,
59 | 'active_hash' => null,
60 | ]);
61 |
62 | $this->flash('success', $this->lang('alerts.registration.successful'));
63 | }
64 |
65 | return $this->redirect('auth.login');
66 | }
67 |
68 | $this->flashNow('error', $this->lang('alerts.registration.error'));
69 | return $this->render('auth/register', [
70 | 'errors' => $validator->errors(),
71 | ]);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Auth/SettingsController.php:
--------------------------------------------------------------------------------
1 | render('auth/account/settings');
12 | }
13 |
14 | public function getProfile()
15 | {
16 | return $this->redirect('auth.settings');
17 | }
18 |
19 |
20 | public function getPassword()
21 | {
22 | return $this->redirect('auth.settings');
23 | }
24 |
25 | public function postProfile()
26 | {
27 | $email = $this->param('email');
28 |
29 | $validator = $this->validator()->validate([
30 | 'email|E-Mail' => [$email, 'required|email|uniqueEmail'],
31 | ]);
32 |
33 | if($validator->passes()) {
34 | $user = $this->user()->update([
35 | 'email' => $email,
36 | ]);
37 |
38 | $this->flash('success', $this->lang('alerts.account.profile.updated'));
39 | return $this->redirect('auth.settings');
40 | }
41 |
42 | $this->flashNow("error", $this->lang('alerts.account.profile.failed'));
43 | return $this->render('auth/account/settings', [
44 | 'errors' => $validator->errors(),
45 | ]);
46 | }
47 |
48 | public function postPassword()
49 | {
50 | $currentPassword = $this->param('current_password');
51 | $newPassword = $this->param('new_password');
52 | $confirmNewPassword = $this->param('confirm_new_password');
53 |
54 | $validator = $this->validator()->validate([
55 | 'current_password|Current Password' => [$currentPassword, 'required|matchesCurrentPassword'],
56 | 'new_password|New Password' => [$newPassword, 'required|min(6)'],
57 | 'confirm_new_password|Confirm New Password' => [$confirmNewPassword, 'required|matches(new_password)'],
58 | ]);
59 |
60 | if($validator->passes()) {
61 | $this->user()->update([
62 | 'password' => $this->hash->password($newPassword),
63 | ]);
64 |
65 | $this->flash('success', $this->lang('alerts.account.password.updated'));
66 | return $this->redirect('auth.settings');
67 | }
68 |
69 | $this->flashNow("error", $this->lang('alerts.account.password.failed'));
70 | return $this->render('auth/account/settings', [
71 | 'errors' => $validator->errors(),
72 | ]);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/App/Http/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 | request = $request;
19 | $this->response = $response;
20 | $this->args = $args;
21 | $this->container = $container;
22 | }
23 |
24 | public function __get($property)
25 | {
26 | if ($this->container->{$property}) {
27 | return $this->container->{$property};
28 | }
29 | }
30 |
31 | public function config($key)
32 | {
33 | return $this->config->get($key);
34 | }
35 |
36 | public function lang($key)
37 | {
38 | return $this->config("lang." . $key);
39 | }
40 |
41 | public function param($name)
42 | {
43 | return $this->request->getParam($name);
44 | }
45 |
46 | public function flash($type, $message)
47 | {
48 | return $this->flash->addMessage($type, $message);
49 | }
50 |
51 | public function flashNow($type, $message)
52 | {
53 | return $this->flash->addMessageNow($type, $message);
54 | }
55 |
56 | public function render($name, array $args = [])
57 | {
58 | return $this->container->view->render($this->response, $name . '.twig', $args);
59 | }
60 |
61 | public function redirect($path = null, $args = [], $params = [])
62 | {
63 | $path = $path != null ? $path : 'home';
64 |
65 | return $this->response->withRedirect($this->router()->pathFor($path, $args, $params));
66 | }
67 |
68 | public function notFound()
69 | {
70 | throw new NotFoundException($this->request, $this->response);
71 | }
72 |
73 | public function validator()
74 | {
75 | return new Validator($this->container);
76 | }
77 |
78 | public function auth()
79 | {
80 | return $this->auth;
81 | }
82 |
83 | public function user()
84 | {
85 | return $this->auth()->user();
86 | }
87 |
88 | protected function router()
89 | {
90 | return $this->container['router'];
91 | }
92 | }
--------------------------------------------------------------------------------
/app/App/Http/Controllers/HomeController.php:
--------------------------------------------------------------------------------
1 | render('home');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/App/Http/Middleware/AdminMiddleware.php:
--------------------------------------------------------------------------------
1 | auth()->check()) {
12 | if($this->user()->isAdmin() || $this->user()->isSuperAdmin() || $this->user()->can('view admin pages')) {
13 | $response = $next($request, $response);
14 | return $response;
15 | }
16 | }
17 |
18 | return $this->notFound($request, $response);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/App/Http/Middleware/AuthMiddleware.php:
--------------------------------------------------------------------------------
1 | auth()->check()) {
12 | $this->flash('warning', $this->lang('alerts.requires_auth'));
13 | return $this->redirect($response, 'auth.login');
14 | }
15 |
16 | $response = $next($request, $response);
17 | return $response;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/App/Http/Middleware/CsrfMiddleware.php:
--------------------------------------------------------------------------------
1 | container->view->getEnvironment()->addGlobal('csrf', [
12 | 'field' => '
13 |
14 |
15 | '
16 | ]);
17 |
18 | $response = $next($request, $response);
19 | return $response;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/App/Http/Middleware/GuestMiddleware.php:
--------------------------------------------------------------------------------
1 | auth()->check()) {
12 | return $this->redirect($response, 'home');
13 | }
14 |
15 | $response = $next($request, $response);
16 | return $response;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/App/Http/Middleware/Middleware.php:
--------------------------------------------------------------------------------
1 | container = $container;
15 | }
16 |
17 | public function auth()
18 | {
19 | return $this->container->auth;
20 | }
21 |
22 | public function user()
23 | {
24 | return $this->auth()->user();
25 | }
26 |
27 | public function flash($type, $message)
28 | {
29 | $this->container->flash->addMessage($type, $message);
30 | }
31 |
32 | public function config($key)
33 | {
34 | return $this->container->config->get($key);
35 | }
36 |
37 | public function lang($key)
38 | {
39 | return $this->config("lang." . $key);
40 | }
41 |
42 | public function redirect($response, $path)
43 | {
44 | return $response->withRedirect($this->router()->pathFor($path));
45 | }
46 |
47 | public function notFound($request, $response)
48 | {
49 | throw new NotFoundException($request, $response);
50 | }
51 |
52 | protected function router()
53 | {
54 | return $this->container['router'];
55 | }
56 |
57 | protected function isSecure()
58 | {
59 | if(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' || !empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
60 | return true;
61 | }
62 |
63 | return false;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/App/Http/Middleware/OldInputMiddleware.php:
--------------------------------------------------------------------------------
1 | getParams());
13 | $this->container->view->getEnvironment()->addGlobal('old', Session::get('old'));
14 |
15 | $response = $next($request, $response);
16 | return $response;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/App/Http/Middleware/Pagination.php:
--------------------------------------------------------------------------------
1 | container->view;
12 | \Illuminate\Pagination\Paginator::viewFactoryResolver( function() use ( $view ) {
13 | return new class( $view ) {
14 | private $view;
15 | private $template;
16 | private $data;
17 | public function __construct( \Slim\Views\Twig $view )
18 | {
19 | $this->view = $view;
20 | }
21 | public function make( string $template, $data = null )
22 | {
23 | $this->template = 'pagination.twig';
24 | $this->data = $data;
25 | return $this;
26 | }
27 | public function render()
28 | {
29 | return $this->view->fetch($this->template, $this->data);
30 | }
31 | };
32 | });
33 | \Illuminate\Pagination\Paginator::currentPageResolver(function() use ($request) {
34 | return $request->getParam('page');
35 | });
36 |
37 | return $next( $request, $response ) ;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/App/Http/Middleware/RememberMiddleware.php:
--------------------------------------------------------------------------------
1 | config('app.remember_id')) && !$this->container->auth->check()) {
14 | $data = Cookie::get($this->config('app.remember_id'));
15 | $credentials = explode('.', $data);
16 |
17 | if(empty(trim($data)) || count($credentials) !== 2) {
18 | Cookie::destroy($this->config('app.remember_id'));
19 | return $this->redirect($response, 'home');
20 | } else {
21 | $identifier = $credentials[0];
22 | $token = $this->container->hash->hash($credentials[1]);
23 |
24 | $user = $this->container->auth->where('remember_identifier', $identifier)->first();
25 |
26 | if($user) {
27 | if($this->container->hash->verifyHash($token, $user->remember_token)) {
28 | if($user->active) {
29 | Session::set($this->config('app.auth_id'), $user->id);
30 | // We must define a reponse with a redirect to detect a session when we first hit the page, REQUEST_URI is optional.
31 | $response = $response->withRedirect($this->container->config->get('site.url') . $_SERVER['REQUEST_URI']);
32 | return $next($request, $response);
33 | } else {
34 | Cookie::destroy($this->config('app.remember_id'));
35 |
36 | $user->removeRememberCredentials();
37 |
38 | $this->flash("warning", "Your account has not been activated.");
39 | return $this->redirect($response, 'auth.login');
40 | }
41 | } else {
42 | $user->removeRememberCredentials();
43 | }
44 | }
45 | }
46 | }
47 |
48 | $response = $next($request, $response);
49 | return $response;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/App/Http/Middleware/RequiresSecureRequestMiddleware.php:
--------------------------------------------------------------------------------
1 | isSecure()) {
12 | throw new \RuntimeException(sprintf("Insecure requests are not allowed for %s!", $request->getRequestTarget()));
13 | }
14 |
15 | $response = $next($request, $response);
16 | return $response;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/App/Lib/Cookie.php:
--------------------------------------------------------------------------------
1 | forNow[$key])) {
14 | $this->forNow[$key] = [];
15 | }
16 |
17 | $this->forNow[$key][] = $message;
18 | }
19 |
20 | public function getMessages()
21 | {
22 | $messages = $this->fromPrevious;
23 |
24 | foreach($this->forNow as $key => $values) {
25 | if(!isset($messages[$key])){
26 | $messages[$key] = [];
27 | }
28 |
29 | foreach($values as $value){
30 | array_push($messages[$key], $value);
31 | }
32 | }
33 |
34 | return $messages;
35 | }
36 |
37 | public function getMessage($key)
38 | {
39 | $messages = $this->getMessages();
40 | return (isset($messages[$key])) ? $messages[$key] : null;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/App/Lib/Hash.php:
--------------------------------------------------------------------------------
1 | _random = new RandomLib;
14 | }
15 |
16 | public function password($password)
17 | {
18 | return password_hash($password, PASSWORD_DEFAULT);
19 | }
20 |
21 | public function verifyPassword($givenPassword, $knownPassword)
22 | {
23 | return password_verify($givenPassword, $knownPassword);
24 | }
25 |
26 | public function generate($length = 64, $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
27 | {
28 | return $this->generator()->generateString($length, $characters);
29 | }
30 |
31 | public function hash($input)
32 | {
33 | return hash('sha256', $input);
34 | }
35 |
36 | public function verifyHash($knownHash, $givenHash)
37 | {
38 | return $this->hash_verify($knownHash, $givenHash);
39 | }
40 |
41 | protected function generator()
42 | {
43 | return $this->_random->getMediumStrengthGenerator();
44 | }
45 |
46 | protected function hash_verify($known_string, $user_string)
47 | {
48 | if (func_num_args() !== 2) {
49 | // handle wrong parameter count as the native implentation
50 | trigger_error('hash_verify() expects exactly 2 parameters, ' . func_num_args() . ' given', E_USER_WARNING);
51 | return null;
52 | }
53 |
54 | if (is_string($known_string) !== true) {
55 | trigger_error('hash_verify(): Expected known_string to be a string, ' . gettype($known_string) . ' given', E_USER_WARNING);
56 | return false;
57 | }
58 |
59 | $known_string_len = strlen($known_string);
60 | $user_string_type_error = 'hash_verify(): Expected user_string to be a string, ' . gettype($user_string) . ' given'; // prepare wrong type error message now to reduce the impact of string concatenation and the gettype call
61 | if (is_string($user_string) !== true) {
62 | trigger_error($user_string_type_error, E_USER_WARNING);
63 | // prevention of timing attacks might be still possible if we handle $user_string as a string of diffent length (the trigger_error() call increases the execution time a bit)
64 | $user_string_len = strlen($user_string);
65 | $user_string_len = $known_string_len + 1;
66 | } else {
67 | $user_string_len = $known_string_len + 1;
68 | $user_string_len = strlen($user_string);
69 | }
70 |
71 | if ($known_string_len !== $user_string_len) {
72 | $res = $known_string ^ $known_string; // use $known_string instead of $user_string to handle strings of diffrent length.
73 | $ret = 1; // set $ret to 1 to make sure false is returned
74 | } else {
75 | $res = $known_string ^ $user_string;
76 | $ret = 0;
77 | }
78 |
79 | for ($i = strlen($res) - 1; $i >= 0; $i--) {
80 | $ret |= ord($res[$i]);
81 | }
82 |
83 | return $ret === 0;
84 | }
85 | }
--------------------------------------------------------------------------------
/app/App/Lib/Session.php:
--------------------------------------------------------------------------------
1 | mailer = $mailer;
15 | $this->container = $container;
16 | }
17 |
18 | public function send($template, $data, $callback)
19 | {
20 | $message = new Message($this->mailer);
21 |
22 | $message->body($this->container->twig->render($template, [
23 | 'data' => $data
24 | ]));
25 |
26 | call_user_func($callback, $message);
27 |
28 | $this->mailer->send();
29 | }
30 | }
--------------------------------------------------------------------------------
/app/App/Mail/Mailtrap/Message.php:
--------------------------------------------------------------------------------
1 | mailer = $mailer;
12 | }
13 |
14 | public function to($address)
15 | {
16 | $this->mailer->addAddress($address);
17 | }
18 |
19 | public function subject($subject)
20 | {
21 | $this->mailer->Subject = $subject;
22 | }
23 |
24 | public function body($body)
25 | {
26 | $this->mailer->Body = $body;
27 | }
28 | }
--------------------------------------------------------------------------------
/app/App/Traits/HasPermissionsTrait.php:
--------------------------------------------------------------------------------
1 | getAllPermissions(Arr::flatten($permissions));
16 |
17 | if ($permissions === null) {
18 | return $this;
19 | }
20 |
21 | if($this->permissions()->exists($permissions)) {
22 | return $this;
23 | }
24 |
25 | $this->permissions()->saveMany($permissions);
26 |
27 | return $this;
28 | }
29 |
30 | public function withdrawPermissionTo(...$permissions)
31 | {
32 | $permissions = $this->getAllPermissions(Arr::flatten($permissions));
33 |
34 | $this->permissions()->detach($permissions);
35 |
36 | return $this;
37 | }
38 |
39 | public function updatePermissions(...$permissions)
40 | {
41 | $this->permissions()->detach();
42 |
43 | return $this->givePermissionTo($permissions);
44 | }
45 |
46 | public function hasRole(...$roles)
47 | {
48 | foreach ($roles as $role) {
49 | if ($this->roles->contains('title', $role)) {
50 | return true;
51 | }
52 | }
53 |
54 | return false;
55 | }
56 |
57 | public function hasPermissionTo($permission)
58 | {
59 | return $this->hasPermissionThroughRole($permission) || $this->hasPermission($permission);
60 | }
61 |
62 | protected function hasPermissionThroughRole($permission)
63 | {
64 | foreach ($permission->roles as $role) {
65 | if ($this->roles->contains($role)) {
66 | return true;
67 | }
68 | }
69 |
70 | return false;
71 | }
72 |
73 | protected function hasPermission($permission)
74 | {
75 | return (bool) $this->permissions->where('name', $permission->name)->count();
76 | }
77 |
78 | protected function getAllPermissions(array $permissions)
79 | {
80 | return Permission::whereIn('name', $permissions)->get();
81 | }
82 |
83 | public function roles()
84 | {
85 | return $this->belongsToMany(Role::class, 'users_roles', 'user_id');
86 | }
87 |
88 | public function permissions()
89 | {
90 | return $this->belongsToMany(Permission::class, 'users_permissions', 'user_id');
91 | }
92 |
93 |
94 | protected function flatten($array, $depth = INF)
95 | {
96 | return array_reduce($array, function ($result, $item) use ($depth) {
97 | $item = $item instanceof Collection ? $item->all() : $item;
98 |
99 | if (! is_array($item)) {
100 | return array_merge($result, [$item]);
101 | } elseif ($depth === 1) {
102 | return array_merge($result, array_values($item));
103 | } else {
104 | return array_merge($result, $this->flatten($item, $depth - 1));
105 | }
106 | }, []);
107 | }
108 | }
--------------------------------------------------------------------------------
/app/App/Twig/TwigExtension.php:
--------------------------------------------------------------------------------
1 | container = $container;
12 | }
13 |
14 | public function getName()
15 | {
16 | return 'app';
17 | }
18 |
19 | public function getFunctions()
20 | {
21 | return [
22 | new \Twig\TwigFunction('asset', [$this, 'asset']),
23 | new \Twig\TwigFunction('getenv', [$this, 'getenv']),
24 | new \Twig\TwigFunction('config', [$this, 'config']),
25 | new \Twig\TwigFunction('pagination_url', [$this, 'pagination_url']),
26 | ];
27 | }
28 |
29 | public function asset($name)
30 | {
31 | return env('APP_URL') . '/' . $name;
32 | }
33 |
34 | public function getenv($key, $default = null)
35 | {
36 | return env($key, $default);
37 | }
38 |
39 | public function config($key)
40 | {
41 | return $this->container->config->get($key);
42 | }
43 |
44 | public function pagination_url($path,$url)
45 | {
46 |
47 | return $path.ltrim($url, '/');
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/App/Validation/Validator.php:
--------------------------------------------------------------------------------
1 | container = $container;
18 | $this->auth = $container->auth;
19 |
20 | $this->addFieldMessages([
21 | 'username' => [
22 | 'min' => 'Your username must be a minimum of {$0} characters.',
23 | 'uniqueUsername' => 'This username has already been taken.',
24 | ],
25 |
26 | 'email' => [
27 | 'uniqueEmail' => 'This e-mail is already in use.',
28 | ],
29 |
30 | 'password' => [
31 | 'min' => 'Your password must be a minimum of {$0} characters.',
32 | ],
33 |
34 | 'new_password' => [
35 | 'min' => 'Your new password must be a minimum of {$0} characters.',
36 | ],
37 |
38 | 'confirm_password' => [
39 | 'matches' => 'Confirm Password must match Password.'
40 | ],
41 |
42 | 'confirm_new_password' => [
43 | 'matches' => 'Confirm New Password must match New Password.'
44 | ],
45 | ]);
46 |
47 | $this->addRuleMessages([
48 | 'matchesCurrentPassword' => 'Your current password is incorrect.',
49 | 'adminUniqueEmail' => "This e-mail is tied to another account.",
50 | 'adminUniqueUsername' => "This username is taken by another account.",
51 | 'adminUniqueTitle' => "This title is taken by another role.",
52 | 'adminUniqueName' => "This name is taken by another permission.",
53 | ]);
54 | }
55 |
56 | public function validate_uniqueUsername($value, $input, $args)
57 | {
58 | return !(bool) $this->auth->where('username', $value)->count();
59 | }
60 |
61 | public function validate_uniqueEmail($value, $input, $args)
62 | {
63 | $user = $this->auth->where('email', $value);
64 |
65 | if($this->auth->check() && $this->auth->user()->email === $value) {
66 | return true;
67 | }
68 |
69 | return !(bool) $user->count();
70 | }
71 |
72 | public function validate_matchesCurrentPassword($value, $input, $args)
73 | {
74 | if($this->auth->check() && $this->container->hash->verifyPassword($value, $this->auth->user()->password)) {
75 | return true;
76 | }
77 |
78 | return false;
79 | }
80 |
81 | public function validate_adminUniqueEmail($value, $input, $args)
82 | {
83 | $user = $this->container->user->where('email', $args[0])->first();
84 |
85 | if(!$user) {
86 | return false;
87 | }
88 |
89 | if($user->email === $value) {
90 | return true;
91 | }
92 |
93 | return !(bool) $this->container->user->where('email', $value)->count();
94 | }
95 |
96 | public function validate_adminUniqueUsername($value, $input, $args)
97 | {
98 | $user = $this->container->user->where('username', $args[0])->first();
99 |
100 | if(!$user) {
101 | return false;
102 | }
103 |
104 | if($user->username === $value) {
105 | return true;
106 | }
107 |
108 | return !(bool) $this->container->user->where('username', $value)->count();
109 | }
110 |
111 | public function validate_adminUniqueTitle($value, $input, $args)
112 | {
113 | $role = Role::where('id', $args[1])->first();
114 |
115 | if(!$role && ($args[1] !== NULL)) {
116 | return false;
117 | }
118 |
119 | if($role->title === $args[0]) {
120 | return true;
121 | }
122 |
123 | return !(bool) Role::where('title', $value)->count();
124 | }
125 |
126 | public function validate_adminUniqueName($value, $input, $args)
127 | {
128 | $role = Permission::where('id', $args[1])->first();
129 |
130 | if(!$role && ($args[1]!==NULL)) {
131 | return false;
132 | }
133 |
134 | if($role->name === $args[0]) {
135 | return true;
136 | }
137 |
138 | return !(bool) Permission::where('name', $value)->count();
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/app/App/Validation/Violin/Contracts/MessageBagContract.php:
--------------------------------------------------------------------------------
1 | = $args[0] && $value <= $args[1]) ? true : false;
12 | }
13 |
14 | public function error()
15 | {
16 | return '{field} must be between {$0} and {$1}.';
17 | }
18 |
19 | public function canSkip()
20 | {
21 | return true;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/App/Validation/Violin/Rules/BoolRule.php:
--------------------------------------------------------------------------------
1 | = (float) $args[0];
15 | }
16 |
17 | return mb_strlen($value) >= (int) $args[0];
18 | }
19 |
20 | public function error()
21 | {
22 | return '{field} must be a minimum of {$0}.';
23 | }
24 |
25 | public function canSkip()
26 | {
27 | return true;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/App/Validation/Violin/Rules/NumberRule.php:
--------------------------------------------------------------------------------
1 | $value) {
28 | $this->messages[$key] = (array) $value;
29 | }
30 | }
31 |
32 | /**
33 | * Checks if the bag has messages for a given key.
34 | *
35 | * @param string $key
36 | * @return boolean
37 | */
38 | public function has($key)
39 | {
40 | return ! is_null($this->first($key));
41 | }
42 |
43 | /**
44 | * Get the first message with a given key.
45 | * If the given key doesn't exist, it returns the first
46 | * message of the bag.
47 | * Returns null if the bag is empty.
48 | *
49 | * @param string $key
50 | * @return string|null
51 | */
52 | public function first($key = null)
53 | {
54 | $messages = is_null($key) ? $this->all() : $this->get($key);
55 | return ($messages && count($messages) > 0) ? $messages[0] : null;
56 | }
57 |
58 | /**
59 | * Get all of the messages from a given key.
60 | * Returns null if the given key is empty, or
61 | * if it doesn't exist.
62 | *
63 | * @param string $key
64 | * @return array|null
65 | */
66 | public function get($key)
67 | {
68 | if (array_key_exists($key, $this->messages)) {
69 | return !empty($this->messages[$key]) ? $this->messages[$key] : null;
70 | }
71 |
72 | return null;
73 | }
74 |
75 | /**
76 | * Get all of the messages in the bag.
77 | *
78 | * @return array
79 | */
80 | public function all()
81 | {
82 | return iterator_to_array(new RecursiveIteratorIterator(
83 | new RecursiveArrayIterator($this->messages)
84 | ), false);
85 | }
86 |
87 | /**
88 | * Return all of the keys in the bag.
89 | *
90 | * @return array
91 | */
92 | public function keys()
93 | {
94 | return array_keys($this->messages);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/Migration/Migration.php:
--------------------------------------------------------------------------------
1 | capsule = new Capsule;
17 | $this->capsule->addConnection([
18 | 'driver' => env('DB_CONNECTION'),
19 | 'host' => env('DB_HOST'),
20 | 'port' => env('DB_PORT'),
21 | 'database' => env('DB_DATABASE'),
22 | 'username' => env('DB_USERNAME'),
23 | 'password' => env('DB_PASSWORD'),
24 | 'charset' => 'utf8',
25 | 'collation' => 'utf8_unicode_ci',
26 | ]);
27 |
28 | $this->capsule->bootEloquent();
29 | $this->capsule->setAsGlobal();
30 | $this->schema = $this->capsule->schema();
31 | }
32 | }
--------------------------------------------------------------------------------
/app/helpers.php:
--------------------------------------------------------------------------------
1 | load();
20 | }
21 |
22 | $app = new App(new Container(
23 | include INC_ROOT . '/container.php'
24 | ));
25 |
26 | $container = $app->getContainer();
27 |
28 | $container['config'] = function($c) {
29 | return new Config(INC_ROOT . '/../config');
30 | };
31 |
32 | $app->add(RememberMiddleware::class);
33 | $app->add(CsrfMiddleware::class);
34 | $app->add(OldInputMiddleware::class);
35 | $app->add(Pagination::class) ;
36 |
37 | $app->add($container->csrf);
38 |
39 | $container['db']->bootEloquent();
40 |
41 | require INC_ROOT . '/../routes/web.php';
42 | require INC_ROOT . '/../routes/admin.php';
43 |
--------------------------------------------------------------------------------
/bootstrap/container.php:
--------------------------------------------------------------------------------
1 | [
4 | 'displayErrorDetails' => getenv('APP_ENV') === "production" ? false : true,
5 | 'determineRouteBeforeAppMiddleware' => true,
6 | 'viewTemplatesDirectory' => INC_ROOT . '/../resources/views',
7 | ],
8 |
9 | 'user' => function($c) {
10 | return new \App\Database\User;
11 | },
12 |
13 | 'auth' => function($c) {
14 | return new \App\Auth\Auth;
15 | },
16 |
17 | 'hash' => function($c) {
18 | return new \App\Lib\Hash;
19 | },
20 |
21 | 'flash' => function($c) {
22 | return new \App\Lib\Flash;
23 | },
24 |
25 | 'recaptcha' => function($c) {
26 | return new \ReCaptcha\ReCaptcha($c->config->get('plugins.recaptcha.secret'));
27 | },
28 |
29 | 'twig' => function($c) {
30 | $twig = new \Twig\Environment(new \Twig\Loader\FilesystemLoader($c['settings']['viewTemplatesDirectory']));
31 |
32 | // We need to load this again to use our functions with our mailing system.
33 | $twig->addExtension(new \App\Twig\TwigExtension($c));
34 |
35 | return $twig;
36 | },
37 |
38 | 'view' => function($c) {
39 | $view = new \Slim\Views\Twig($c['settings']['viewTemplatesDirectory'], [
40 | 'debug' => env('APP_ENV', 'development') === "production" ? false : true
41 | ]);
42 |
43 | $view->getEnvironment()->addGlobal('auth', [
44 | 'check' => $c->auth->check(),
45 | 'user' => $c->auth->user(),
46 | ]);
47 |
48 | $view->addExtension(new \Slim\Views\TwigExtension($c['router'], $c['request']->getUri()));
49 | $view->addExtension(new \Twig\Extension\DebugExtension);
50 | $view->addExtension(new \App\Twig\TwigExtension($c));
51 |
52 | $view->getEnvironment()->addGlobal('flash', $c['flash']);
53 |
54 | return $view;
55 | },
56 |
57 | 'notFoundHandler' => function($c) {
58 | return function($request, $response) use ($c) {
59 | $response = $response->withStatus(404);
60 | return $c->view->render($response, 'errors/404.twig', [
61 | 'request_uri' => urldecode($_SERVER['REQUEST_URI'])
62 | ]);
63 | };
64 | },
65 |
66 | 'notAllowedHandler' => function($c) {
67 | return function ($request, $response, $methods) use ($c) {
68 | $response = $response->withStatus(405);
69 | return $c->view->render($response, 'errors/405.twig', [
70 | 'request_uri' => $_SERVER['REQUEST_URI'],
71 | 'method' => $_SERVER['REQUEST_METHOD'],
72 | 'methods' => implode(', ', $methods)
73 | ]);
74 | };
75 | },
76 |
77 | 'errorHandler' => function($c) {
78 | return function($request, $response, $exception) use ($c) {
79 | $response = $response->withStatus(500);
80 |
81 | $data = [
82 | 'exception' => null
83 | ];
84 |
85 | if(env('APP_ENV') === "development") {
86 | $data['exception'] = $exception->getMessage();
87 | }
88 |
89 | return $c->view->render($response, 'errors/500.twig', $data);
90 | };
91 | },
92 |
93 | 'csrf' => function($c) {
94 | $guard = new \Slim\Csrf\Guard;
95 |
96 | $guard->setFailureCallable(function($request, $response, $next) use ($c) {
97 | $request = $request->withAttribute("csrf_status", false);
98 | if($request->getAttribute('csrf_status') === false) {
99 | $c['flash']->addMessage('error', "CSRF verification failed, terminating your request.");
100 |
101 | return $response->withStatus(400)->withRedirect($c['router']->pathFor('home'));
102 | } else {
103 | return $next($request, $response);
104 | }
105 | });
106 |
107 | return $guard;
108 | },
109 |
110 | 'db' => function($c) {
111 | $capsule = new \Illuminate\Database\Capsule\Manager;
112 |
113 | $capsule->addConnection($c['config']->get('database'), 'default');
114 |
115 | return $capsule;
116 | },
117 |
118 | 'mail' => function($c) {
119 | $mailer = new \PHPMailer;
120 |
121 | $mailer->isSMTP();
122 | $mailer->Host = $c['config']->get('mail.host');
123 | $mailer->Port = $c['config']->get('mail.port');
124 | $mailer->Username = $c['config']->get('mail.username');
125 | $mailer->Password = $c['config']->get('mail.password');
126 | $mailer->SMTPAuth = true;
127 | $mailer->SMTPSecure = false;
128 | $mailer->FromName = $c['config']->get('mail.from.name');
129 | $mailer->From = $c['config']->get('mail.from');
130 |
131 | $mailer->isHTML(true);
132 |
133 | return new \App\Mail\Mailer($mailer, $c);
134 | },
135 | ];
136 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "devsavage/slim-3-authentication",
3 | "description": "An authentication system using the Slim Framework.",
4 | "type": "project",
5 | "version": "2.0.0",
6 | "keywords": ["authentication","slim-3", "slim3", "slimframework", "slim-framework"],
7 | "homepage": "https://github.com/devsavage/slim-3-authentication",
8 | "license": "MIT",
9 | "authors": [
10 | {
11 | "name": "Savage",
12 | "email": "savage@savagedev.io",
13 | "homepage": "https://savagedev.io",
14 | "role": "Developer"
15 | }
16 | ],
17 | "autoload": {
18 | "psr-4": {
19 | "App\\": "app/App",
20 | "Migration\\": "app/Migration"
21 | },
22 | "files": [
23 | "app/helpers.php",
24 | "phinx.php"
25 | ]
26 | },
27 |
28 | "require": {
29 | "php": ">=5.6.0 ^7.2",
30 | "slim/slim": "^3.0",
31 | "illuminate/database": "^5.2",
32 | "illuminate/pagination": "^5.2",
33 | "slim/twig-view": "^2.0",
34 | "slim/flash": "^0.1.0",
35 | "slim/csrf": "^0.6.0",
36 | "ircmaxell/random-lib": "^1.1",
37 | "phpmailer/phpmailer": "^5.2",
38 | "vlucas/phpdotenv": "^3",
39 | "hassankhan/config": "^0.10.0",
40 | "symfony/console": "^3.1",
41 | "google/recaptcha": "~1.1",
42 | "robmorgan/phinx": "^0.10.7"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/config/app.php:
--------------------------------------------------------------------------------
1 | [
4 | 'environment' => env('APP_ENV', 'development'),
5 | 'url' => env('APP_URL', 'http://127.0.0.1'),
6 | 'activation' => [
7 | 'method' => env('APP_ACTIVATION_METHOD', 'mail'),
8 | ],
9 | 'auth_id' => env('APP_AUTH_ID', 'user_id'),
10 | 'remember_id' => env('APP_REMEMBER_ID', 'APP_REMEMBER_TOKEN'),
11 | ]
12 | ];
--------------------------------------------------------------------------------
/config/database.php:
--------------------------------------------------------------------------------
1 | [
4 | 'driver' => env('DB_CONNECTION', 'mysql'),
5 | 'host' => env('DB_HOST', '127.0.0.1'),
6 | 'port' => env('DB_PORT', '3306'),
7 | 'username' => env('DB_USERNAME', 'root'),
8 | 'password' => env('DB_PASSWORD'),
9 | 'database' => env('DB_DATABASE', 'auth'),
10 | 'charset' => 'utf8',
11 | 'collation' => 'utf8_unicode_ci',
12 | ]
13 | ];
--------------------------------------------------------------------------------
/config/lang.php:
--------------------------------------------------------------------------------
1 | [
4 | 'mail' => [
5 | 'activation' => [
6 | 'subject' => env("APP_NAME", "My App") . " Account Activation",
7 | ],
8 |
9 | 'password' => [
10 | 'forgot' => [
11 | 'subject' => env("APP_NAME", "My App") . " Password Reset Request",
12 | ]
13 | ],
14 | ],
15 |
16 | 'alerts' => [
17 | 'requires_auth' => "You must be signed in to access that page.",
18 | 'recaptcha_failed' => "Please verify you are not a robot by completing the reCAPTCHA.",
19 | 'forgot_password_success' => "If your email is valid, you'll receive an email with instructions on how to reset your password.",
20 | 'forgot_password_failed' => "Please enter the e-mail address associated with your account.",
21 | 'reset_password_invalid' => "Your password reset token was invalid. Please submit another password reset request.",
22 | 'reset_password_failed' => "Your password could not be reset at this time.",
23 | 'reset_password_success' => "You have successfully reset your password. You can now login with your new password.",
24 | 'reset_password_no_email' => "Please verify your e-mail.",
25 | 'registration' => [
26 | 'successful' => "Your account has been created!",
27 | 'error' => "Please fix any errors with your registration and try again.",
28 | 'requires_mail_activation' => "Your account has been created but you will need to activate it. Please check your e-mail for instructions.",
29 | ],
30 |
31 | 'login' => [
32 | 'invalid' => "You have supplied invalid credentials.",
33 | 'error' => "Please enter your credentials to continue.",
34 | 'resend_activation' => "Another activation e-mail has been sent. Please check your e-mail for instructions.",
35 | ],
36 |
37 | 'account' => [
38 | 'already_activated' => "Your account has already been activated.",
39 | 'activatied' => "Your account has been activated! You can now login.",
40 | 'invalid_active_hash' => "The active hash you are trying to use has already expired or never existed.",
41 |
42 | 'password' => [
43 | 'updated' => "Your password has been changed.",
44 | 'failed' => "Your password couldn't be changed at this time.",
45 | ],
46 |
47 | 'profile' => [
48 | 'updated' => "Your profile has been updated!",
49 | 'failed' => "Your profile couldn't be updated at this time.",
50 | ]
51 | ]
52 | ],
53 |
54 | 'admin' => [
55 | 'user' => [
56 | 'general' => [
57 | 'user_not_found' => "User not found.",
58 | 'user_edit_from_settings' => "You cannot edit your profile from the Admin Dashboard!",
59 | 'cant_edit_user' => "You do not have permission to edit that user!",
60 | 'user_deleted' => "User has been deleted.",
61 | 'user_not_deleted' => "User was not deleted.",
62 | 'not_authorized' => "You are not authorized to complete that action!",
63 | ],
64 | 'revoke' => [
65 | 'remember' => "User's remember credentials have been removed.",
66 | 'recovery' => "User's recover hash has been revoked.",
67 | ],
68 | 'update' => [
69 | 'profile' => [
70 | 'success' => "User profile updated!",
71 | 'fail' => "User profile cannot be updated!",
72 | ],
73 | 'settings' => [
74 | 'active' => [
75 | 'yes' => "User's account has been activated!",
76 | 'resend' => "User's account has been deactivated and another activation email has been sent.",
77 | 'no' => "User's account has been deactivated!",
78 | ]
79 | ],
80 | ]
81 | ],
82 | 'general' => [
83 | 'created' => "Created successfully!",
84 | 'success' => "Updated successfully!",
85 | 'fail' => "There was an error while trying to process your request!",
86 | 'deleted' => "Item has been deleted.",
87 | 'not_deleted' => "Item was not deleted.",
88 | ],
89 | 'role' => [
90 | 'general' => [
91 | 'cant_edit' => "You do not have permission to edit that role!",
92 | 'cant_create' => "You do not have permission to create new roles!",
93 | 'deleted' => "Role has been deleted.",
94 | 'not_deleted' => "Role was not deleted.",
95 | 'not_authorized' => "You are not authorized to complete that action!",
96 | ],
97 | ]
98 | ],
99 | ]
100 | ];
101 |
--------------------------------------------------------------------------------
/config/mail.php:
--------------------------------------------------------------------------------
1 | [
4 | 'host' => env('MAIL_HOST'),
5 | 'port' => env('MAIL_PORT'),
6 | 'username' => env('MAIL_USERNAME'),
7 | 'password' => env('MAIL_PASSWORD'),
8 | 'from.name' => env('MAIL_FROM_NAME', 'noreply'),
9 | 'from' => env('MAIL_FROM', 'noreply@example.com'),
10 | ]
11 | ];
--------------------------------------------------------------------------------
/config/plugins.php:
--------------------------------------------------------------------------------
1 | [
4 | 'recaptcha' => [
5 | 'public' => env('RECAPTCHA_PUBLIC'),
6 | 'secret' => env('RECAPTCHA_SECRET'),
7 | ]
8 | ]
9 | ];
--------------------------------------------------------------------------------
/database/migrations/20190527142257_permissions.php:
--------------------------------------------------------------------------------
1 | schema->create('permissions', function(Illuminate\Database\Schema\Blueprint $table){
9 | // Auto-increment id
10 | $table->increments('id');
11 | $table->string('name');
12 | // Required for Eloquent's created_at and updated_at columns
13 | $table->timestamps();
14 | });
15 | }
16 | public function down() {
17 | $this->schema->drop('permissions');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/database/migrations/20190527142308_roles.php:
--------------------------------------------------------------------------------
1 | schema->create('roles', function(Illuminate\Database\Schema\Blueprint $table){
9 | // Auto-increment id
10 | $table->increments('id');
11 | $table->string('title');
12 | // Required for Eloquent's created_at and updated_at columns
13 | $table->timestamps();
14 | });
15 | }
16 | public function down() {
17 | $this->schema->drop('roles');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/database/migrations/20190527142321_roles_permissions.php:
--------------------------------------------------------------------------------
1 | schema->create('roles_permissions', function(Illuminate\Database\Schema\Blueprint $table){
9 | // Auto-increment id
10 | $table->increments('id');
11 | $table->unsignedInteger('role_id');
12 | $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
13 | $table->unsignedInteger('permission_id');
14 | $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
15 | //$table->primary(['role_id','permission_id']);
16 | // Required for Eloquent's created_at and updated_at columns
17 | $table->timestamp('created_at')->useCurrent();
18 | $table->timestamp('updated_at')->useCurrent();
19 | });
20 | }
21 | public function down() {
22 | $this->schema->drop('roles_permissions');
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/database/migrations/20190527142334_users.php:
--------------------------------------------------------------------------------
1 | schema->create('users', function(Illuminate\Database\Schema\Blueprint $table){
9 | // Auto-increment id
10 | $table->increments('id');
11 | $table->string('username')->unique()->nullable();
12 | $table->string('email')->unique()->nullable();
13 | $table->string('password')->nullable();
14 | $table->boolean('active')->default(0);
15 | $table->string('active_hash')->nullable();
16 | $table->string('remember_token')->nullable();
17 | $table->string('remember_identifier')->nullable();
18 | $table->string('recover_hash')->nullable();
19 | // Required for Eloquent's created_at and updated_at columns
20 | $table->timestamps();
21 | });
22 | }
23 | public function down() {
24 | $this->schema->drop('users');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/database/migrations/20190527142340_users_permissions.php:
--------------------------------------------------------------------------------
1 | schema->create('users_permissions', function(Illuminate\Database\Schema\Blueprint $table){
9 | // Auto-increment id
10 | $table->unsignedInteger('user_id');
11 | $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
12 | $table->unsignedInteger('permission_id');
13 | $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
14 | // Required for Eloquent's created_at and updated_at columns
15 | $table->timestamps();
16 | });
17 | }
18 | public function down() {
19 | $this->schema->drop('users_permissions');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/database/migrations/20190527142344_users_roles.php:
--------------------------------------------------------------------------------
1 | schema->create('users_roles', function(Illuminate\Database\Schema\Blueprint $table){
9 | // Auto-increment id
10 | $table->increments('id');
11 | $table->unsignedInteger('user_id');
12 | $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
13 | $table->unsignedInteger('role_id');
14 | $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
15 | // Required for Eloquent's created_at and updated_at columns
16 | $table->timestamps();
17 | });
18 | }
19 | public function down() {
20 | $this->schema->drop('users_roles');
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/database/seeds/PermissionSeeder.php:
--------------------------------------------------------------------------------
1 | 'delete users',
20 | 'created_at' => date('Y-m-d H:i:s'),
21 | 'updated_at' => date('Y-m-d H:i:s'),
22 | ],
23 | [
24 | 'name' => 'manage roles',
25 | 'created_at' => date('Y-m-d H:i:s'),
26 | 'updated_at' => date('Y-m-d H:i:s'),
27 | ],
28 | [
29 | 'name' => 'edit users',
30 | 'created_at' => date('Y-m-d H:i:s'),
31 | 'updated_at' => date('Y-m-d H:i:s'),
32 | ],
33 | [
34 | 'name' => 'edit admins',
35 | 'created_at' => date('Y-m-d H:i:s'),
36 | 'updated_at' => date('Y-m-d H:i:s'),
37 | ],
38 | [
39 | 'name' => 'view admin pages',
40 | 'created_at' => date('Y-m-d H:i:s'),
41 | 'updated_at' => date('Y-m-d H:i:s'),
42 | ],
43 | [
44 | 'name' => 'make admin',
45 | 'created_at' => date('Y-m-d H:i:s'),
46 | 'updated_at' => date('Y-m-d H:i:s'),
47 | ]
48 | ];
49 |
50 | $posts = $this->table('permissions');
51 | $posts->insert($data)
52 | ->save();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/database/seeds/RolePermissionSeeder.php:
--------------------------------------------------------------------------------
1 | '1',
28 | 'permission_id' => '1',
29 | 'created_at' => date('Y-m-d H:i:s'),
30 | 'updated_at' => date('Y-m-d H:i:s'),
31 | ],
32 | [
33 | 'role_id' => '1',
34 | 'permission_id' => '3',
35 | 'created_at' => date('Y-m-d H:i:s'),
36 | 'updated_at' => date('Y-m-d H:i:s'),
37 | ],
38 | [
39 | 'role_id' => '1',
40 | 'permission_id' => '5',
41 | 'created_at' => date('Y-m-d H:i:s'),
42 | 'updated_at' => date('Y-m-d H:i:s'),
43 | ],
44 | [
45 | 'role_id' => '2',
46 | 'permission_id' => '1',
47 | 'created_at' => date('Y-m-d H:i:s'),
48 | 'updated_at' => date('Y-m-d H:i:s'),
49 | ],
50 | [
51 | 'role_id' => '2',
52 | 'permission_id' => '2',
53 | 'created_at' => date('Y-m-d H:i:s'),
54 | 'updated_at' => date('Y-m-d H:i:s'),
55 | ],
56 | [
57 | 'role_id' => '2',
58 | 'permission_id' => '3',
59 | 'created_at' => date('Y-m-d H:i:s'),
60 | 'updated_at' => date('Y-m-d H:i:s'),
61 | ],
62 | [
63 | 'role_id' => '2',
64 | 'permission_id' => '4',
65 | 'created_at' => date('Y-m-d H:i:s'),
66 | 'updated_at' => date('Y-m-d H:i:s'),
67 | ],
68 | [
69 | 'role_id' => '2',
70 | 'permission_id' => '5',
71 | 'created_at' => date('Y-m-d H:i:s'),
72 | 'updated_at' => date('Y-m-d H:i:s'),
73 | ],
74 | [
75 | 'role_id' => '2',
76 | 'permission_id' => '6',
77 | 'created_at' => date('Y-m-d H:i:s'),
78 | 'updated_at' => date('Y-m-d H:i:s'),
79 | ]
80 | ];
81 |
82 | $posts = $this->table('roles_permissions');
83 | $posts->insert($data)
84 | ->save();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/database/seeds/RoleSeeder.php:
--------------------------------------------------------------------------------
1 | 'admin',
20 | 'created_at' => date('Y-m-d H:i:s'),
21 | 'updated_at' => date('Y-m-d H:i:s'),
22 | ],
23 | [
24 | 'title' => 'superadmin',
25 | 'created_at' => date('Y-m-d H:i:s'),
26 | 'updated_at' => date('Y-m-d H:i:s'),
27 | ]
28 | ];
29 |
30 | $posts = $this->table('roles');
31 | $posts->insert($data)
32 | ->save();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/forge:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | boot($kernel);
9 |
10 | $console->run();
11 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var elixir = require('laravel-elixir');
2 | require('laravel-elixir-sass-compass');
3 | require('laravel-elixir-webpack-official');
4 |
5 | elixir.config.sourcemaps = false;
6 |
7 | elixir((mix) => {
8 | mix.copy('node_modules/jquery/dist/jquery.min.js','public/js/jquery.min.js');
9 |
10 | mix.sass(['app.scss'], 'public/css/')
11 | .webpack('app.js', 'public/js/app.min.js');
12 | });
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "prod": "gulp --production",
5 | "dev": "gulp watch"
6 | },
7 | "devDependencies": {
8 | "gulp": "^3.9.1",
9 | "jquery": "^3.1.0",
10 | "laravel-elixir": "^6.0.0-10",
11 | "laravel-elixir-sass-compass": "^0.5.0",
12 | "laravel-elixir-webpack-official": "^1.0.4",
13 | "lodash": "^4.16.2",
14 | "normalize.css": "^4.1.1",
15 | "bootstrap": "^4.0.0-alpha.6"
16 | },
17 | "dependencies": {
18 | "font-awesome": "^4.7.0",
19 | "tether": "^1.3.7",
20 | "popper.js": "^1.14.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/phinx:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | run();
29 |
--------------------------------------------------------------------------------
/phinx.php:
--------------------------------------------------------------------------------
1 | [
7 | 'migrations' => 'database/migrations',
8 | 'seeds' => 'database/seeds'
9 | ],
10 | 'templates' => [
11 | 'file' => 'resources/phinx/Migration.template.php.dist'
12 | ],
13 | 'migration_base_class' => '\Migration\Migration',
14 | 'environments' => [
15 | 'default_migration_table' => 'phinxlog',
16 | 'default_database' => 'development',
17 | 'development' => [
18 | 'adapter' => env('DB_CONNECTION'),
19 | 'host' => env('DB_HOST'),
20 | 'name' => env('DB_DATABASE'),
21 | 'user' => env('DB_USERNAME'),
22 | 'pass' => env('DB_PASSWORD'),
23 | 'port' => env('DB_PORT')
24 | ],
25 | 'production' => [
26 | 'adapter' => env('DB_CONNECTION'),
27 | 'host' => env('DB_HOST'),
28 | 'name' => env('DB_DATABASE'),
29 | 'user' => env('DB_USERNAME'),
30 | 'pass' => env('DB_PASSWORD'),
31 | 'port' => env('DB_PORT')
32 | ]
33 | ]
34 | ];
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 | RewriteEngine On
2 | RewriteCond %{REQUEST_FILENAME} !-f
3 | RewriteRule ^ index.php [QSA,L]
4 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 | run();
6 |
--------------------------------------------------------------------------------
/resources/assets/js/app.js:
--------------------------------------------------------------------------------
1 | require('./bootstrap');
--------------------------------------------------------------------------------
/resources/assets/js/bootstrap.js:
--------------------------------------------------------------------------------
1 | window._ = require('lodash');
2 | window.$ = window.jQuery = require('jquery');
3 | window.Tether = require('tether');
4 |
5 | require('bootstrap');
--------------------------------------------------------------------------------
/resources/assets/sass/app.scss:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Lato:300,400,700);
2 | @import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css);
3 |
4 | @import "../../../node_modules/normalize.css/normalize.css";
5 |
6 | // Override bootstrap styling
7 | @import "components/bootstrap/custom";
8 | @import "../../../node_modules/bootstrap/scss/bootstrap.scss";
9 |
10 | @import "../../../node_modules/font-awesome/scss/font-awesome.scss";
11 |
12 | @import "components/base";
--------------------------------------------------------------------------------
/resources/assets/sass/components/_base.scss:
--------------------------------------------------------------------------------
1 | html {
2 | position: relative;
3 | min-height: 100%;
4 | }
5 |
6 | body {
7 | padding-top: 75px;
8 | margin-bottom: 40px;
9 | }
--------------------------------------------------------------------------------
/resources/assets/sass/components/bootstrap/_custom.scss:
--------------------------------------------------------------------------------
1 | $brand-primary: #4285F4 !default;
2 | $brand-success: #34A853 !default;
3 | $brand-info: #00A1F1 !default;
4 | $brand-warning: #FBBC05 !default;
5 | $brand-danger: #EA4335 !default;
6 |
7 | $state-success-bg: $brand-success;
8 | $state-success-text: #FFF;
9 | $state-info-bg: $brand-info;
10 | $state-info-text: #FFF;
11 | $state-warning-bg: $brand-warning;
12 | $state-warning-text: #FFF;
13 | $state-danger-bg: $brand-danger;
14 | $state-danger-text: #FFF;
15 |
16 | .btn {
17 | cursor: pointer !important;
18 | }
--------------------------------------------------------------------------------
/resources/phinx/Migration.template.php.dist:
--------------------------------------------------------------------------------
1 | schema->create('TABLE_NAME_HERE', function(Illuminate\Database\Schema\Blueprint $table){
9 | // Auto-increment id
10 | $table->increments('id');
11 | // Required for Eloquent's created_at and updated_at columns
12 | $table->timestamps();
13 | });
14 | }
15 |
16 | public function down() {
17 | $this->schema->drop('TABLE_NAME_HERE');
18 | }
19 | }
--------------------------------------------------------------------------------
/resources/views/admin/home.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminHome" %}
3 | {% block content %}
4 |
{{ auth.user.username }} , welcome to the Admin Dashboard. Use the navigation bar above to find your way around.
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/resources/views/admin/permission/create.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminPermissionCreate" %}
3 | {% block content %}
4 |
33 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/permission/delete.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% block content %}
3 |
4 |
Are you sure you want to delete {{ permission.name}} permission?
5 | Warning: This will delete all records tied to this permission and cannot be undone!
6 |
7 |
12 |
13 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/permission/edit.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminPermissionEdit" %}
3 | {% block content %}
4 |
38 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/permission/list.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminPermissionList" %}
3 | {% block content %}
4 |
5 |
6 |
14 |
15 | {% if permissions is empty %}
16 |
No results found!
17 | {% else %}
18 |
48 | {{ permissions.links|raw }}
49 | {% endif %}
50 |
51 |
52 |
53 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/role/create.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminRoleCreate" %}
3 | {% block content %}
4 |
46 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/role/delete.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% block content %}
3 |
4 |
Are you sure you want to delete {{ role.title}} role?
5 | Warning: This will delete all records tied to this role and cannot be undone!
6 |
7 |
12 |
13 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/role/edit.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminRoleEdit" %}
3 | {% block content %}
4 |
51 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/role/list.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminRoleList" %}
3 | {% block content %}
4 |
5 |
6 |
14 |
15 | {% if roles is empty %}
16 |
No results found!
17 | {% else %}
18 |
19 |
20 |
21 | ID
22 | Name
23 | Action
24 |
25 |
26 |
27 | {% for role in roles %}
28 |
29 | {{ role.id }}
30 | {{ role.title }}
31 |
32 | {% if auth.user.isSuperAdmin() or auth.user.can('edit role') %}
33 |
34 |
35 | {% else %}
36 |
37 |
38 | {% endif %}
39 |
40 |
41 |
42 | {% endfor %}
43 |
44 |
45 | {{ roles.links|raw }}
46 | {% endif %}
47 |
48 |
49 |
50 | {% endblock %}
51 |
--------------------------------------------------------------------------------
/resources/views/admin/templates/admin.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {% block styles %}{% endblock %}
10 |
11 |
14 |
15 | {{ title is defined ? title : getenv('APP_NAME', 'My App') }}
16 |
17 |
18 | {% include 'templates/partials/nav.twig'%}
19 |
20 |
21 |
22 |
23 | {% include 'templates/partials/alerts.twig'%}
24 |
25 |
26 |
Admin Dashboard
27 |
28 |
29 |
30 | {% include 'admin/templates/partials/_menu.twig' %}
31 |
32 |
33 | {% block content %}{% endblock %}
34 |
35 |
36 |
37 |
38 |
39 |
40 | {% block scripts %}{% endblock %}
41 |
42 |
43 |
--------------------------------------------------------------------------------
/resources/views/admin/templates/partials/_menu.twig:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/resources/views/admin/user/adminlist.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminAdminList" %}
3 | {% block content %}
4 |
5 |
6 |
9 |
10 | {% if users is empty %}
11 |
You don't have any registerd users.
12 | {% else %}
13 |
49 | {{ roles.users|raw }}
50 | {% endif %}
51 |
52 |
53 |
54 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/user/delete.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% block content %}
3 |
4 |
Are you sure you want to delete {{ user.username }} 's account?
5 | Warning: This will delete all records tied to this account and cannot be undone!
6 |
7 |
12 |
13 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/user/edit.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminUserEdit" %}
3 | {% block content %}
4 |
16 |
17 |
85 | {% if auth.user.can('make admin') %}
86 |
89 | {% endif %}
90 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/admin/user/list.twig:
--------------------------------------------------------------------------------
1 | {% extends 'admin/templates/admin.twig' %}
2 | {% set page = "adminUserList" %}
3 | {% block content %}
4 |
5 |
6 |
9 |
10 | {% if users is empty %}
11 |
You don't have any registerd users.
12 | {% else %}
13 |
49 | {{ users.links|raw }}
50 | {% endif %}
51 |
52 |
53 |
54 | {% endblock %}
--------------------------------------------------------------------------------
/resources/views/auth/account/settings.twig:
--------------------------------------------------------------------------------
1 | {% extends 'templates/app.twig' %}
2 |
3 | {% block content %}
4 |
5 |
Settings
6 |
7 |
71 |
72 | {% endblock %}
73 |
--------------------------------------------------------------------------------
/resources/views/auth/login.twig:
--------------------------------------------------------------------------------
1 | {% extends 'templates/app.twig' %}
2 | {% set page = "login" %}
3 | {% block content %}
4 |
56 |
57 | {% endblock %}
58 |
--------------------------------------------------------------------------------
/resources/views/auth/password/forgot.twig:
--------------------------------------------------------------------------------
1 | {% extends 'templates/app.twig' %}
2 |
3 | {% block content %}
4 |
34 | {% endblock %}
35 | {% block scripts %}
36 |
37 | {% endblock %}
38 |
--------------------------------------------------------------------------------
/resources/views/auth/password/reset.twig:
--------------------------------------------------------------------------------
1 | {% extends 'templates/app.twig' %}
2 |
3 | {% block content %}
4 |
47 | {% endblock %}
48 |
--------------------------------------------------------------------------------
/resources/views/auth/register.twig:
--------------------------------------------------------------------------------
1 | {% extends 'templates/app.twig' %}
2 | {% set page = "register" %}
3 | {% block content %}
4 |
64 |
65 | {% endblock %}
66 | {% block scripts %}
67 | {% if getenv('APP_ACTIVATION_METHOD') == 'recaptcha' %}
68 |
69 | {% endif %}
70 | {% endblock %}
71 |
--------------------------------------------------------------------------------
/resources/views/errors/404.twig:
--------------------------------------------------------------------------------
1 | {% extends 'templates/app.twig' %}
2 | {% set title = "Error 404 (Not Found)" %}
3 | {% block content %}
4 |
5 |
404. That's an error.
6 |
7 |
The requested URL {{ request_uri }} was not found on this server.
8 |
9 |
That's all we know.
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/resources/views/errors/405.twig:
--------------------------------------------------------------------------------
1 | {% extends 'templates/app.twig' %}
2 | {% set title = "Error 405 (Method Not Allowed)" %}
3 | {% block content %}
4 |
5 |
405. That's an error.
6 |
7 |
Your requested method ({{ method }} ) is not allowed for {{ request_uri }} .
8 |
9 |
Acceptable Methods: {{ methods }}
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/resources/views/errors/500.twig:
--------------------------------------------------------------------------------
1 | {% extends 'templates/app.twig' %}
2 | {% set title = "Error 500 (Internal Server Error)" %}
3 | {% block content %}
4 |
5 |
500. That's a (bad) error.
6 |
7 |
Sorry, but the server could not handle your request at this time. You can try refreshing or try your request again later.
8 |
9 | {% if exception %}
10 |
Exception: {{ exception }}
11 |
12 | {% endif %}
13 |
Sorry about that.
14 |
15 | {% endblock %}
16 |
--------------------------------------------------------------------------------
/resources/views/home.twig:
--------------------------------------------------------------------------------
1 | {% extends 'templates/app.twig' %}
2 | {% set page = "home" %}
3 | {% block content %}
4 | Welcome home{{ auth.check ? ", " ~ auth.user.username ~ "!" : "." }}
5 | {% if auth.check and auth.user.isAdmin() or auth.user.isSuperAdmin() %}
6 |
7 |
8 |
You are an admin !
9 |
10 | {% endif %}
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/resources/views/mail/auth/activate.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | {{ getenv('APP_NAME') }}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | Hello, {{ data.user.username }}!
37 |
38 |
39 |
40 | Click the button below to activate your account:
41 |
42 |
43 |
58 |
59 |
60 |
61 | Regards, {{ getenv('APP_NAME') }}
62 |
63 |
64 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | © {{ "now"|date("Y") }}
93 | {{ getenv('APP_NAME') }} .
94 | All rights reserved.
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/resources/views/mail/password/forgot.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | {{ getenv('APP_NAME') }}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Hello, {{ data.user.username }}!
36 |
37 |
38 | You are receiving this email because we received a password reset request for your account. Click the button below to reset your password:
39 |
40 |
54 |
55 | If you did not request a password reset, no further action is required.
56 |
57 |
58 |
59 | Regards, {{ getenv('APP_NAME') }}
60 |
61 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | © {{ "now"|date("Y") }}
88 | {{ getenv('APP_NAME') }} .
89 | All rights reserved.
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/resources/views/pagination.twig:
--------------------------------------------------------------------------------
1 | {% if paginator.hasPages() %}
2 |
17 | {% endif %}
--------------------------------------------------------------------------------
/resources/views/templates/app.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {% block styles %}{% endblock %}
10 |
11 |
14 |
15 | {{ title is defined ? title : getenv('APP_NAME', 'My App') }}
16 |
17 |
18 | {% include 'templates/partials/nav.twig'%}
19 |
20 |
21 |
22 |
23 | {% include 'templates/partials/alerts.twig'%}
24 |
25 |
26 | {% block content %}{% endblock %}
27 |
28 |
29 |
30 | {% block scripts %}{% endblock %}
31 |
32 |
33 |
--------------------------------------------------------------------------------
/resources/views/templates/partials/alerts.twig:
--------------------------------------------------------------------------------
1 | {% if flash.getMessage('success').0 %}
2 |
3 |
4 | ×
5 |
6 |
Success!
7 |
8 | {{ flash.getMessage('success').0 }}
9 |
10 |
11 | {% endif %}
12 |
13 | {% if flash.getMessage('info').0 %}
14 |
15 |
16 | ×
17 |
18 |
Heads Up!
19 |
20 | {{ flash.getMessage('info').0 }}
21 |
22 |
23 | {% endif %}
24 |
25 | {% if flash.getMessage('warning').0 %}
26 |
27 |
28 | ×
29 |
30 |
Warning!
31 |
32 | {{ flash.getMessage('warning').0 }}
33 |
34 |
35 | {% endif %}
36 |
37 | {% if flash.getMessage('error').0 %}
38 |
39 |
40 | ×
41 |
42 |
Error!
43 |
44 | {{ flash.getMessage('error').0 }}
45 |
46 |
47 | {% endif %}
48 |
49 | {% if flash.getMessage('raw_error').0 %}
50 |
51 |
52 | ×
53 |
54 |
Error!
55 |
56 | {{ flash.getMessage('raw_error').0|raw }}
57 |
58 |
59 | {% endif %}
60 |
61 | {% if flash.getMessage('raw_warning').0 %}
62 |
63 |
64 | ×
65 |
66 |
Warning!
67 |
68 | {{ flash.getMessage('raw_warning').0|raw }}
69 |
70 |
71 | {% endif %}
72 |
73 | {% if flash.getMessage('raw_success').0 %}
74 |
75 |
76 | ×
77 |
78 |
Success!
79 |
80 | {{ flash.getMessage('raw_success').0|raw }}
81 |
82 |
83 | {% endif %}
--------------------------------------------------------------------------------
/resources/views/templates/partials/nav.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
42 |
--------------------------------------------------------------------------------
/routes/admin.php:
--------------------------------------------------------------------------------
1 | group('/admin', function() {
4 | $this->route(['GET'], '[/]', App\Http\Controllers\Admin\AdminController::class)->setName('admin.home');
5 |
6 | //USERS
7 | $this->route(['GET'], '/users[/]', App\Http\Controllers\Admin\AdminUserController::class)->setName('admin.users.list');
8 | $this->route(['GET'], '/admins[/]', App\Http\Controllers\Admin\AdminUserController::class, 'admins')->setName('admin.admins.list');
9 | $this->route(['GET'], '/users/{userId}/edit[/]', App\Http\Controllers\Admin\AdminUserController::class, 'edit')->setName('admin.users.edit');
10 | $this->route(['GET', 'POST'], '/users/{userId}/delete[/]', App\Http\Controllers\Admin\AdminUserController::class, 'delete')->setName('admin.users.delete');
11 | $this->route(['GET', 'POST'], '/users/{userId}/edit/profile', App\Http\Controllers\Admin\AdminUserController::class, 'editProfile')->setName('admin.users.edit.profile');
12 | $this->route(['GET', 'POST'], '/users/{userId}/edit/settings', App\Http\Controllers\Admin\AdminUserController::class, 'editSettings')->setName('admin.users.edit.settings');
13 | $this->route(['POST'], '/users/{userId}/update/role/{role}/{action}', App\Http\Controllers\Admin\AdminUserController::class, 'updateRole')->setName('admin.users.update.role');
14 |
15 | //ROLES
16 | $this->route(['GET'], '/roles[/]', App\Http\Controllers\Admin\AdminRoleController::class)->setName('admin.roles.list');
17 | $this->route(['GET','POST'], '/roles/{roleId}/edit[/]', App\Http\Controllers\Admin\AdminRoleController::class, 'edit')->setName('admin.roles.edit');
18 | $this->route(['GET','POST'], '/roles/create[/]', App\Http\Controllers\Admin\AdminRoleController::class, 'create')->setName('admin.roles.create');
19 | $this->route(['GET', 'POST'], '/roles/{roleId}/delete[/]', App\Http\Controllers\Admin\AdminRoleController::class, 'delete')->setName('admin.roles.delete');
20 |
21 | //PERMISSIONS
22 | $this->route(['GET'], '/permissions[/]', App\Http\Controllers\Admin\AdminPermissionController::class)->setName('admin.permissions.list');
23 | $this->route(['GET','POST'], '/permissions/{permissionId}/edit[/]', App\Http\Controllers\Admin\AdminPermissionController::class, 'edit')->setName('admin.permissions.edit');
24 | $this->route(['GET','POST'], '/permissions/create[/]', App\Http\Controllers\Admin\AdminPermissionController::class, 'create')->setName('admin.permissions.create');
25 | $this->route(['GET', 'POST'], '/permissions/{permissionId}/delete[/]', App\Http\Controllers\Admin\AdminPermissionController::class, 'delete')->setName('admin.permissions.delete');
26 |
27 | })->add(new App\Http\Middleware\AdminMiddleware($app->getContainer()));
--------------------------------------------------------------------------------
/routes/web.php:
--------------------------------------------------------------------------------
1 | route(['GET'], '/', App\Http\Controllers\HomeController::class)->setName('home');
4 |
5 | $app->group('/auth', function() {
6 | $this->route(['GET', 'POST'], '/login', App\Http\Controllers\Auth\LoginController::class)
7 | ->add(new App\Http\Middleware\GuestMiddleware($this->getContainer()))
8 | ->add(new App\Http\Middleware\RequiresSecureRequestMiddleware($this->getContainer()))
9 | ->setName('auth.login');
10 |
11 | $this->route(['GET', 'POST'], '/register', App\Http\Controllers\Auth\RegisterController::class)
12 | ->add(new App\Http\Middleware\GuestMiddleware($this->getContainer()))
13 | ->add(new App\Http\Middleware\RequiresSecureRequestMiddleware($this->getContainer()))
14 | ->setName('auth.register');
15 |
16 | $this->route(['GET'], '/settings', App\Http\Controllers\Auth\SettingsController::class)
17 | ->add(new App\Http\Middleware\AuthMiddleware($this->getContainer()))
18 | ->add(new App\Http\Middleware\RequiresSecureRequestMiddleware($this->getContainer()))
19 | ->setName('auth.settings');
20 |
21 | $this->route(['GET', 'POST'], '/settings/profile', App\Http\Controllers\Auth\SettingsController::class, 'profile')
22 | ->add(new App\Http\Middleware\AuthMiddleware($this->getContainer()))
23 | ->add(new App\Http\Middleware\RequiresSecureRequestMiddleware($this->getContainer()))
24 | ->setName('auth.settings.profile');
25 |
26 | $this->route(['GET', 'POST'], '/settings/password', App\Http\Controllers\Auth\SettingsController::class, 'password')
27 | ->add(new App\Http\Middleware\AuthMiddleware($this->getContainer()))
28 | ->add(new App\Http\Middleware\RequiresSecureRequestMiddleware($this->getContainer()))
29 | ->setName('auth.settings.password');
30 |
31 | $this->route(['GET'], '/activate', App\Http\Controllers\Auth\ActivationController::class)->setName('auth.activate');
32 |
33 | $this->route(['GET'], '/activate/resend', App\Http\Controllers\Auth\ActivationController::class, 'resend')->setName('auth.activate.resend');
34 |
35 | $this->route(['GET', 'POST'], '/password/forgot', App\Http\Controllers\Auth\PasswordResetController::class, 'forgot')
36 | ->add(new App\Http\Middleware\RequiresSecureRequestMiddleware($this->getContainer()))
37 | ->add(new App\Http\Middleware\GuestMiddleware($this->getContainer()))
38 | ->setName('auth.password.forgot');
39 |
40 | $this->route(['GET', 'POST'], '/password/reset', App\Http\Controllers\Auth\PasswordResetController::class, 'reset')
41 | ->add(new App\Http\Middleware\GuestMiddleware($this->getContainer()))
42 | ->add(new App\Http\Middleware\RequiresSecureRequestMiddleware($this->getContainer()))
43 | ->setName('auth.password.reset');
44 | });
45 |
46 | $app->get('/auth/logout', function($request, $response, $args) {
47 | if(App\Lib\Cookie::exists(env('APP_REMEMBER_ID', 'APP_REMEMBER_TOKEN'))) {
48 | $this['auth']->user()->removeRememberCredentials();
49 | App\Lib\Cookie::destroy(env('APP_REMEMBER_ID', 'APP_REMEMBER_TOKEN'));
50 | }
51 |
52 | App\Lib\Session::destroy(env('APP_AUTH_ID', 'user_id'));
53 |
54 | return $response->withRedirect($this['router']->pathFor('home'));
55 | })->add(new App\Http\Middleware\AuthMiddleware($app->getContainer()))->setName('auth.logout');
56 |
--------------------------------------------------------------------------------