├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── _config.yml ├── back-end ├── .editorconfig ├── .env.example ├── .gitattributes ├── .gitignore ├── Procfile ├── app │ ├── Console │ │ └── Kernel.php │ ├── Core │ │ ├── AccessToken.php │ │ ├── AccessTokenRepository.php │ │ └── FileHelper.php │ ├── Exceptions │ │ └── Handler.php │ ├── Http │ │ ├── Controllers │ │ │ ├── Controller.php │ │ │ └── UserController.php │ │ ├── Kernel.php │ │ └── Middleware │ │ │ ├── Authenticate.php │ │ │ ├── CheckForMaintenanceMode.php │ │ │ ├── EncryptCookies.php │ │ │ ├── LocaleMiddleware.php │ │ │ ├── RedirectIfAuthenticated.php │ │ │ ├── TrimStrings.php │ │ │ ├── TrustProxies.php │ │ │ └── VerifyCsrfToken.php │ ├── Providers │ │ ├── AppServiceProvider.php │ │ ├── AuthServiceProvider.php │ │ ├── BroadcastServiceProvider.php │ │ ├── EventServiceProvider.php │ │ ├── PassportServiceProvider.php │ │ └── RouteServiceProvider.php │ ├── Rules │ │ └── UserExists.php │ └── User.php ├── artisan ├── bootstrap │ ├── app.php │ └── cache │ │ └── .gitignore ├── composer.json ├── composer.lock ├── config │ ├── app.php │ ├── auth.php │ ├── broadcasting.php │ ├── cache.php │ ├── cors.php │ ├── database.php │ ├── filesystems.php │ ├── hashing.php │ ├── logging.php │ ├── mail.php │ ├── queue.php │ ├── security-starter.php │ ├── services.php │ ├── session.php │ ├── simple-passport.php │ └── view.php ├── database │ ├── .gitignore │ ├── factories │ │ └── UserFactory.php │ ├── migrations │ │ ├── 2014_10_12_000000_create_users_table.php │ │ ├── 2014_10_12_100000_create_password_resets_table.php │ │ └── 2019_04_02_075555_add_picture_to_user_table.php │ └── seeds │ │ ├── DatabaseSeeder.php │ │ ├── ProfileRolesSeeder.php │ │ ├── ProfilesSeeder.php │ │ ├── RolesSeeder.php │ │ ├── UserProfilesSeeder.php │ │ └── UsersSeeder.php ├── package.json ├── phpunit.xml ├── public │ ├── .htaccess │ ├── css │ │ └── app.css │ ├── favicon.ico │ ├── index.php │ ├── js │ │ └── app.js │ ├── robots.txt │ └── svg │ │ ├── 403.svg │ │ ├── 404.svg │ │ ├── 500.svg │ │ └── 503.svg ├── resources │ ├── js │ │ ├── app.js │ │ ├── bootstrap.js │ │ └── components │ │ │ └── ExampleComponent.vue │ ├── lang │ │ ├── en │ │ │ ├── auth.php │ │ │ ├── pagination.php │ │ │ ├── passwords.php │ │ │ └── validation.php │ │ ├── fr │ │ │ ├── auth.php │ │ │ ├── pagination.php │ │ │ ├── passwords.php │ │ │ └── validation.php │ │ └── vendor │ │ │ └── simple-passport │ │ │ └── en │ │ │ ├── forgot-password.php │ │ │ └── recover-password.php │ ├── sass │ │ ├── _variables.scss │ │ └── app.scss │ └── views │ │ ├── simple-passport │ │ ├── forgot-password.blade.php │ │ └── recover-password.blade.php │ │ └── welcome.blade.php ├── routes │ ├── api.php │ ├── channels.php │ ├── console.php │ └── web.php ├── server.php ├── storage │ ├── app │ │ ├── .gitignore │ │ └── public │ │ │ └── .gitignore │ ├── framework │ │ ├── .gitignore │ │ ├── cache │ │ │ ├── .gitignore │ │ │ └── data │ │ │ │ └── .gitignore │ │ ├── sessions │ │ │ └── .gitignore │ │ ├── testing │ │ │ └── .gitignore │ │ └── views │ │ │ └── .gitignore │ └── logs │ │ └── .gitignore ├── tests │ ├── CreatesApplication.php │ ├── Feature │ │ └── ExampleTest.php │ ├── TestCase.php │ └── Unit │ │ └── ExampleTest.php ├── webpack.mix.js └── yarn.lock └── front-end ├── .editorconfig ├── .gitignore ├── angular.json ├── e2e ├── src │ ├── app.e2e-spec.ts │ └── app.po.ts └── tsconfig.e2e.json ├── package-lock.json ├── package.json ├── screenshot.jpg ├── src ├── app │ ├── app-routing.module.ts │ ├── app.component.html │ ├── app.component.scss │ ├── app.component.ts │ ├── app.module.ts │ ├── authentication │ │ ├── authentication.module.ts │ │ ├── forgot-password │ │ │ ├── forgot-password.component.html │ │ │ ├── forgot-password.component.scss │ │ │ ├── forgot-password.component.ts │ │ │ ├── forgot-password.module.ts │ │ │ └── i18n │ │ │ │ ├── en.ts │ │ │ │ └── fr.ts │ │ ├── login │ │ │ ├── i18n │ │ │ │ ├── en.ts │ │ │ │ └── fr.ts │ │ │ ├── login.component.html │ │ │ ├── login.component.scss │ │ │ ├── login.component.ts │ │ │ └── login.module.ts │ │ └── recover │ │ │ ├── i18n │ │ │ ├── en.ts │ │ │ └── fr.ts │ │ │ ├── recover.component.html │ │ │ ├── recover.component.scss │ │ │ ├── recover.component.ts │ │ │ └── recover.module.ts │ ├── core │ │ ├── modules │ │ │ └── shared.module.ts │ │ ├── services │ │ │ ├── config.service.ts │ │ │ └── translation-loader.service.ts │ │ └── utils │ │ │ └── toastr.ts │ ├── main │ │ ├── account-settings │ │ │ ├── account-settings.component.html │ │ │ ├── account-settings.component.scss │ │ │ ├── account-settings.component.ts │ │ │ ├── account-settings.module.ts │ │ │ └── i18n │ │ │ │ ├── en.ts │ │ │ │ └── fr.ts │ │ ├── dashboard │ │ │ ├── dashboard.component.html │ │ │ ├── dashboard.component.scss │ │ │ ├── dashboard.component.ts │ │ │ ├── dashboard.module.ts │ │ │ └── i18n │ │ │ │ ├── en.ts │ │ │ │ └── fr.ts │ │ ├── footer │ │ │ ├── footer.component.html │ │ │ ├── footer.component.scss │ │ │ └── footer.component.ts │ │ ├── main.module.ts │ │ ├── navbar │ │ │ ├── i18n │ │ │ │ ├── en.ts │ │ │ │ └── fr.ts │ │ │ ├── navbar.component.html │ │ │ ├── navbar.component.scss │ │ │ └── navbar.component.ts │ │ ├── security │ │ │ ├── profiles │ │ │ │ ├── i18n │ │ │ │ │ ├── en.ts │ │ │ │ │ └── fr.ts │ │ │ │ ├── profiles.component.html │ │ │ │ ├── profiles.component.scss │ │ │ │ ├── profiles.component.ts │ │ │ │ └── profiles.module.ts │ │ │ ├── roles │ │ │ │ ├── i18n │ │ │ │ │ ├── en.ts │ │ │ │ │ └── fr.ts │ │ │ │ ├── roles.component.html │ │ │ │ ├── roles.component.scss │ │ │ │ ├── roles.component.ts │ │ │ │ └── roles.module.ts │ │ │ ├── security.module.ts │ │ │ └── users │ │ │ │ ├── i18n │ │ │ │ ├── en.ts │ │ │ │ └── fr.ts │ │ │ │ ├── users.component.html │ │ │ │ ├── users.component.scss │ │ │ │ ├── users.component.ts │ │ │ │ └── users.module.ts │ │ └── sidebar │ │ │ ├── i18n │ │ │ ├── en.ts │ │ │ └── fr.ts │ │ │ ├── sidebar.component.html │ │ │ ├── sidebar.component.scss │ │ │ └── sidebar.component.ts │ ├── models │ │ ├── common │ │ │ └── partial-list.model.ts │ │ ├── profile.model.ts │ │ ├── role.model.ts │ │ └── user.model.ts │ └── services │ │ ├── common │ │ └── crud.service.ts │ │ ├── profile.service.ts │ │ ├── role.service.ts │ │ ├── security │ │ ├── authentication.service.ts │ │ ├── guards │ │ │ ├── auth.guard.ts │ │ │ ├── interceptor.service.ts │ │ │ ├── no-auth.guard.ts │ │ │ └── role.guard.ts │ │ └── jwt-helper.service.ts │ │ └── user.service.ts ├── assets │ ├── .gitkeep │ ├── fonts │ │ └── PT_Sans │ │ │ ├── OFL.txt │ │ │ ├── PTSans-Bold.eot │ │ │ ├── PTSans-Bold.ttf │ │ │ ├── PTSans-Bold.woff │ │ │ ├── PTSans-Bold.woff2 │ │ │ ├── PTSans-Regular.eot │ │ │ ├── PTSans-Regular.ttf │ │ │ ├── PTSans-Regular.woff │ │ │ └── PTSans-Regular.woff2 │ ├── images │ │ ├── carousel │ │ │ ├── banner_1.jpg │ │ │ ├── banner_10.jpg │ │ │ ├── banner_11.jpg │ │ │ ├── banner_12.jpg │ │ │ ├── banner_2.jpg │ │ │ ├── banner_3.jpg │ │ │ ├── banner_4.jpg │ │ │ ├── banner_5.jpg │ │ │ ├── banner_6.jpg │ │ │ ├── banner_7.jpg │ │ │ ├── banner_8.jpg │ │ │ └── banner_9.jpg │ │ ├── dashboard │ │ │ ├── img_1.jpg │ │ │ ├── img_2.jpg │ │ │ ├── img_3.jpg │ │ │ └── img_4.jpg │ │ ├── faces-clipart │ │ │ ├── pic-1.png │ │ │ ├── pic-2.png │ │ │ ├── pic-3.png │ │ │ └── pic-4.png │ │ ├── faces │ │ │ ├── avatar.png │ │ │ ├── face1.jpg │ │ │ ├── face10.jpg │ │ │ ├── face11.jpg │ │ │ ├── face12.jpg │ │ │ ├── face13.jpg │ │ │ ├── face14.jpg │ │ │ ├── face15.jpg │ │ │ ├── face16.jpg │ │ │ ├── face17.jpg │ │ │ ├── face18.jpg │ │ │ ├── face19.jpg │ │ │ ├── face2.jpg │ │ │ ├── face20.jpg │ │ │ ├── face21.jpg │ │ │ ├── face22.jpg │ │ │ ├── face23.jpg │ │ │ ├── face24.jpg │ │ │ ├── face25.jpg │ │ │ ├── face26.jpg │ │ │ ├── face27.jpg │ │ │ ├── face3.jpg │ │ │ ├── face4.jpg │ │ │ ├── face5.jpg │ │ │ ├── face6.jpg │ │ │ ├── face7.jpg │ │ │ ├── face8.jpg │ │ │ ├── face9.jpg │ │ │ └── profile │ │ │ │ └── profile.jpg │ │ ├── file-icons │ │ │ ├── 64 │ │ │ │ ├── 001-interface-1.png │ │ │ │ ├── 002-tool.png │ │ │ │ ├── 003-interface.png │ │ │ │ ├── 004-folder-1.png │ │ │ │ ├── 005-database.png │ │ │ │ ├── 006-record.png │ │ │ │ ├── 007-folder.png │ │ │ │ └── 008-archive.png │ │ │ ├── 128 │ │ │ │ ├── 001-interface-1.png │ │ │ │ ├── 002-tool.png │ │ │ │ ├── 003-interface.png │ │ │ │ ├── 004-folder-1.png │ │ │ │ ├── 005-database.png │ │ │ │ ├── 006-record.png │ │ │ │ ├── 007-folder.png │ │ │ │ └── 008-archive.png │ │ │ ├── 256 │ │ │ │ ├── 001-interface-1.png │ │ │ │ ├── 002-tool.png │ │ │ │ ├── 003-interface.png │ │ │ │ ├── 004-folder-1.png │ │ │ │ ├── 005-database.png │ │ │ │ ├── 006-record.png │ │ │ │ ├── 007-folder.png │ │ │ │ └── 008-archive.png │ │ │ └── 512 │ │ │ │ ├── 001-interface-1.png │ │ │ │ ├── 002-tool.png │ │ │ │ ├── 003-interface.png │ │ │ │ ├── 004-folder-1.png │ │ │ │ ├── 005-database.png │ │ │ │ ├── 006-record.png │ │ │ │ ├── 007-folder.png │ │ │ │ └── 008-archive.png │ │ ├── flags │ │ │ ├── en.png │ │ │ ├── fr.png │ │ │ └── lang.png │ │ ├── icons │ │ │ ├── forgot-password.png │ │ │ └── login.png │ │ ├── lightbox │ │ │ ├── play-button.png │ │ │ ├── thumb-v-v-1.jpg │ │ │ ├── thumb-v-v-2.jpg │ │ │ ├── thumb-v-y-1.jpg │ │ │ └── thumb-v-y-2.jpg │ │ ├── logos │ │ │ └── logo.png │ │ ├── menu_icons │ │ │ ├── 01.png │ │ │ ├── 02.png │ │ │ ├── 03.png │ │ │ ├── 04.png │ │ │ ├── 05.png │ │ │ ├── 06.png │ │ │ ├── 07.png │ │ │ ├── 08.png │ │ │ ├── 09.png │ │ │ ├── 10.png │ │ │ ├── 11.png │ │ │ ├── 12.png │ │ │ ├── 13.png │ │ │ ├── 14.png │ │ │ ├── 15.png │ │ │ ├── 16.png │ │ │ ├── 17.png │ │ │ ├── 18.png │ │ │ ├── 19.png │ │ │ ├── 20.png │ │ │ ├── 21.png │ │ │ ├── 22.png │ │ │ ├── 23.png │ │ │ ├── 24.png │ │ │ ├── 25.png │ │ │ ├── 26.png │ │ │ ├── 27.png │ │ │ ├── 28.png │ │ │ ├── 29.png │ │ │ ├── 30.png │ │ │ ├── 31.png │ │ │ ├── 32.png │ │ │ ├── 33.png │ │ │ ├── 34.png │ │ │ ├── 35.png │ │ │ ├── 36.png │ │ │ ├── 37.png │ │ │ ├── 38.png │ │ │ ├── 39.png │ │ │ ├── 40.png │ │ │ ├── 41.png │ │ │ ├── 42.png │ │ │ ├── 43.png │ │ │ ├── 44.png │ │ │ └── 45.png │ │ ├── samples │ │ │ ├── 1280x768 │ │ │ │ ├── 1.jpg │ │ │ │ ├── 10.jpg │ │ │ │ ├── 11.jpg │ │ │ │ ├── 12.jpg │ │ │ │ ├── 13.jpg │ │ │ │ ├── 14.jpg │ │ │ │ ├── 15.jpg │ │ │ │ ├── 2.jpg │ │ │ │ ├── 3.jpg │ │ │ │ ├── 4.jpg │ │ │ │ ├── 5.jpg │ │ │ │ ├── 6.jpg │ │ │ │ ├── 7.jpg │ │ │ │ ├── 8.jpg │ │ │ │ └── 9.jpg │ │ │ ├── 300x300 │ │ │ │ ├── 1.jpg │ │ │ │ ├── 10.jpg │ │ │ │ ├── 11.jpg │ │ │ │ ├── 12.jpg │ │ │ │ ├── 13.jpg │ │ │ │ ├── 14.jpg │ │ │ │ ├── 15.jpg │ │ │ │ ├── 2.jpg │ │ │ │ ├── 3.jpg │ │ │ │ ├── 4.jpg │ │ │ │ ├── 5.jpg │ │ │ │ ├── 6.jpg │ │ │ │ ├── 7.jpg │ │ │ │ ├── 8.jpg │ │ │ │ └── 9.jpg │ │ │ ├── Login_bg.jpg │ │ │ ├── Login_bg2.jpg │ │ │ ├── lockscreen-bg.jpg │ │ │ └── weather.svg │ │ └── sprites │ │ │ ├── blue.png │ │ │ ├── dark.png │ │ │ ├── green.png │ │ │ ├── jsgrid-icons.png │ │ │ ├── logo-mini.svg │ │ │ ├── red.png │ │ │ └── yellow.png │ └── styles │ │ ├── _accordions.scss │ │ ├── _badges.scss │ │ ├── _bootstrap-alerts.scss │ │ ├── _bootstrap-progress.scss │ │ ├── _breadcrumbs.scss │ │ ├── _buttons.scss │ │ ├── _cards.scss │ │ ├── _datatables.scss │ │ ├── _demo.scss │ │ ├── _dropdowns.scss │ │ ├── _fonts.scss │ │ ├── _forms.scss │ │ ├── _functions.scss │ │ ├── _icons.scss │ │ ├── _layouts.scss │ │ ├── _lists.scss │ │ ├── _misc.scss │ │ ├── _modals.scss │ │ ├── _nav.scss │ │ ├── _override.scss │ │ ├── _pagination.scss │ │ ├── _popovers.scss │ │ ├── _preview.scss │ │ ├── _rating.scss │ │ ├── _reset.scss │ │ ├── _responsive.scss │ │ ├── _tables.scss │ │ ├── _tabs.scss │ │ ├── _tooltips.scss │ │ ├── _typography.scss │ │ ├── _utilities.scss │ │ ├── _variables.scss │ │ └── mixins │ │ ├── _animation.scss │ │ ├── _background.scss │ │ ├── _badges.scss │ │ ├── _blockqoute.scss │ │ ├── _breadcrumbs.scss │ │ ├── _buttons.scss │ │ ├── _cards.scss │ │ ├── _color-functions.scss │ │ ├── _misc.scss │ │ ├── _pagination.scss │ │ ├── _popovers.scss │ │ └── _tooltips.scss ├── browserslist ├── environments │ ├── constants.ts │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── karma.conf.js ├── main.ts ├── polyfills.ts ├── styles.scss ├── test.ts ├── tsconfig.app.json ├── tsconfig.spec.json └── tslint.json ├── tsconfig.json ├── tslint.json └── yarn.lock /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 EL OUFIR Hatim 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 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /back-end/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.yml] 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /back-end/.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | 9 | DB_CONNECTION=mysql 10 | DB_HOST=127.0.0.1 11 | DB_PORT=3306 12 | DB_DATABASE=homestead 13 | DB_USERNAME=homestead 14 | DB_PASSWORD=secret 15 | 16 | BROADCAST_DRIVER=log 17 | CACHE_DRIVER=file 18 | QUEUE_CONNECTION=sync 19 | SESSION_DRIVER=file 20 | SESSION_LIFETIME=120 21 | 22 | REDIS_HOST=127.0.0.1 23 | REDIS_PASSWORD=null 24 | REDIS_PORT=6379 25 | 26 | MAIL_DRIVER=smtp 27 | MAIL_HOST=smtp.mailtrap.io 28 | MAIL_PORT=2525 29 | MAIL_USERNAME=null 30 | MAIL_PASSWORD=null 31 | MAIL_ENCRYPTION=null 32 | 33 | PUSHER_APP_ID= 34 | PUSHER_APP_KEY= 35 | PUSHER_APP_SECRET= 36 | PUSHER_APP_CLUSTER=mt1 37 | 38 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 39 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 40 | -------------------------------------------------------------------------------- /back-end/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /back-end/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /storage/*.key 5 | /vendor 6 | .env 7 | .phpunit.result.cache 8 | Homestead.json 9 | Homestead.yaml 10 | npm-debug.log 11 | yarn-error.log 12 | /.idea 13 | /storage/uploads/users/* -------------------------------------------------------------------------------- /back-end/Procfile: -------------------------------------------------------------------------------- 1 | "web: vendor/bin/heroku-php-apache2 public/" 2 | -------------------------------------------------------------------------------- /back-end/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire') 28 | // ->hourly(); 29 | } 30 | 31 | /** 32 | * Register the commands for the application. 33 | * 34 | * @return void 35 | */ 36 | protected function commands() 37 | { 38 | $this->load(__DIR__.'/Commands'); 39 | 40 | require base_path('routes/console.php'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /back-end/app/Core/AccessTokenRepository.php: -------------------------------------------------------------------------------- 1 | > Register the custom access token enhancer 11 | * 12 | * @package App\Core 13 | * 14 | * @author EL OUFIR Hatim 15 | */ 16 | class AccessTokenRepository extends PassportAccessTokenRepository 17 | { 18 | 19 | /** 20 | * Get the new customized token 21 | * 22 | * @param ClientEntityInterface $clientEntity The client entity interface 23 | * @param array $scopes The scope array 24 | * @param null $userIdentifier The user identifier (if exists) 25 | * 26 | * @return AccessToken The customized access token 27 | * 28 | * @author EL OUFIR Hatim 29 | */ 30 | public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null) 31 | { 32 | return new AccessToken($userIdentifier, $scopes); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /back-end/app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 18 | return route('login'); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /back-end/app/Http/Middleware/CheckForMaintenanceMode.php: -------------------------------------------------------------------------------- 1 | setLocale($request->hasHeader('Language') ? $request->header('Language') : 'en'); 19 | return $next($request); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /back-end/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | return redirect('/home'); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /back-end/app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 'App\Policies\ModelPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | * 22 | * @return void 23 | */ 24 | public function boot() 25 | { 26 | $this->registerPolicies(); 27 | 28 | // 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /back-end/app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | ]; 22 | 23 | /** 24 | * Register any events for your application. 25 | * 26 | * @return void 27 | */ 28 | public function boot() 29 | { 30 | parent::boot(); 31 | 32 | // 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /back-end/app/Providers/PassportServiceProvider.php: -------------------------------------------------------------------------------- 1 | > Register the custom passport repository 10 | * 11 | * @package App\Providers 12 | * 13 | * @author EL OUFIR Hatim 14 | */ 15 | class PassportServiceProvider extends \Laravel\Passport\PassportServiceProvider 16 | { 17 | 18 | /** 19 | * Initialize the authorization server with the custom passport token enhancer 20 | * 21 | * @return AuthorizationServer The authorization server instance 22 | * 23 | * @author EL OUFIR Hatim 24 | */ 25 | public function makeAuthorizationServer() 26 | { 27 | return new AuthorizationServer( 28 | $this->app->make(\Laravel\Passport\Bridge\ClientRepository::class), 29 | $this->app->make(\App\Core\AccessTokenRepository::class), 30 | $this->app->make(\Laravel\Passport\Bridge\ScopeRepository::class), 31 | $this->makeCryptKey('private'), 32 | app('encrypter')->getKey() 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /back-end/app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | mapApiRoutes(); 39 | 40 | $this->mapWebRoutes(); 41 | 42 | // 43 | } 44 | 45 | /** 46 | * Define the "web" routes for the application. 47 | * 48 | * These routes all receive session state, CSRF protection, etc. 49 | * 50 | * @return void 51 | */ 52 | protected function mapWebRoutes() 53 | { 54 | Route::middleware('web') 55 | ->namespace($this->namespace) 56 | ->group(base_path('routes/web.php')); 57 | } 58 | 59 | /** 60 | * Define the "api" routes for the application. 61 | * 62 | * These routes are typically stateless. 63 | * 64 | * @return void 65 | */ 66 | protected function mapApiRoutes() 67 | { 68 | Route::prefix('api') 69 | ->middleware('api') 70 | ->namespace($this->namespace) 71 | ->group(base_path('routes/api.php')); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /back-end/app/Rules/UserExists.php: -------------------------------------------------------------------------------- 1 | id = $id; 15 | } 16 | 17 | /** 18 | * Determine if the validation rule passes. 19 | * 20 | * @param string $attribute 21 | * @param mixed $value 22 | * @return bool 23 | */ 24 | public function passes($attribute, $value) 25 | { 26 | return User::where('id', $this->id)->count() != 0; 27 | } 28 | 29 | /** 30 | * Get the validation error message. 31 | * 32 | * @return string 33 | */ 34 | public function message() 35 | { 36 | return trans('validation.exists', ['attribute' => 'user']); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /back-end/app/User.php: -------------------------------------------------------------------------------- 1 | 'datetime', 41 | ]; 42 | 43 | /** 44 | * Get the list of user's roles 45 | * 46 | * @return array The user's roles array 47 | * 48 | * @author EL OUFIR Hatim 49 | */ 50 | public function roles(): array 51 | { 52 | $results = collect(); 53 | foreach ($this->profiles as $profile) { 54 | foreach ($profile->roles as $role) { 55 | if (!$results->contains($role->code)) { 56 | $results->push($role->code); 57 | } 58 | } 59 | } 60 | return $results->toArray(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /back-end/artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /back-end/bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /back-end/bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /back-end/config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | 'cluster' => env('PUSHER_APP_CLUSTER'), 40 | 'encrypted' => true, 41 | ], 42 | ], 43 | 44 | 'redis' => [ 45 | 'driver' => 'redis', 46 | 'connection' => 'default', 47 | ], 48 | 49 | 'log' => [ 50 | 'driver' => 'log', 51 | ], 52 | 53 | 'null' => [ 54 | 'driver' => 'null', 55 | ], 56 | 57 | ], 58 | 59 | ]; 60 | -------------------------------------------------------------------------------- /back-end/config/cors.php: -------------------------------------------------------------------------------- 1 | false, 16 | 'allowedOrigins' => ['*'], 17 | 'allowedOriginsPatterns' => [], 18 | 'allowedHeaders' => ['*'], 19 | 'allowedMethods' => ['*'], 20 | 'exposedHeaders' => [], 21 | 'maxAge' => 0, 22 | 23 | ]; 24 | -------------------------------------------------------------------------------- /back-end/config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Bcrypt Options 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may specify the configuration options that should be used when 26 | | passwords are hashed using the Bcrypt algorithm. This will allow you 27 | | to control the amount of time it takes to hash the given password. 28 | | 29 | */ 30 | 31 | 'bcrypt' => [ 32 | 'rounds' => env('BCRYPT_ROUNDS', 10), 33 | ], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Argon Options 38 | |-------------------------------------------------------------------------- 39 | | 40 | | Here you may specify the configuration options that should be used when 41 | | passwords are hashed using the Argon algorithm. These will allow you 42 | | to control the amount of time it takes to hash the given password. 43 | | 44 | */ 45 | 46 | 'argon' => [ 47 | 'memory' => 1024, 48 | 'threads' => 2, 49 | 'time' => 2, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /back-end/config/security-starter.php: -------------------------------------------------------------------------------- 1 | > You can change these values before starting the migration command. 14 | | 15 | */ 16 | 'tables' => [ 17 | 'profiles' => 'profiles', 18 | 'roles' => 'roles', 19 | 'associations' => [ 20 | 'profile_roles' => 'profile_roles', 21 | 'user_profiles' => 'user_profiles' 22 | ] 23 | ], 24 | 25 | /* 26 | |-------------------------------------------------------------------------- 27 | | Privileges 28 | |-------------------------------------------------------------------------- 29 | | 30 | | This value represents the roles that the use must have to access 31 | | respectively the profiles and roles REST resources 32 | | >> Please refer to [https://github.com/heloufir/security-starter] to have 33 | | an idea on how to use this package 34 | | 35 | */ 36 | 'privileges' => [ 37 | 'profiles' => 'any,ROLE_PROFILES', 38 | 'roles' => 'any,ROLE_ROLES' 39 | ] 40 | 41 | ]; -------------------------------------------------------------------------------- /back-end/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | ], 22 | 23 | 'ses' => [ 24 | 'key' => env('SES_KEY'), 25 | 'secret' => env('SES_SECRET'), 26 | 'region' => env('SES_REGION', 'us-east-1'), 27 | ], 28 | 29 | 'sparkpost' => [ 30 | 'secret' => env('SPARKPOST_SECRET'), 31 | ], 32 | 33 | 'stripe' => [ 34 | 'model' => App\User::class, 35 | 'key' => env('STRIPE_KEY'), 36 | 'secret' => env('STRIPE_SECRET'), 37 | 'webhook' => [ 38 | 'secret' => env('STRIPE_WEBHOOK_SECRET'), 39 | 'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300), 40 | ], 41 | ], 42 | 43 | ]; 44 | -------------------------------------------------------------------------------- /back-end/config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /back-end/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /back-end/database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | define(App\User::class, function (Faker $faker) { 18 | return [ 19 | 'name' => $faker->name, 20 | 'email' => $faker->unique()->safeEmail, 21 | 'email_verified_at' => now(), 22 | 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret 23 | 'remember_token' => Str::random(10), 24 | ]; 25 | }); 26 | -------------------------------------------------------------------------------- /back-end/database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->timestamp('email_verified_at')->nullable(); 21 | $table->string('password'); 22 | $table->rememberToken(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('users'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /back-end/database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /back-end/database/migrations/2019_04_02_075555_add_picture_to_user_table.php: -------------------------------------------------------------------------------- 1 | string('picture', 255)->nullable(true); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('users', function (Blueprint $table) { 29 | $table->dropColumn('picture'); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /back-end/database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(RolesSeeder::class); 16 | 17 | // Execute profiles seeder 18 | $this->call(ProfilesSeeder::class); 19 | 20 | // Execute profile roles seeder 21 | $this->call(ProfileRolesSeeder::class); 22 | 23 | // Execute users seeder 24 | $this->call(UsersSeeder::class); 25 | 26 | // Execute user profiles seeder 27 | $this->call(UserProfilesSeeder::class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /back-end/database/seeds/ProfileRolesSeeder.php: -------------------------------------------------------------------------------- 1 | where('code', 'ROLE_ROLES') 17 | ->first() 18 | ->id; 19 | $roleProfiles = DB::table(config('security-starter.tables.roles')) 20 | ->where('code', 'ROLE_PROFILES') 21 | ->first() 22 | ->id; 23 | $roleUsers = DB::table(config('security-starter.tables.roles')) 24 | ->where('code', 'ROLE_USERS') 25 | ->first() 26 | ->id; 27 | $profile = DB::table(config('security-starter.tables.profiles')) 28 | ->where('code', 'PROFILE_ADMIN') 29 | ->first() 30 | ->id; 31 | DB::table(config('security-starter.tables.associations.profile_roles')) 32 | ->insert([ 33 | [ 34 | 'refRole' => $roleRoles, 35 | 'refProfile' => $profile 36 | ], [ 37 | 'refRole' => $roleProfiles, 38 | 'refProfile' => $profile 39 | ], [ 40 | 'refRole' => $roleUsers, 41 | 'refProfile' => $profile 42 | ] 43 | ]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /back-end/database/seeds/ProfilesSeeder.php: -------------------------------------------------------------------------------- 1 | insert([ 18 | 'code' => 'PROFILE_ADMIN', 19 | 'designation' => 'Administrator privileges', 20 | 'created_at' => Carbon::now(), 21 | 'updated_at' => Carbon::now() 22 | ]); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /back-end/database/seeds/RolesSeeder.php: -------------------------------------------------------------------------------- 1 | insert([ 18 | [ 19 | 'code' => 'ROLE_ROLES', 20 | 'designation' => 'Roles management access', 21 | 'created_at' => Carbon::now(), 22 | 'updated_at' => Carbon::now() 23 | ], [ 24 | 'code' => 'ROLE_PROFILES', 25 | 'designation' => 'Profiles management access', 26 | 'created_at' => Carbon::now(), 27 | 'updated_at' => Carbon::now() 28 | ], [ 29 | 'code' => 'ROLE_USERS', 30 | 'designation' => 'Users management access', 31 | 'created_at' => Carbon::now(), 32 | 'updated_at' => Carbon::now() 33 | ] 34 | ]); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /back-end/database/seeds/UserProfilesSeeder.php: -------------------------------------------------------------------------------- 1 | table ?: 'users') 16 | ->where('email', 'john.doe@gmail.com') 17 | ->first() 18 | ->id; 19 | $profile = DB::table(config('security-starter.tables.profiles')) 20 | ->where('code', 'PROFILE_ADMIN') 21 | ->first() 22 | ->id; 23 | DB::table(config('security-starter.tables.associations.user_profiles')) 24 | ->insert([ 25 | 'refUser' => $user, 26 | 'refProfile' => $profile 27 | ]); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /back-end/database/seeds/UsersSeeder.php: -------------------------------------------------------------------------------- 1 | table ?: 'users') 17 | ->insert([ 18 | 'email' => 'john.doe@gmail.com', 19 | 'name' => 'John DOE', 20 | 'password' => bcrypt('secret'), 21 | 'created_at' => Carbon::now(), 22 | 'updated_at' => Carbon::now() 23 | ]); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /back-end/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "npm run development -- --watch", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "axios": "^0.18", 14 | "bootstrap": "^4.0.0", 15 | "cross-env": "^5.1", 16 | "jquery": "^3.2", 17 | "laravel-mix": "^4.0.7", 18 | "lodash": "^4.17.5", 19 | "popper.js": "^1.12", 20 | "resolve-url-loader": "^2.3.1", 21 | "sass": "^1.15.2", 22 | "sass-loader": "^7.1.0", 23 | "vue": "^2.5.17" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /back-end/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/Unit 14 | 15 | 16 | 17 | ./tests/Feature 18 | 19 | 20 | 21 | 22 | ./app 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /back-end/public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /back-end/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/back-end/public/favicon.ico -------------------------------------------------------------------------------- /back-end/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /back-end/resources/js/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * First we will load all of this project's JavaScript dependencies which 4 | * includes Vue and other libraries. It is a great starting point when 5 | * building robust, powerful web applications using Vue and Laravel. 6 | */ 7 | 8 | require('./bootstrap'); 9 | 10 | window.Vue = require('vue'); 11 | 12 | /** 13 | * The following block of code may be used to automatically register your 14 | * Vue components. It will recursively scan this directory for the Vue 15 | * components and automatically register them with their "basename". 16 | * 17 | * Eg. ./components/ExampleComponent.vue -> 18 | */ 19 | 20 | // const files = require.context('./', true, /\.vue$/i) 21 | // files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default)) 22 | 23 | Vue.component('example-component', require('./components/ExampleComponent.vue').default); 24 | 25 | /** 26 | * Next, we will create a fresh Vue application instance and attach it to 27 | * the page. Then, you may begin adding components to this application 28 | * or customize the JavaScript scaffolding to fit your unique needs. 29 | */ 30 | 31 | const app = new Vue({ 32 | el: '#app' 33 | }); 34 | -------------------------------------------------------------------------------- /back-end/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | 2 | window._ = require('lodash'); 3 | 4 | /** 5 | * We'll load jQuery and the Bootstrap jQuery plugin which provides support 6 | * for JavaScript based Bootstrap features such as modals and tabs. This 7 | * code may be modified to fit the specific needs of your application. 8 | */ 9 | 10 | try { 11 | window.Popper = require('popper.js').default; 12 | window.$ = window.jQuery = require('jquery'); 13 | 14 | require('bootstrap'); 15 | } catch (e) {} 16 | 17 | /** 18 | * We'll load the axios HTTP library which allows us to easily issue requests 19 | * to our Laravel back-end. This library automatically handles sending the 20 | * CSRF token as a header based on the value of the "XSRF" token cookie. 21 | */ 22 | 23 | window.axios = require('axios'); 24 | 25 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 26 | 27 | /** 28 | * Next we will register the CSRF Token as a common header with Axios so that 29 | * all outgoing HTTP requests automatically have it attached. This is just 30 | * a simple convenience so we don't have to attach every token manually. 31 | */ 32 | 33 | let token = document.head.querySelector('meta[name="csrf-token"]'); 34 | 35 | if (token) { 36 | window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content; 37 | } else { 38 | console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token'); 39 | } 40 | 41 | /** 42 | * Echo exposes an expressive API for subscribing to channels and listening 43 | * for events that are broadcast by Laravel. Echo and event broadcasting 44 | * allows your team to easily build robust real-time web applications. 45 | */ 46 | 47 | // import Echo from 'laravel-echo' 48 | 49 | // window.Pusher = require('pusher-js'); 50 | 51 | // window.Echo = new Echo({ 52 | // broadcaster: 'pusher', 53 | // key: process.env.MIX_PUSHER_APP_KEY, 54 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER, 55 | // encrypted: true 56 | // }); 57 | -------------------------------------------------------------------------------- /back-end/resources/js/components/ExampleComponent.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | -------------------------------------------------------------------------------- /back-end/resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /back-end/resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /back-end/resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Passwords must be at least six characters and match the confirmation.', 17 | 'reset' => 'Your password has been reset!', 18 | 'sent' => 'We have e-mailed your password reset link!', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that e-mail address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /back-end/resources/lang/fr/auth.php: -------------------------------------------------------------------------------- 1 | 'Ces identifiants ne correspondent pas à nos enregistrements', 14 | 'throttle' => 'Tentatives de connexion trop nombreuses. Veuillez essayer de nouveau dans :seconds secondes.', 15 | ]; -------------------------------------------------------------------------------- /back-end/resources/lang/fr/pagination.php: -------------------------------------------------------------------------------- 1 | '« Précédent', 14 | 'next' => 'Suivant »', 15 | ]; -------------------------------------------------------------------------------- /back-end/resources/lang/fr/passwords.php: -------------------------------------------------------------------------------- 1 | 'Les mots de passe doivent contenir au moins six caractères et être identiques.', 14 | 'reset' => 'Votre mot de passe a été réinitialisé !', 15 | 'sent' => 'Nous vous avons envoyé par email le lien de réinitialisation du mot de passe !', 16 | 'token' => "Ce jeton de réinitialisation du mot de passe n'est pas valide.", 17 | 'user' => "Aucun utilisateur n'a été trouvé avec cette adresse email.", 18 | ]; -------------------------------------------------------------------------------- /back-end/resources/lang/vendor/simple-passport/en/forgot-password.php: -------------------------------------------------------------------------------- 1 | 'Forgot your password?', 5 | 'title' => 'Forgot your password?', 6 | 'notification_description' => 'Forgot your password? No worries, take a moment and follow the steps described in this email to recover your password.', 7 | 'description' => 'No worries! Take a moment and follow the steps described in this email to recover your password' 8 | . '
First of all click on the following button:', 9 | 'button' => 'Recover your password' 10 | ]; -------------------------------------------------------------------------------- /back-end/resources/lang/vendor/simple-passport/en/recover-password.php: -------------------------------------------------------------------------------- 1 | 'Password recovered', 5 | 'title' => 'Password recovered', 6 | 'notification_description' => 'Congrats! Your password was successfully recovered. You can now log on using your new password.', 7 | 'description' => 'Congrats! Your password was successfully recovered. You can now log on using your new password.' 8 | ]; -------------------------------------------------------------------------------- /back-end/resources/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | 2 | // Body 3 | $body-bg: #f8fafc; 4 | 5 | // Typography 6 | $font-family-sans-serif: "Nunito", sans-serif; 7 | $font-size-base: 0.9rem; 8 | $line-height-base: 1.6; 9 | 10 | // Colors 11 | $blue: #3490dc; 12 | $indigo: #6574cd; 13 | $purple: #9561e2; 14 | $pink: #f66D9b; 15 | $red: #e3342f; 16 | $orange: #f6993f; 17 | $yellow: #ffed4a; 18 | $green: #38c172; 19 | $teal: #4dc0b5; 20 | $cyan: #6cb2eb; 21 | -------------------------------------------------------------------------------- /back-end/resources/sass/app.scss: -------------------------------------------------------------------------------- 1 | 2 | // Fonts 3 | @import url('https://fonts.googleapis.com/css?family=Nunito'); 4 | 5 | // Variables 6 | @import 'variables'; 7 | 8 | // Bootstrap 9 | @import '~bootstrap/scss/bootstrap'; 10 | 11 | .navbar-laravel { 12 | background-color: #fff; 13 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04); 14 | } 15 | -------------------------------------------------------------------------------- /back-end/routes/api.php: -------------------------------------------------------------------------------- 1 | except(['create', 'edit', 'update']) 5 | ->middleware(['auth:api', 'roles:ROLE_USERS']); 6 | 7 | // IMPORTANT: The update() function is override here because the HTTP PUT request does not 8 | // accept formData object from the HTTP request (only POST does) 9 | Route::post('users/{user}', 'UserController@update') 10 | ->middleware(['auth:api', 'roles:ROLE_USERS']); 11 | -------------------------------------------------------------------------------- /back-end/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 16 | }); 17 | -------------------------------------------------------------------------------- /back-end/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 18 | })->describe('Display an inspiring quote'); 19 | -------------------------------------------------------------------------------- /back-end/routes/web.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /back-end/storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /back-end/storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /back-end/storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /back-end/storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /back-end/storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /back-end/storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /back-end/storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /back-end/storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /back-end/storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /back-end/tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /back-end/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /back-end/tests/TestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /back-end/webpack.mix.js: -------------------------------------------------------------------------------- 1 | const mix = require('laravel-mix'); 2 | 3 | /* 4 | |-------------------------------------------------------------------------- 5 | | Mix Asset Management 6 | |-------------------------------------------------------------------------- 7 | | 8 | | Mix provides a clean, fluent API for defining some Webpack build steps 9 | | for your Laravel application. By default, we are compiling the Sass 10 | | file for the application as well as bundling up all the JS files. 11 | | 12 | */ 13 | 14 | mix.js('resources/js/app.js', 'public/js') 15 | .sass('resources/sass/app.scss', 'public/css'); 16 | -------------------------------------------------------------------------------- /front-end/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /front-end/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist-server 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # e2e 38 | /e2e/*.js 39 | /e2e/*.map 40 | 41 | # System Files 42 | .DS_Store 43 | Thumbs.db 44 | -------------------------------------------------------------------------------- /front-end/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('workspace-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to star-admin-angular!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /front-end/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /front-end/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /front-end/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/screenshot.jpg -------------------------------------------------------------------------------- /front-end/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | /** 6 | * Main application routes 7 | * 8 | * @author EL OUFIR Hatim 9 | */ 10 | const routes: Routes = [ 11 | // Authentication module 12 | { 13 | path: 'auth', 14 | loadChildren: './authentication/authentication.module#AuthenticationModule' 15 | }, 16 | // Main module 17 | { 18 | path: '', 19 | loadChildren: './main/main.module#MainModule', 20 | data: { preload: true } 21 | } 22 | ]; 23 | 24 | @NgModule({ 25 | imports: [ 26 | // Application routes injection into the application forRoot() routes 27 | RouterModule.forRoot(routes) 28 | ], 29 | exports: [ 30 | // Angular router module 31 | RouterModule 32 | ] 33 | }) 34 | export class AppRoutingModule { } 35 | -------------------------------------------------------------------------------- /front-end/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 | 38 | 39 |
40 | 41 | 42 |
43 | -------------------------------------------------------------------------------- /front-end/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | @import '../styles'; 2 | :host { 3 | padding: 0; 4 | margin: 0; 5 | overflow-x: hidden; 6 | font-size: 1rem; 7 | font-family: $type-1; 8 | } 9 | 10 | .container-fluid { 11 | &.full-screen { 12 | padding-top: 0; 13 | height: 100vh; 14 | } 15 | } 16 | 17 | .main-panel { 18 | &.full-screen { 19 | width: 100%; 20 | } 21 | } 22 | 23 | .content-wrapper { 24 | position: relative; 25 | &>mat-progress-bar { 26 | position: absolute; 27 | top: 0; 28 | left: 0; 29 | right: 0; 30 | } 31 | } -------------------------------------------------------------------------------- /front-end/src/app/authentication/authentication.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | 6 | // Authentication module routes 7 | const routes: Routes = [ 8 | { 9 | path: 'login', 10 | loadChildren: './login/login.module#LoginModule' 11 | }, 12 | { 13 | path: 'forgot-password', 14 | loadChildren: './forgot-password/forgot-password.module#ForgotPasswordModule' 15 | }, 16 | { 17 | path: 'recover/:token', 18 | loadChildren: './recover/recover.module#RecoverModule' 19 | } 20 | ]; 21 | 22 | @NgModule({ 23 | declarations: [], 24 | imports: [ 25 | // Angular modules 26 | CommonModule, 27 | // Application routes injection into the application forChild() routes 28 | RouterModule.forChild(routes) 29 | ] 30 | }) 31 | export class AuthenticationModule { } 32 | -------------------------------------------------------------------------------- /front-end/src/app/authentication/forgot-password/forgot-password.component.scss: -------------------------------------------------------------------------------- 1 | #forgot-password { 2 | .input-group { 3 | .input-group-prepend { 4 | .input-group-text { 5 | i { 6 | font-size: 25px; 7 | } 8 | } 9 | } 10 | input { 11 | font-size: 15px; 12 | height: 60px; 13 | line-height: 60px; 14 | } 15 | } 16 | .forgot-password-btn { 17 | img { 18 | width: 48px; 19 | } 20 | } 21 | mat-spinner { 22 | position: absolute; 23 | left: calc(50% - 38px); 24 | top: calc(100% - 70px); 25 | } 26 | } -------------------------------------------------------------------------------- /front-end/src/app/authentication/forgot-password/forgot-password.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | import { ReactiveFormsModule, FormsModule } from '@angular/forms'; 6 | 7 | // Forgot password component 8 | import { ForgotPasswordComponent } from './forgot-password.component'; 9 | 10 | // Material modules 11 | import { MatProgressSpinnerModule } from '@angular/material'; 12 | 13 | // Routes guards 14 | import { NoAuthGuard } from '@services/security/guards/no-auth.guard'; 15 | 16 | // Shared module 17 | import { SharedModule } from '@app/core/modules/shared.module'; 18 | 19 | // Module routes 20 | const routes: Routes = [ 21 | { 22 | path: '', 23 | component: ForgotPasswordComponent, 24 | canActivate: [ NoAuthGuard ] 25 | } 26 | ]; 27 | 28 | @NgModule({ 29 | declarations: [ 30 | // Forgot password component 31 | ForgotPasswordComponent 32 | ], 33 | imports: [ 34 | // Angular modules 35 | CommonModule, 36 | // Forms modules 37 | FormsModule, 38 | ReactiveFormsModule, 39 | // Application routes injection into the application forChild() routes 40 | RouterModule.forChild(routes), 41 | // Material modules 42 | MatProgressSpinnerModule, 43 | // Shared module 44 | SharedModule 45 | ] 46 | }) 47 | export class ForgotPasswordModule { } 48 | -------------------------------------------------------------------------------- /front-end/src/app/authentication/forgot-password/i18n/en.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'en', 5 | data: { 6 | 'FORGOT_PASSWORD': { 7 | 'TITLE': 'Forgot password? Don\'t worry!', 8 | 'FIELDS': { 9 | 'EMAIL': 'Email address' 10 | }, 11 | 'ERRORS': { 12 | 'EMAIL': { 13 | 'REQUIRED': 'The email address is required', 14 | 'VALID': 'Please enter a valid email address' 15 | } 16 | }, 17 | 'LINKS': { 18 | 'LOGIN': 'Login to your account' 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /front-end/src/app/authentication/forgot-password/i18n/fr.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'fr', 5 | data: { 6 | 'FORGOT_PASSWORD': { 7 | 'TITLE': 'Mot de passe oublié? Ne vous inquiètez pas!', 8 | 'FIELDS': { 9 | 'EMAIL': 'Adresse email' 10 | }, 11 | 'ERRORS': { 12 | 'EMAIL': { 13 | 'REQUIRED': 'L\'adresse email est obligatiore', 14 | 'VALID': 'Veuillez entrer une adresse email valide' 15 | } 16 | }, 17 | 'LINKS': { 18 | 'LOGIN': 'Connectez-vous à votre compte' 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /front-end/src/app/authentication/login/i18n/en.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'en', 5 | data: { 6 | 'LOGIN': { 7 | 'TITLE': 'Login to your account', 8 | 'FIELDS': { 9 | 'EMAIL': 'Email address', 10 | 'PASSWORD': 'Password' 11 | }, 12 | 'ERRORS': { 13 | 'EMAIL': { 14 | 'REQUIRED': 'The email address is required', 15 | 'VALID': 'Please enter a valid email address' 16 | }, 17 | 'PASSWORD': { 18 | 'REQUIRED': 'The password is required' 19 | } 20 | }, 21 | 'LINKS': { 22 | 'FORGOT_PASSWORD': 'Forgot your password?' 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /front-end/src/app/authentication/login/i18n/fr.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'fr', 5 | data: { 6 | 'LOGIN': { 7 | 'TITLE': 'Connectez-vous à votre compte', 8 | 'FIELDS': { 9 | 'EMAIL': 'Adresse email', 10 | 'PASSWORD': 'Mot de passe' 11 | }, 12 | 'ERRORS': { 13 | 'EMAIL': { 14 | 'REQUIRED': 'L\'adresse email est obligatiore', 15 | 'VALID': 'Veuillez entrer une adresse email valide' 16 | }, 17 | 'PASSWORD': { 18 | 'REQUIRED': 'Le mot de passe est obligatoire' 19 | } 20 | }, 21 | 'LINKS': { 22 | 'FORGOT_PASSWORD': 'Mot de passe oublié ?' 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /front-end/src/app/authentication/login/login.component.scss: -------------------------------------------------------------------------------- 1 | #login { 2 | .input-group { 3 | .input-group-prepend { 4 | .input-group-text { 5 | i { 6 | font-size: 25px; 7 | } 8 | } 9 | } 10 | input { 11 | font-size: 15px; 12 | height: 60px; 13 | line-height: 60px; 14 | } 15 | } 16 | .login-btn { 17 | img { 18 | width: 48px; 19 | } 20 | } 21 | mat-spinner { 22 | position: absolute; 23 | left: calc(50% - 38px); 24 | top: calc(100% - 70px); 25 | } 26 | } -------------------------------------------------------------------------------- /front-end/src/app/authentication/login/login.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | import { ReactiveFormsModule, FormsModule } from '@angular/forms'; 6 | 7 | // Module components 8 | import { LoginComponent } from './login.component'; 9 | 10 | // Material modules 11 | import { MatProgressSpinnerModule } from '@angular/material'; 12 | 13 | // Routes guards 14 | import { NoAuthGuard } from '@services/security/guards/no-auth.guard'; 15 | 16 | // Shared module 17 | import { SharedModule } from '@app/core/modules/shared.module'; 18 | 19 | // Module routes 20 | const routes: Routes = [ 21 | { 22 | path: '', 23 | component: LoginComponent, 24 | canActivate: [ NoAuthGuard ] 25 | } 26 | ]; 27 | 28 | @NgModule({ 29 | declarations: [ 30 | // Module components 31 | LoginComponent 32 | ], 33 | imports: [ 34 | // Angular modules 35 | CommonModule, 36 | // Forms modules 37 | FormsModule, 38 | ReactiveFormsModule, 39 | // Application routes injection into the application forChild() routes 40 | RouterModule.forChild(routes), 41 | // Material modules 42 | MatProgressSpinnerModule, 43 | // Shared module 44 | SharedModule 45 | ] 46 | }) 47 | export class LoginModule { } 48 | -------------------------------------------------------------------------------- /front-end/src/app/authentication/recover/i18n/en.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'en', 5 | data: { 6 | 'RECOVER': { 7 | 'TITLE': 'Recover your password', 8 | 'FIELDS': { 9 | 'EMAIL': 'Email address', 10 | 'PASSWORD': 'New password', 11 | 'PASSWORD_CONFIRMATION': 'Password confirmation' 12 | }, 13 | 'ERRORS': { 14 | 'EMAIL': { 15 | 'REQUIRED': 'The email address is required', 16 | 'VALID': 'Please enter a valid email address' 17 | }, 18 | 'PASSWORD': { 19 | 'REQUIRED': 'The password is required' 20 | }, 21 | 'PASSWORD_CONFIRMATION': { 22 | 'REQUIRED': 'The password confirmation is required', 23 | } 24 | }, 25 | 'LINKS': { 26 | 'LOGIN': 'Login to your account' 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /front-end/src/app/authentication/recover/i18n/fr.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'fr', 5 | data: { 6 | 'RECOVER': { 7 | 'TITLE': 'Récupère ton mot de passe', 8 | 'FIELDS': { 9 | 'EMAIL': 'Adresse email', 10 | 'PASSWORD': 'Nouveau mot de passe', 11 | 'PASSWORD_CONFIRMATION': 'Confirmation du mot de passe' 12 | }, 13 | 'ERRORS': { 14 | 'EMAIL': { 15 | 'REQUIRED': 'L\'adresse email est obligatiore', 16 | 'VALID': 'Veuillez entrer une adresse email valide' 17 | }, 18 | 'PASSWORD': { 19 | 'REQUIRED': 'Le mot de passe est obligatoire' 20 | }, 21 | 'PASSWORD_CONFIRMATION': { 22 | 'REQUIRED': 'La confirmation du mot de passe est obligatiore' 23 | } 24 | }, 25 | 'LINKS': { 26 | 'FORGOT_PASSWORD': 'Connectez-vous à votre compte' 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /front-end/src/app/authentication/recover/recover.component.scss: -------------------------------------------------------------------------------- 1 | #recover-password { 2 | .input-group { 3 | .input-group-prepend { 4 | .input-group-text { 5 | i { 6 | font-size: 25px; 7 | } 8 | } 9 | } 10 | input { 11 | font-size: 15px; 12 | height: 60px; 13 | line-height: 60px; 14 | } 15 | } 16 | .recover-password-btn { 17 | img { 18 | width: 48px; 19 | } 20 | } 21 | mat-spinner { 22 | position: absolute; 23 | left: calc(50% - 38px); 24 | top: calc(100% - 70px); 25 | } 26 | } -------------------------------------------------------------------------------- /front-end/src/app/authentication/recover/recover.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | import { ReactiveFormsModule, FormsModule } from '@angular/forms'; 6 | 7 | // Recover component 8 | import { RecoverComponent } from './recover.component'; 9 | 10 | // Material modules 11 | import { MatProgressSpinnerModule } from '@angular/material'; 12 | 13 | // Routes guards 14 | import { NoAuthGuard } from '@services/security/guards/no-auth.guard'; 15 | 16 | // Shared module 17 | import { SharedModule } from '@app/core/modules/shared.module'; 18 | 19 | // Module routes 20 | const routes: Routes = [ 21 | { 22 | path: '', 23 | component: RecoverComponent, 24 | canActivate: [ NoAuthGuard ] 25 | } 26 | ]; 27 | 28 | @NgModule({ 29 | declarations: [ 30 | // Recover component 31 | RecoverComponent 32 | ], 33 | imports: [ 34 | // Angular modules 35 | CommonModule, 36 | // Forms modules 37 | FormsModule, 38 | ReactiveFormsModule, 39 | // Application routes injection into the application forChild() routes 40 | RouterModule.forChild(routes), 41 | // Material modules 42 | MatProgressSpinnerModule, 43 | // Shared module 44 | SharedModule 45 | ] 46 | }) 47 | export class RecoverModule { } 48 | -------------------------------------------------------------------------------- /front-end/src/app/core/modules/shared.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | 5 | // Translate module 6 | import { TranslateModule } from '@ngx-translate/core'; 7 | 8 | @NgModule({ 9 | declarations: [], 10 | imports: [ 11 | // Angular modules 12 | CommonModule, 13 | // Translate module 14 | TranslateModule 15 | ], 16 | exports : [ 17 | // Translate module 18 | TranslateModule 19 | ] 20 | }) 21 | export class SharedModule { } 22 | -------------------------------------------------------------------------------- /front-end/src/app/core/services/config.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 3 | import { Platform } from '@angular/cdk/platform'; 4 | 5 | export interface ConfigObject { 6 | navbar: boolean; 7 | sidebar: boolean; 8 | footer: boolean; 9 | } 10 | 11 | @Injectable({ 12 | providedIn: 'root' 13 | }) 14 | export class ConfigService { 15 | 16 | settings: ConfigObject; 17 | onSettingsChanged: BehaviorSubject; 18 | 19 | /** 20 | * Config service constructor 21 | * 22 | * @param platform 23 | * The angular/cdk platform object 24 | * 25 | * @author EL OUFIR Hatim 26 | */ 27 | constructor( 28 | public platform: Platform 29 | ) { 30 | // Set the settings 31 | this.settings = this.defaultSettings(); 32 | 33 | // Create the behavior subject 34 | this.onSettingsChanged = new BehaviorSubject(this.settings); 35 | } 36 | 37 | /** 38 | * Sets settings 39 | * 40 | * @param settings 41 | * The configuration object 42 | * 43 | * @author EL OUFIR Hatim 44 | */ 45 | setSettings(settings: ConfigObject) { 46 | // Set the settings from the given object 47 | this.settings = Object.assign({}, this.settings, settings); 48 | 49 | // Trigger the event 50 | this.onSettingsChanged.next(this.settings); 51 | } 52 | 53 | /** 54 | * Get default settings 55 | * 56 | * @author EL OUFIR Hatim 57 | */ 58 | defaultSettings(): ConfigObject { 59 | return { 60 | navbar: true, 61 | sidebar: true, 62 | footer: true 63 | }; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /front-end/src/app/core/services/translation-loader.service.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { Injectable } from '@angular/core'; 3 | 4 | // Translate service 5 | import { TranslateService } from '@ngx-translate/core'; 6 | 7 | export interface Locale { 8 | lang: string; 9 | data: Object; 10 | } 11 | 12 | @Injectable({ 13 | providedIn: 'root' 14 | }) 15 | export class TranslationLoaderService { 16 | 17 | /** 18 | * Service constructor 19 | * 20 | * @param _translateService The translate service 21 | */ 22 | constructor( 23 | private _translateService: TranslateService 24 | ) { } 25 | 26 | /** 27 | * Load translations 28 | * 29 | * @param args The translations data 30 | * 31 | * @author EL OUFIR Hatim 32 | */ 33 | loadTranslations(...args: Locale[]): void 34 | { 35 | const locales = [...args]; 36 | locales.forEach((locale) => { 37 | // use setTranslation() with the third argument set to true 38 | // to append translations instead of replacing them 39 | this._translateService.setTranslation(locale.lang, locale.data, true); 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /front-end/src/app/main/account-settings/account-settings.component.scss: -------------------------------------------------------------------------------- 1 | .img-uploader { 2 | width: 100%; 3 | float: left; 4 | padding: 10px; 5 | .img-preview { 6 | width: 250px; 7 | max-width: 100%; 8 | float: none; 9 | margin: 0 auto; 10 | padding: 10px; 11 | background-color: rgba(119, 119, 119, .05); 12 | border: 1px dashed rgba(119, 119, 119, .2); 13 | border-radius: 50%; 14 | img { 15 | width: 230px; 16 | max-width: 100%; 17 | border-radius: 50%; 18 | box-shadow: 1px 1px 5px rgba(119, 119, 119, .2); 19 | } 20 | } 21 | .img-input { 22 | width: 100%; 23 | float: left; 24 | text-align: center; 25 | input { 26 | display: none; 27 | } 28 | label { 29 | font-size: 30px; 30 | &:hover { 31 | cursor: pointer; 32 | } 33 | } 34 | } 35 | } 36 | 37 | .loading { 38 | float: none; 39 | margin: 0 auto; 40 | } 41 | 42 | .loading-account-data { 43 | position: absolute; 44 | left: 0; 45 | right: 0; 46 | top: 0; 47 | } 48 | 49 | .info-icon { 50 | float: none; 51 | text-align: center; 52 | font-size: 30px; 53 | margin-top: 10px; 54 | display: block; 55 | margin-left: 10px; 56 | margin-bottom: 10px; 57 | } -------------------------------------------------------------------------------- /front-end/src/app/main/account-settings/account-settings.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 6 | 7 | // Account settings component 8 | import { AccountSettingsComponent } from './account-settings.component'; 9 | 10 | // Authentication guard 11 | import { AuthGuard } from '@services/security/guards/auth.guard'; 12 | 13 | // Bootstrap module 14 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 15 | 16 | // Material modules 17 | import { MatProgressSpinnerModule, MatProgressBarModule } from '@angular/material'; 18 | 19 | // Shared module 20 | import { SharedModule } from '@app/core/modules/shared.module'; 21 | 22 | // Module routes 23 | const routes: Routes = [ 24 | // Dashboard component 25 | { 26 | path: '', 27 | component: AccountSettingsComponent, 28 | canActivate: [AuthGuard] 29 | }, 30 | ]; 31 | 32 | @NgModule({ 33 | declarations: [ 34 | // Account settings component 35 | AccountSettingsComponent 36 | ], 37 | imports: [ 38 | // Angular modules 39 | CommonModule, 40 | FormsModule, 41 | ReactiveFormsModule, 42 | // Bootstrap module 43 | NgbModule, 44 | // Router module 45 | RouterModule.forChild(routes), 46 | // Material modules 47 | MatProgressSpinnerModule, 48 | MatProgressBarModule, 49 | // Shared module 50 | SharedModule 51 | ] 52 | }) 53 | export class AccountSettingsModule { } 54 | -------------------------------------------------------------------------------- /front-end/src/app/main/dashboard/dashboard.component.scss: -------------------------------------------------------------------------------- 1 | @import "src/styles"; 2 | .card-statistics { 3 | .highlight-icon { 4 | height: 53px; 5 | width: 53px; 6 | @include display-flex; 7 | @include align-items(center); 8 | @include justify-content(center); 9 | @include border-radius(50px); 10 | i { 11 | font-size: 27px; 12 | line-height: 1; 13 | } 14 | } 15 | i { 16 | line-height: 1; 17 | } 18 | mat-spinner { 19 | display: block; 20 | float: right; 21 | } 22 | } -------------------------------------------------------------------------------- /front-end/src/app/main/dashboard/dashboard.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | 6 | // Dashboard component 7 | import { DashboardComponent } from './dashboard.component'; 8 | 9 | // Authentication guard 10 | import { AuthGuard } from '@services/security/guards/auth.guard'; 11 | 12 | // Bootstrap module 13 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 14 | 15 | // Material modules 16 | import { MatProgressSpinnerModule } from '@angular/material'; 17 | 18 | // Shared module 19 | import { SharedModule } from '@app/core/modules/shared.module'; 20 | 21 | // Module routes 22 | const routes: Routes = [ 23 | // Dashboard component 24 | { 25 | path: '', 26 | component: DashboardComponent, 27 | canActivate: [AuthGuard] 28 | }, 29 | ]; 30 | 31 | @NgModule({ 32 | declarations: [ 33 | // Dashboard component 34 | DashboardComponent 35 | ], 36 | imports: [ 37 | // Angular modules 38 | CommonModule, 39 | // Bootstrap module 40 | NgbModule, 41 | // Router module 42 | RouterModule.forChild(routes), 43 | // Material modules 44 | MatProgressSpinnerModule, 45 | // Shared module 46 | SharedModule 47 | ] 48 | }) 49 | export class DashboardModule { } 50 | -------------------------------------------------------------------------------- /front-end/src/app/main/dashboard/i18n/en.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'en', 5 | data: { 6 | 'DASHBOARD': { 7 | 'STATISTICS': { 8 | 'USERS': { 9 | 'TITLE': 'Total users', 10 | 'DESCRIPTION': 'Total number of users' 11 | }, 12 | 'PROFILES': { 13 | 'TITLE': 'Total profiles', 14 | 'DESCRIPTION': 'Total number of profiles' 15 | }, 16 | 'ROLES': { 17 | 'TITLE': 'Total roles', 18 | 'DESCRIPTION': 'Total number of roles' 19 | } 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /front-end/src/app/main/dashboard/i18n/fr.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'fr', 5 | data: { 6 | 'DASHBOARD': { 7 | 'STATISTICS': { 8 | 'USERS': { 9 | 'TITLE': 'Total des utilisateurs', 10 | 'DESCRIPTION': 'Nombre total des utilisateurs' 11 | }, 12 | 'PROFILES': { 13 | 'TITLE': 'Total des profils', 14 | 'DESCRIPTION': 'Nombre total des profils' 15 | }, 16 | 'ROLES': { 17 | 'TITLE': 'Total des rôles', 18 | 'DESCRIPTION': 'Nombre total des rôles' 19 | } 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /front-end/src/app/main/footer/footer.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Copyright © 2018 Bootstrap Dash. All rights reserved. 4 | Hand-crafted & made with 5 |
6 |
-------------------------------------------------------------------------------- /front-end/src/app/main/footer/footer.component.scss: -------------------------------------------------------------------------------- 1 | @import '../../../styles'; 2 | :host { 3 | width: 100%; 4 | } 5 | 6 | .footer { 7 | background: $footer-bg; 8 | color: $footer-color; 9 | padding: 20px 1.8rem; 10 | transition: all $action-transition-duration $action-transition-timing-function; 11 | -moz-transition: all $action-transition-duration $action-transition-timing-function; 12 | -webkit-transition: all $action-transition-duration $action-transition-timing-function; 13 | -ms-transition: all $action-transition-duration $action-transition-timing-function; 14 | border-top: $border-width solid $border-color; 15 | font-size: calc(#{$default-font-size} - 0.05rem); 16 | font-family: $type-1; 17 | a { 18 | color: theme-color(success); 19 | font-size: inherit; 20 | } 21 | @media (max-width: 991px) { 22 | margin-left: 0; 23 | width: 100%; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /front-end/src/app/main/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-footer', 5 | templateUrl: './footer.component.html', 6 | styleUrls: ['./footer.component.scss'] 7 | }) 8 | export class FooterComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /front-end/src/app/main/main.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | 6 | // Shared module 7 | import { SharedModule } from '@app/core/modules/shared.module'; 8 | 9 | // Module routes 10 | const routes: Routes = [ 11 | // Dashboard module 12 | { 13 | path: 'dashboard', 14 | loadChildren: './dashboard/dashboard.module#DashboardModule' 15 | }, 16 | // Security module 17 | { 18 | path: 'security', 19 | loadChildren: './security/security.module#SecurityModule' 20 | }, 21 | // Account settings module 22 | { 23 | path: 'account-settings', 24 | loadChildren: './account-settings/account-settings.module#AccountSettingsModule' 25 | }, 26 | // Default redirection to dashboard if route is unknown 27 | { 28 | path: '**', 29 | redirectTo: '/dashboard' 30 | } 31 | ]; 32 | 33 | @NgModule({ 34 | declarations: [], 35 | imports: [ 36 | // Angular modules 37 | CommonModule, 38 | // Router module 39 | RouterModule.forChild(routes), 40 | // Shared module 41 | SharedModule 42 | ] 43 | }) 44 | export class MainModule { } 45 | -------------------------------------------------------------------------------- /front-end/src/app/main/navbar/i18n/en.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'en', 5 | data: { 6 | 'NAVBAR': { 7 | 'HELLO': 'Hello', 8 | 'ACCOUNT_SETTINGS': 'Account settings', 9 | 'SIGN_OUT': 'Sign out' 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /front-end/src/app/main/navbar/i18n/fr.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'fr', 5 | data: { 6 | 'NAVBAR': { 7 | 'HELLO': 'Bienvenu', 8 | 'ACCOUNT_SETTINGS': 'Paramètrage', 9 | 'SIGN_OUT': 'Déconnexion' 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /front-end/src/app/main/security/profiles/profiles.component.scss: -------------------------------------------------------------------------------- 1 | @import "src/assets/styles/datatables"; 2 | .card-title { 3 | .btn-primary { 4 | color: white; 5 | } 6 | } 7 | 8 | .loading-roles { 9 | float: none; 10 | margin: 0 auto; 11 | } -------------------------------------------------------------------------------- /front-end/src/app/main/security/profiles/profiles.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 6 | 7 | // Profiles component 8 | import { ProfilesComponent } from './profiles.component'; 9 | 10 | // Authentication guard 11 | import { AuthGuard } from '@services/security/guards/auth.guard'; 12 | 13 | // Bootstrap modules 14 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 15 | import { RoleGuard } from '@services/security/guards/role.guard'; 16 | 17 | // Material modules 18 | import { 19 | MatProgressBarModule, 20 | MatProgressSpinnerModule, 21 | MatCheckboxModule 22 | } from '@angular/material'; 23 | 24 | // Shared module 25 | import { SharedModule } from '@app/core/modules/shared.module'; 26 | 27 | // Module routes 28 | const routes: Routes = [ 29 | // Profiles component 30 | { 31 | path: '', 32 | component: ProfilesComponent, 33 | canActivate: [ AuthGuard, RoleGuard ], 34 | data: { 35 | expectedRolesType: 'any', 36 | expectedRoles: [ 'ROLE_PROFILES' ] 37 | } 38 | } 39 | ]; 40 | 41 | @NgModule({ 42 | declarations: [ 43 | // Profiles component 44 | ProfilesComponent 45 | ], 46 | imports: [ 47 | // Angular modules 48 | CommonModule, 49 | FormsModule, 50 | ReactiveFormsModule, 51 | // Bootstrap modules 52 | NgbModule, 53 | // Router module 54 | RouterModule.forChild(routes), 55 | // Material modules 56 | MatProgressBarModule, 57 | MatProgressSpinnerModule, 58 | MatCheckboxModule, 59 | // Shared module 60 | SharedModule 61 | ] 62 | }) 63 | export class ProfilesModule { } 64 | -------------------------------------------------------------------------------- /front-end/src/app/main/security/roles/roles.component.scss: -------------------------------------------------------------------------------- 1 | @import "src/assets/styles/datatables"; 2 | .card-title { 3 | .btn-primary { 4 | color: white; 5 | } 6 | } -------------------------------------------------------------------------------- /front-end/src/app/main/security/roles/roles.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 6 | 7 | // Roles component 8 | import { RolesComponent } from './roles.component'; 9 | 10 | // Authentication guard 11 | import { AuthGuard } from '@services/security/guards/auth.guard'; 12 | 13 | // Bootstrap module 14 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 15 | import { RoleGuard } from '@services/security/guards/role.guard'; 16 | 17 | // Material modules 18 | import { MatProgressBarModule } from '@angular/material'; 19 | 20 | // Shared module 21 | import { SharedModule } from '@app/core/modules/shared.module'; 22 | 23 | // Module routes 24 | const routes: Routes = [ 25 | // Roles component 26 | { 27 | path: '', 28 | component: RolesComponent, 29 | canActivate: [ AuthGuard, RoleGuard ], 30 | data: { 31 | expectedRolesType: 'any', 32 | expectedRoles: [ 'ROLE_ROLES' ] 33 | } 34 | } 35 | ]; 36 | 37 | @NgModule({ 38 | declarations: [ 39 | // Roles component 40 | RolesComponent 41 | ], 42 | imports: [ 43 | // Angular modules 44 | CommonModule, 45 | FormsModule, 46 | ReactiveFormsModule, 47 | // Bootstrap module 48 | NgbModule, 49 | // Router module 50 | RouterModule.forChild(routes), 51 | // Material modules 52 | MatProgressBarModule, 53 | // Shared module 54 | SharedModule 55 | ] 56 | }) 57 | export class RolesModule { } 58 | -------------------------------------------------------------------------------- /front-end/src/app/main/security/security.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | 6 | // Module routes 7 | const routes: Routes = [ 8 | // Users module 9 | { 10 | path: 'users', 11 | loadChildren: './users/users.module#UsersModule' 12 | }, 13 | // Profiles module 14 | { 15 | path: 'profiles', 16 | loadChildren: './profiles/profiles.module#ProfilesModule' 17 | }, 18 | // Roles module 19 | { 20 | path: 'roles', 21 | loadChildren: './roles/roles.module#RolesModule' 22 | } 23 | ]; 24 | 25 | @NgModule({ 26 | declarations: [], 27 | imports: [ 28 | // Angular modules 29 | CommonModule, 30 | // Router module 31 | RouterModule.forChild(routes) 32 | ] 33 | }) 34 | export class SecurityModule { } 35 | -------------------------------------------------------------------------------- /front-end/src/app/main/security/users/users.component.scss: -------------------------------------------------------------------------------- 1 | @import "src/assets/styles/datatables"; 2 | .card-title { 3 | .btn-primary { 4 | color: white; 5 | } 6 | } 7 | 8 | .loading-profiles { 9 | float: none; 10 | margin: 0 auto; 11 | } 12 | 13 | .img-uploader { 14 | width: 100%; 15 | float: left; 16 | padding: 10px; 17 | .img-preview { 18 | width: 120px; 19 | height: 120px; 20 | float: none; 21 | margin: 0 auto; 22 | padding: 10px; 23 | background-color: rgba(119, 119, 119, .05); 24 | border: 1px dashed rgba(119, 119, 119, .2); 25 | border-radius: 50%; 26 | img { 27 | width: 100px; 28 | height: 100px; 29 | border-radius: 50%; 30 | box-shadow: 1px 1px 5px rgba(119, 119, 119, .2); 31 | } 32 | } 33 | .img-input { 34 | width: 100%; 35 | float: left; 36 | text-align: center; 37 | input { 38 | display: none; 39 | } 40 | label { 41 | font-size: 30px; 42 | &:hover { 43 | cursor: pointer; 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /front-end/src/app/main/security/users/users.module.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { NgModule } from '@angular/core'; 3 | import { CommonModule } from '@angular/common'; 4 | import { Routes, RouterModule } from '@angular/router'; 5 | import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 6 | 7 | // Users component 8 | import { UsersComponent } from './users.component'; 9 | 10 | // Authentication guard 11 | import { AuthGuard } from '@services/security/guards/auth.guard'; 12 | 13 | // Bootstrap modules 14 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 15 | import { RoleGuard } from '@services/security/guards/role.guard'; 16 | 17 | // Material modules 18 | import { 19 | MatProgressBarModule, 20 | MatProgressSpinnerModule, 21 | MatCheckboxModule 22 | } from '@angular/material'; 23 | 24 | // Shared module 25 | import { SharedModule } from '@app/core/modules/shared.module'; 26 | 27 | // Module routes 28 | const routes: Routes = [ 29 | // Users component 30 | { 31 | path: '', 32 | component: UsersComponent, 33 | canActivate: [ AuthGuard, RoleGuard ], 34 | data: { 35 | expectedRolesType: 'any', 36 | expectedRoles: [ 'ROLE_USERS' ] 37 | } 38 | } 39 | ]; 40 | 41 | @NgModule({ 42 | declarations: [ 43 | // Users component 44 | UsersComponent 45 | ], 46 | imports: [ 47 | // Angular modules 48 | CommonModule, 49 | FormsModule, 50 | ReactiveFormsModule, 51 | // Bootstrap modules 52 | NgbModule, 53 | // Router module 54 | RouterModule.forChild(routes), 55 | // Material modules 56 | MatProgressBarModule, 57 | MatProgressSpinnerModule, 58 | MatCheckboxModule, 59 | // Shared module 60 | SharedModule 61 | ] 62 | }) 63 | export class UsersModule { } 64 | -------------------------------------------------------------------------------- /front-end/src/app/main/sidebar/i18n/en.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'en', 5 | data: { 6 | 'SIDE_BAR': { 7 | 'MENU': { 8 | 'DASHBOARD': 'Dashboard', 9 | 'SECURITY': 'Security', 10 | 'USERS': 'Manage users', 11 | 'PROFILES': 'Manage profiles', 12 | 'ROLES': 'Manage roles' 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /front-end/src/app/main/sidebar/i18n/fr.ts: -------------------------------------------------------------------------------- 1 | import { Locale } from '@app/core/services/translation-loader.service'; 2 | 3 | export const locale: Locale = { 4 | lang: 'fr', 5 | data: { 6 | 'SIDE_BAR': { 7 | 'MENU': { 8 | 'DASHBOARD': 'Tableau de bord', 9 | 'SECURITY': 'Securité', 10 | 'USERS': 'Gérer les utilisateurs', 11 | 'PROFILES': 'Gérer les profils', 12 | 'ROLES': 'Gérer les rôles' 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /front-end/src/app/main/sidebar/sidebar.component.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { Component, OnInit } from '@angular/core'; 3 | 4 | // JWT helper service 5 | import { JwtHelperService } from '@services/security/jwt-helper.service'; 6 | 7 | // Translation imports 8 | import { TranslationLoaderService } from '@app/core/services/translation-loader.service'; 9 | import { locale as en } from './i18n/en'; 10 | import { locale as fr } from './i18n/fr'; 11 | 12 | @Component({ 13 | selector: 'app-sidebar', 14 | templateUrl: './sidebar.component.html', 15 | styleUrls: ['./sidebar.component.scss'] 16 | }) 17 | export class SidebarComponent implements OnInit { 18 | 19 | /** 20 | * User's picture version 21 | */ 22 | pictureVersion = Math.random(); 23 | 24 | /** 25 | * Component constructor 26 | * 27 | * @param jwtHelper The jwt helper service 28 | * @param _translationLoader The translation loader 29 | * 30 | * @author EL OUFIR Hatim 31 | */ 32 | constructor( 33 | public jwtHelper: JwtHelperService, 34 | private _translationLoader: TranslationLoaderService 35 | ) { 36 | // Load translation 37 | this._translationLoader.loadTranslations(en, fr); 38 | } 39 | 40 | /** 41 | * Component OnInit phase 42 | * 43 | * @author EL OUFIR Hatim 44 | */ 45 | ngOnInit(): void { } 46 | 47 | /** 48 | * Check if logged user has an authority based on a String 49 | * 50 | * @param role The authority's code 51 | * 52 | * @author EL OUFIR Hatim 53 | */ 54 | hasRole(role: string): Boolean { 55 | return this.jwtHelper.hasRole(role); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /front-end/src/app/models/common/partial-list.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A partial list that will contains a list of paginated data 3 | * 4 | * @author EL OUFIR Hatim 5 | */ 6 | export class PartialList { 7 | 8 | /** 9 | * The paginated data list 10 | */ 11 | data: Array; 12 | 13 | /** 14 | * Database data count 15 | * >> It's the total count of all items from database 16 | */ 17 | count: number; 18 | 19 | /** 20 | * The current page retrieved 21 | */ 22 | page: number; 23 | 24 | /** 25 | * The current page size 26 | */ 27 | size: number; 28 | } 29 | -------------------------------------------------------------------------------- /front-end/src/app/models/profile.model.ts: -------------------------------------------------------------------------------- 1 | // Application models 2 | import { User } from './user.model'; 3 | import { Role } from './role.model'; 4 | 5 | /** 6 | * The profile model definition 7 | * 8 | * @author EL OUFIR Hatim 9 | */ 10 | export class Profile { 11 | 12 | /** 13 | * The profile's id 14 | */ 15 | id: number; 16 | 17 | /** 18 | * The profile's code 19 | */ 20 | code: string; 21 | 22 | /** 23 | * The profile's designation 24 | */ 25 | designation: string; 26 | 27 | /** 28 | * The profile's attached roles 29 | */ 30 | roles: Array; 31 | 32 | /** 33 | * The profile's linked users 34 | */ 35 | users: Array; 36 | 37 | /** 38 | * Model constructor 39 | * 40 | * @author EL OUFIR Hatim 41 | */ 42 | constructor() { 43 | this.roles = []; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /front-end/src/app/models/role.model.ts: -------------------------------------------------------------------------------- 1 | // Application models 2 | import { Profile } from './profile.model'; 3 | 4 | /** 5 | * The role model definition 6 | * 7 | * @author EL OUFIR Hatim 8 | */ 9 | export class Role { 10 | 11 | /** 12 | * The role's id 13 | */ 14 | id: number; 15 | 16 | /** 17 | * The role's code 18 | */ 19 | code: string; 20 | 21 | /** 22 | * The role's designation 23 | */ 24 | designation: string; 25 | 26 | /** 27 | * The role's linked profiles 28 | */ 29 | profiles: Array; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /front-end/src/app/models/user.model.ts: -------------------------------------------------------------------------------- 1 | import { Profile } from './profile.model'; 2 | 3 | /** 4 | * The user model definition 5 | * 6 | * @author EL OUFIR Hatim 7 | */ 8 | export class User { 9 | 10 | /** 11 | * The user's id 12 | */ 13 | id: number; 14 | 15 | /** 16 | * The user's full name 17 | */ 18 | name: string; 19 | 20 | /** 21 | * The user's email address 22 | */ 23 | email: string; 24 | 25 | /** 26 | * The user's password 27 | */ 28 | password: string; 29 | 30 | /** 31 | * The user's remember token 32 | */ 33 | remember_token: string; 34 | 35 | /** 36 | * The user's created date 37 | */ 38 | created_at: Date; 39 | 40 | /** 41 | * The user's last update date 42 | */ 43 | updated_at: Date; 44 | 45 | /** 46 | * The user's password token 47 | */ 48 | password_token: string; 49 | 50 | /** 51 | * Profiles attached to the user 52 | */ 53 | profiles: Array; 54 | 55 | /** 56 | * The user's picture 57 | */ 58 | picture: any; 59 | 60 | /** 61 | * Model constructor 62 | * 63 | * @author EL OUFIR Hatim 64 | */ 65 | constructor() { 66 | this.profiles = []; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /front-end/src/app/services/profile.service.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { Injectable } from '@angular/core'; 3 | 4 | // CRUD Abstract service 5 | import { CrudService } from '@services/common/crud.service'; 6 | 7 | // Application models 8 | import { Profile } from '@models/profile.model'; 9 | 10 | // Angular Http client 11 | import { HttpClient } from '@angular/common/http'; 12 | 13 | @Injectable({ 14 | providedIn: 'root' 15 | }) 16 | /** 17 | * The profile model services 18 | * 19 | * @author EL OUFIR Hatim 20 | */ 21 | export class ProfileService extends CrudService { 22 | 23 | /** 24 | * Service constructor 25 | * 26 | * @param _http The Http object 27 | * 28 | * @author EL OUFIR Hatim 29 | */ 30 | constructor( 31 | _http: HttpClient 32 | ) { 33 | super(_http); 34 | this.setUrl('profiles'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /front-end/src/app/services/role.service.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { Injectable } from '@angular/core'; 3 | 4 | // CRUD Abstract service 5 | import { CrudService } from '@services/common/crud.service'; 6 | 7 | // Application models 8 | import { Role } from '@models/role.model'; 9 | 10 | // Angular Http client 11 | import { HttpClient } from '@angular/common/http'; 12 | 13 | @Injectable({ 14 | providedIn: 'root' 15 | }) 16 | /** 17 | * The role model services 18 | * 19 | * @author EL OUFIR Hatim 20 | */ 21 | export class RoleService extends CrudService { 22 | 23 | /** 24 | * Service constructor 25 | * 26 | * @param _http The Http object 27 | * 28 | * @author EL OUFIR Hatim 29 | */ 30 | constructor( 31 | _http: HttpClient 32 | ) { 33 | super(_http); 34 | this.setUrl('roles'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /front-end/src/app/services/security/guards/auth.guard.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { Injectable } from '@angular/core'; 3 | import { RouterStateSnapshot, ActivatedRouteSnapshot, Router, CanActivate } from '@angular/router'; 4 | 5 | // Application constants 6 | import { constants } from 'environments/constants'; 7 | 8 | @Injectable({ 9 | providedIn: 'root' 10 | }) 11 | /** 12 | * The authenticated guard 13 | * >> Used to give access to a specific route for the authenticated users 14 | * (having an access token) 15 | * 16 | * @author EL OUFIR Hatim 17 | */ 18 | export class AuthGuard implements CanActivate { 19 | 20 | /** 21 | * Service constructor 22 | * 23 | * @param router The router object 24 | * 25 | * @author EL OUFIR Hatim 26 | */ 27 | constructor( 28 | private router: Router 29 | ) { } 30 | 31 | /** 32 | * Check if the route can be accessed or not 33 | * >> Check if there is an access token registred in the localstorage 34 | * 35 | * @param next The next route to go into it 36 | * @param state The router state snapshot object 37 | * 38 | * @author EL OUFIR Hatim 39 | */ 40 | canActivate( 41 | next: ActivatedRouteSnapshot, 42 | state: RouterStateSnapshot 43 | ): boolean { 44 | if ( 45 | localStorage.getItem(constants.access_token) 46 | ) { return true; } 47 | localStorage.removeItem(constants.access_token); 48 | this.router.navigate([constants.auth_url]); 49 | return false; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /front-end/src/app/services/security/guards/no-auth.guard.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { Injectable } from '@angular/core'; 3 | import { RouterStateSnapshot, ActivatedRouteSnapshot, Router, CanActivate } from '@angular/router'; 4 | 5 | // Application constants 6 | import { constants } from 'environments/constants'; 7 | 8 | @Injectable({ 9 | providedIn: 'root' 10 | }) 11 | /** 12 | * The guest guard 13 | * >> Used to give access to a specific route for the guest users 14 | * (non-authenticated user) 15 | * 16 | * @author EL OUFIR Hatim 17 | */ 18 | export class NoAuthGuard implements CanActivate { 19 | 20 | /** 21 | * Service constructor 22 | * 23 | * @param router The router object 24 | * 25 | * @author EL OUFIR Hatim 26 | */ 27 | constructor( 28 | private router: Router 29 | ) { } 30 | 31 | /** 32 | * Check if the route can be accessed or not 33 | * >> Check if there isn't an access token registred in the localstorage 34 | * 35 | * @param next The next route to go into it 36 | * @param state The router state snapshot object 37 | * 38 | * @author EL OUFIR Hatim 39 | */ 40 | canActivate( 41 | next: ActivatedRouteSnapshot, 42 | state: RouterStateSnapshot 43 | ): boolean { 44 | if ( 45 | !localStorage.getItem(constants.access_token) 46 | ) { 47 | localStorage.removeItem(constants.access_token); 48 | return true; 49 | } 50 | this.router.navigate([constants.home_url]); 51 | return false; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /front-end/src/app/services/user.service.ts: -------------------------------------------------------------------------------- 1 | // Angular modules 2 | import { Injectable } from '@angular/core'; 3 | 4 | // CRUD Abstract service 5 | import { CrudService } from '@services/common/crud.service'; 6 | 7 | // Application models 8 | import { User } from '@models/user.model'; 9 | 10 | // Angular Http client 11 | import { HttpClient } from '@angular/common/http'; 12 | 13 | @Injectable({ 14 | providedIn: 'root' 15 | }) 16 | /** 17 | * The user model services 18 | * 19 | * @author EL OUFIR Hatim 20 | */ 21 | export class UserService extends CrudService { 22 | 23 | /** 24 | * Service constructor 25 | * 26 | * @param _http The Http object 27 | * 28 | * @author EL OUFIR Hatim 29 | */ 30 | constructor( 31 | private __http: HttpClient 32 | ) { 33 | super(__http); 34 | this.setUrl('users'); 35 | } 36 | 37 | /** 38 | * @override 39 | * Save the item into database 40 | * 41 | * @param model The item to save 42 | * @param update A flag if set to TRUE it means it's an update, otherwise it's a save 43 | * 44 | * @author EL OUFIR Hatim 45 | */ 46 | public save(model: any, update?: boolean): any { 47 | this.options.params = undefined; 48 | if (update) { 49 | return this.__http.post(this.url + '/' + model.get('id'), model, this.options); 50 | } else { 51 | return this.__http.post(this.url, model, this.options); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /front-end/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/.gitkeep -------------------------------------------------------------------------------- /front-end/src/assets/fonts/PT_Sans/PTSans-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/fonts/PT_Sans/PTSans-Bold.eot -------------------------------------------------------------------------------- /front-end/src/assets/fonts/PT_Sans/PTSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/fonts/PT_Sans/PTSans-Bold.ttf -------------------------------------------------------------------------------- /front-end/src/assets/fonts/PT_Sans/PTSans-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/fonts/PT_Sans/PTSans-Bold.woff -------------------------------------------------------------------------------- /front-end/src/assets/fonts/PT_Sans/PTSans-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/fonts/PT_Sans/PTSans-Bold.woff2 -------------------------------------------------------------------------------- /front-end/src/assets/fonts/PT_Sans/PTSans-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/fonts/PT_Sans/PTSans-Regular.eot -------------------------------------------------------------------------------- /front-end/src/assets/fonts/PT_Sans/PTSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/fonts/PT_Sans/PTSans-Regular.ttf -------------------------------------------------------------------------------- /front-end/src/assets/fonts/PT_Sans/PTSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/fonts/PT_Sans/PTSans-Regular.woff -------------------------------------------------------------------------------- /front-end/src/assets/fonts/PT_Sans/PTSans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/fonts/PT_Sans/PTSans-Regular.woff2 -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_10.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_11.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_12.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_3.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_4.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_5.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_6.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_7.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_8.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/carousel/banner_9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/carousel/banner_9.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/dashboard/img_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/dashboard/img_1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/dashboard/img_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/dashboard/img_2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/dashboard/img_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/dashboard/img_3.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/dashboard/img_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/dashboard/img_4.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces-clipart/pic-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces-clipart/pic-1.png -------------------------------------------------------------------------------- /front-end/src/assets/images/faces-clipart/pic-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces-clipart/pic-2.png -------------------------------------------------------------------------------- /front-end/src/assets/images/faces-clipart/pic-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces-clipart/pic-3.png -------------------------------------------------------------------------------- /front-end/src/assets/images/faces-clipart/pic-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces-clipart/pic-4.png -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/avatar.png -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face10.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face11.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face12.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face13.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face14.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face15.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face16.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face17.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face18.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face19.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face20.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face21.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face22.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face23.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face24.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face25.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face26.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face27.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face3.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face4.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face5.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face6.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face7.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face8.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/face9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/face9.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/faces/profile/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/faces/profile/profile.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/128/001-interface-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/128/001-interface-1.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/128/002-tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/128/002-tool.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/128/003-interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/128/003-interface.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/128/004-folder-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/128/004-folder-1.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/128/005-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/128/005-database.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/128/006-record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/128/006-record.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/128/007-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/128/007-folder.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/128/008-archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/128/008-archive.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/256/001-interface-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/256/001-interface-1.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/256/002-tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/256/002-tool.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/256/003-interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/256/003-interface.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/256/004-folder-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/256/004-folder-1.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/256/005-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/256/005-database.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/256/006-record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/256/006-record.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/256/007-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/256/007-folder.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/256/008-archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/256/008-archive.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/512/001-interface-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/512/001-interface-1.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/512/002-tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/512/002-tool.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/512/003-interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/512/003-interface.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/512/004-folder-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/512/004-folder-1.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/512/005-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/512/005-database.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/512/006-record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/512/006-record.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/512/007-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/512/007-folder.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/512/008-archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/512/008-archive.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/64/001-interface-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/64/001-interface-1.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/64/002-tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/64/002-tool.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/64/003-interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/64/003-interface.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/64/004-folder-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/64/004-folder-1.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/64/005-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/64/005-database.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/64/006-record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/64/006-record.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/64/007-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/64/007-folder.png -------------------------------------------------------------------------------- /front-end/src/assets/images/file-icons/64/008-archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/file-icons/64/008-archive.png -------------------------------------------------------------------------------- /front-end/src/assets/images/flags/en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/flags/en.png -------------------------------------------------------------------------------- /front-end/src/assets/images/flags/fr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/flags/fr.png -------------------------------------------------------------------------------- /front-end/src/assets/images/flags/lang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/flags/lang.png -------------------------------------------------------------------------------- /front-end/src/assets/images/icons/forgot-password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/icons/forgot-password.png -------------------------------------------------------------------------------- /front-end/src/assets/images/icons/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/icons/login.png -------------------------------------------------------------------------------- /front-end/src/assets/images/lightbox/play-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/lightbox/play-button.png -------------------------------------------------------------------------------- /front-end/src/assets/images/lightbox/thumb-v-v-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/lightbox/thumb-v-v-1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/lightbox/thumb-v-v-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/lightbox/thumb-v-v-2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/lightbox/thumb-v-y-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/lightbox/thumb-v-y-1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/lightbox/thumb-v-y-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/lightbox/thumb-v-y-2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/logos/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/logos/logo.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/01.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/02.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/03.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/04.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/05.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/06.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/07.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/08.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/09.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/10.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/11.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/12.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/13.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/14.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/15.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/16.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/17.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/18.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/19.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/20.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/21.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/22.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/23.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/24.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/25.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/26.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/27.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/28.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/29.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/30.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/31.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/32.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/33.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/34.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/35.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/36.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/37.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/38.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/39.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/40.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/41.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/42.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/43.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/44.png -------------------------------------------------------------------------------- /front-end/src/assets/images/menu_icons/45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/menu_icons/45.png -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/10.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/11.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/12.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/13.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/14.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/15.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/3.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/4.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/5.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/6.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/7.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/8.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/1280x768/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/1280x768/9.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/1.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/10.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/11.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/12.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/13.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/14.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/15.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/3.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/4.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/5.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/6.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/7.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/8.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/300x300/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/300x300/9.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/Login_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/Login_bg.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/Login_bg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/Login_bg2.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/samples/lockscreen-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/samples/lockscreen-bg.jpg -------------------------------------------------------------------------------- /front-end/src/assets/images/sprites/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/sprites/blue.png -------------------------------------------------------------------------------- /front-end/src/assets/images/sprites/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/sprites/dark.png -------------------------------------------------------------------------------- /front-end/src/assets/images/sprites/green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/sprites/green.png -------------------------------------------------------------------------------- /front-end/src/assets/images/sprites/jsgrid-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/sprites/jsgrid-icons.png -------------------------------------------------------------------------------- /front-end/src/assets/images/sprites/logo-mini.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /front-end/src/assets/images/sprites/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/sprites/red.png -------------------------------------------------------------------------------- /front-end/src/assets/images/sprites/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/assets/images/sprites/yellow.png -------------------------------------------------------------------------------- /front-end/src/assets/styles/_badges.scss: -------------------------------------------------------------------------------- 1 | .badge { 2 | border-radius: 0.25rem; 3 | font-size: 0.65rem; 4 | font-weight: initial; 5 | line-height: 1; 6 | padding: 0.2rem 0.3rem; 7 | font-family: $type-1; 8 | font-weight: 600; 9 | &:empty { 10 | display: inline-block; 11 | min-width: 10px; 12 | min-height: 10px; 13 | padding: 0; 14 | margin-right: 10px; 15 | @include border-radius(100%); 16 | .rtl & { 17 | margin-left: 10px; 18 | margin-right: 0; 19 | } 20 | } 21 | &.badge-pill { 22 | border-radius: 10rem; 23 | } 24 | &.badge-fw { 25 | min-width: 70px; 26 | } 27 | &.badge-lg { 28 | padding: 0.4rem 0.5rem; 29 | } 30 | } 31 | 32 | /*Badge variations*/ 33 | 34 | @each $color, 35 | $value in $theme-colors { 36 | .badge-#{$color} { 37 | @include badge-variations($value); 38 | } 39 | } 40 | 41 | /*Badge inverse variations*/ 42 | 43 | @each $color, 44 | $value in $theme-colors { 45 | .badge-inverse-#{$color} { 46 | @include badge-inverse-variations($value); 47 | } 48 | } 49 | 50 | /*Badge outlined variations*/ 51 | 52 | @each $color, 53 | $value in $theme-colors { 54 | .badge-outline-#{$color} { 55 | @include badge-outline-variations($value); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/_bootstrap-alerts.scss: -------------------------------------------------------------------------------- 1 | /* Bootstrap Alerts */ 2 | 3 | .alert { 4 | font-size: $default-font-size; 5 | i { 6 | font-size: 1.25rem; 7 | margin-right: 1.25rem; 8 | vertical-align: middle; 9 | line-height: .5; 10 | } 11 | } 12 | 13 | @each $color, 14 | $value in $theme-colors { 15 | .alert-#{$color} { 16 | @include alert-variant(rgba(theme-color($color), .2), theme-color-level($color, 1), theme-color-level($color, 3)); 17 | } 18 | } 19 | 20 | @each $color, 21 | $value in $theme-colors { 22 | .alert-fill-#{$color} { 23 | @include alert-variant(theme-color($color), theme-color($color), color(white)); 24 | } 25 | } 26 | 27 | .alert-transparent-left { 28 | background: transparent; 29 | text-align: left; 30 | border: none; 31 | padding: 0; 32 | } 33 | 34 | .alert-transparent-center { 35 | background: transparent; 36 | text-align: center; 37 | border: none; 38 | padding: 0; 39 | } 40 | 41 | .alert-transparent-right { 42 | background: transparent; 43 | text-align: right; 44 | border: none; 45 | padding: 0; 46 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/_bootstrap-progress.scss: -------------------------------------------------------------------------------- 1 | /* Bootstrap Progress */ 2 | 3 | .progress { 4 | @include border-radius(3px); 5 | height: 8px; 6 | .progress-bar { 7 | @include border-radius(3px); 8 | } 9 | &.progress-sm { 10 | height: 0.375rem; 11 | } 12 | &.progress-md { 13 | height: 8px; 14 | } 15 | &.progress-lg { 16 | height: 15px; 17 | } 18 | &.progress-xl { 19 | height: 18px; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/_cards.scss: -------------------------------------------------------------------------------- 1 | /* Cards */ 2 | 3 | .card { 4 | border: 0; 5 | @include border-radius(2px); 6 | .card-body { 7 | padding: $card-padding-y $card-padding-x; 8 | + .card-body { 9 | padding-top: 0; 10 | } 11 | } 12 | &.card-outline-success{ 13 | border: 1px solid theme-color("success"); 14 | } 15 | &.card-outline-primary{ 16 | border: 1px solid theme-color("primary"); 17 | } 18 | &.card-outline-warning{ 19 | border: 1px solid theme-color("warning"); 20 | } 21 | &.card-outline-danger{ 22 | border: 1px solid theme-color("danger"); 23 | } 24 | &.card-rounded{ 25 | @include border-radius(5px); 26 | } 27 | 28 | &.card-faded { 29 | background: #b5b0b2; 30 | border-color: #b5b0b2; 31 | } 32 | &.card-circle-progress { 33 | color: $white; 34 | text-align: center; 35 | } 36 | } 37 | 38 | @each $color, $value in $theme-colors { 39 | .card-inverse-#{$color} { 40 | @include card-inverse-variant(rgba(theme-color($color), .2), theme-color-level($color, 1), theme-color-level($color, 3)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/_datatables.scss: -------------------------------------------------------------------------------- 1 | .datatable-container { 2 | .table { 3 | tr { 4 | th, 5 | td { 6 | vertical-align: middle; 7 | } 8 | td { 9 | &.actions { 10 | button { 11 | &:not(:last-child) { 12 | margin-right: 0.5rem; 13 | } 14 | } 15 | } 16 | } 17 | } 18 | .loading-data { 19 | position: relative; 20 | mat-progress-bar { 21 | position: absolute; 22 | top: 0; 23 | left: 0; 24 | right: 0; 25 | } 26 | } 27 | } 28 | ngb-pagination { 29 | margin-top: 20px; 30 | } 31 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/_dropdowns.scss: -------------------------------------------------------------------------------- 1 | /* Dropdowns */ 2 | 3 | .dropdown-menu { 4 | font-size: $default-font-size; 5 | .dropdown-item { 6 | &:active { 7 | background: initial; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/_fonts.scss: -------------------------------------------------------------------------------- 1 | /* Fonts */ 2 | 3 | @import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700'); 4 | @import url('https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700'); 5 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/_forms.scss: -------------------------------------------------------------------------------- 1 | /* Forms */ 2 | 3 | .input-group-append, 4 | .input-group-prepend { 5 | background: color(white); 6 | color: $input-placeholder-color; 7 | width: auto; 8 | border: none; 9 | .input-group-text { 10 | background: transparent; 11 | border-color: $border-color; 12 | } 13 | } 14 | 15 | .form-control { 16 | height: 35px; 17 | border: 1px solid $border-color; 18 | font-family: $type-1; 19 | font-size: $input-font-size; 20 | padding: $btn-padding-y .75rem; 21 | line-height: 14px; 22 | &.form-control-lg { 23 | padding: $input-btn-padding-y-lg .75rem; 24 | } 25 | &.form-control-sm { 26 | padding: $input-btn-padding-y-sm .75rem; 27 | } 28 | &:focus { 29 | border-color: transparent; 30 | } 31 | } 32 | 33 | select { 34 | &.form-control { 35 | padding: 0.4375rem 0.75rem; 36 | } 37 | } 38 | 39 | .form-group { 40 | label { 41 | font-size: $default-font-size; 42 | padding-top: 5px; 43 | } 44 | &.has-danger { 45 | .form-control { 46 | border-color: theme-color(danger); 47 | } 48 | } 49 | .file-upload-default { 50 | visibility: hidden; 51 | position: absolute; 52 | } 53 | .file-upload-info { 54 | background: transparent; 55 | } 56 | .input-group { 57 | .input-group-addon { 58 | padding: 5px 10px; 59 | } 60 | } 61 | } 62 | 63 | .input-group, 64 | .form-control { 65 | &.has-error { 66 | border: 1px solid #d44b4b; 67 | } 68 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/_functions.scss: -------------------------------------------------------------------------------- 1 | @function social-color($key: "twitter") { 2 | @return map-get($social-colors, $key); 3 | } 4 | 5 | @function theme-gradient-color($key: "primary") { 6 | @return map-get($theme-gradient-colors, $key); 7 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/_icons.scss: -------------------------------------------------------------------------------- 1 | /* Icons */ 2 | 3 | 4 | .icons-list { 5 | border-left: 1px solid $border-color; 6 | border-bottom: 1px solid $border-color; 7 | 8 | > div { 9 | background: $white; 10 | border-top: 1px solid $border-color; 11 | border-right: 1px solid $border-color; 12 | @include display-flex; 13 | @include align-items(center); 14 | padding: 15px; 15 | font-family: $type-1; 16 | font-size: $default-font-size; 17 | 18 | i { 19 | display: inline-block; 20 | font-size: 20px; 21 | width: 40px; 22 | text-align: left; 23 | color: theme-color(primary); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/_lists.scss: -------------------------------------------------------------------------------- 1 | ul, 2 | ol, 3 | dl { 4 | padding-left: 1rem; 5 | font-size: $default-font-size; 6 | li { 7 | line-height: 1.8; 8 | } 9 | } 10 | 11 | .list-ticked, 12 | .list-arrow, 13 | .list-star { 14 | list-style: none; 15 | padding: 0; 16 | li { 17 | padding-left: 1.5rem; 18 | &:before { 19 | font-family: "Material Design Icons"; 20 | margin-left: -1.5rem; 21 | width: 1.5rem; 22 | margin-right: .5rem; 23 | } 24 | } 25 | } 26 | 27 | .list-ticked { 28 | li { 29 | &:before { 30 | content: '\F12D'; 31 | color: theme-color(danger); 32 | } 33 | } 34 | } 35 | 36 | .list-arrow { 37 | li { 38 | &:before { 39 | content: '\F142'; 40 | color: theme-color(success); 41 | } 42 | } 43 | } 44 | 45 | .list-star { 46 | li { 47 | &:before { 48 | content: '\F4CE'; 49 | color: theme-color(warning); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/_misc.scss: -------------------------------------------------------------------------------- 1 | body, 2 | html { 3 | overflow-x: hidden; 4 | padding-right: 0 !important; // resets padding right added by Bootstrap modal 5 | } 6 | 7 | *:-moz-full-screen, 8 | *:-webkit-full-screen, 9 | *:fullscreen *:-ms-fullscreen { 10 | overflow: auto !important; 11 | } 12 | 13 | .page-body-wrapper { 14 | min-height: calc(100vh - #{$navbar-height}); 15 | @include display-flex(); 16 | @include flex-direction(row); 17 | padding-left: 0; 18 | padding-right: 0; 19 | padding-top: $navbar-height; 20 | &.full-page-wrapper { 21 | width: 100%; 22 | min-height: 100vh; 23 | } 24 | } 25 | 26 | .main-panel { 27 | transition: width $action-transition-duration $action-transition-timing-function, margin $action-transition-duration $action-transition-timing-function; 28 | width: calc(100% - #{$sidebar-width-lg}); 29 | min-height: calc(100vh - #{$navbar-height}); 30 | @include display-flex(); 31 | @include flex-direction(column); 32 | @media (max-width: 991px) { 33 | margin-left: 0; 34 | width: 100%; 35 | } 36 | } 37 | 38 | .content-wrapper { 39 | background: $content-bg; 40 | padding: 1.5rem 1.7rem; 41 | width: 100%; 42 | @include flex-grow(1); 43 | } 44 | 45 | .container-scroller { 46 | overflow: hidden; 47 | } 48 | 49 | .scroll-container { 50 | position: relative; 51 | &.horizontally { 52 | overflow-x: hidden; 53 | width: 100%; 54 | max-width: 100%; 55 | } 56 | &.vertically { 57 | overflow-y: hidden; 58 | height: 100%; 59 | max-height: 100%; 60 | } 61 | } 62 | 63 | pre { 64 | background: color(gray-lighter); 65 | padding: 15px; 66 | font-size: 14px; 67 | } 68 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/_modals.scss: -------------------------------------------------------------------------------- 1 | /* Modals */ 2 | 3 | .modal{ 4 | .modal-dialog{ 5 | margin-top: calc(#{$navbar-height} + 30px); 6 | .modal-content{ 7 | .modal-header{ 8 | padding: $modal-header-padding-y $modal-header-padding-x; 9 | .close{ 10 | span{ 11 | font-size: 20px; 12 | font-weight: 400; 13 | color: #6a6a6a; 14 | } 15 | } 16 | } 17 | .modal-body{ 18 | padding: $modal-body-padding-y $modal-body-padding-x; 19 | } 20 | .modal-footer{ 21 | padding: $modal-footer-padding-y $modal-footer-padding-x; 22 | } 23 | } 24 | } 25 | } 26 | 27 | .modal-content { 28 | background-color: #fff; 29 | .form-control { 30 | background-color: #f2f8f9; 31 | } 32 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/_override.scss: -------------------------------------------------------------------------------- 1 | #toast-container>div { 2 | opacity: 1; 3 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/_rating.scss: -------------------------------------------------------------------------------- 1 | .rating { 2 | span { 3 | color: theme-color(warning); 4 | font-size: 1.2rem; 5 | margin-right: 2px; 6 | } 7 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/_responsive.scss: -------------------------------------------------------------------------------- 1 | @media (max-width: 991px) { 2 | .navbar { 3 | .navbar-brand-wrapper { 4 | .brand-logo { 5 | display: none; 6 | } 7 | .brand-logo-mini { 8 | display: inline-block; 9 | } 10 | } 11 | } 12 | } 13 | @media screen and (max-width: 991px) { 14 | .row-offcanvas { 15 | position: relative; 16 | -webkit-transition: all .25s ease-out; 17 | -o-transition: all .25s ease-out; 18 | transition: all .25s ease-out; 19 | 20 | &.row-offcanvas-right { 21 | right: 0; 22 | 23 | /deep/ .sidebar-offcanvas { 24 | right: -100%; // 12 columns 25 | } 26 | 27 | &.active { 28 | right: calc(50% + 30px); // 6 columns 29 | 30 | /deep/ .sidebar-offcanvas { 31 | right: calc(-50% - 15px); // 6 columns 32 | } 33 | } 34 | } 35 | 36 | &.row-offcanvas-left { 37 | left: 0; 38 | 39 | /deep/ .sidebar-offcanvas { 40 | left: -100%; // 12 columns 41 | } 42 | 43 | &.active { 44 | left: 50%; // 6 columns 45 | 46 | /deep/ .sidebar-offcanvas { 47 | left: -50%; // 6 columns 48 | } 49 | } 50 | } 51 | 52 | /deep/ .sidebar-offcanvas { 53 | position: absolute; 54 | top: 0; 55 | width: calc( 50% + 30px); // 6 columns 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/_tables.scss: -------------------------------------------------------------------------------- 1 | /* Tables */ 2 | 3 | .table { 4 | margin-bottom: 0; 5 | thead { 6 | th { 7 | border-top: 0; 8 | border-bottom-width: 1px; 9 | font-family: $type-2; 10 | font-weight: 500; 11 | i { 12 | margin-left: 0.325rem; 13 | } 14 | } 15 | } 16 | td, 17 | th { 18 | vertical-align: middle; 19 | font-size: $default-font-size; 20 | line-height: 1; 21 | white-space: nowrap; 22 | img { 23 | @extend .img-xs; 24 | border-radius: 100%; 25 | } 26 | .badge { 27 | margin-bottom: 0; 28 | } 29 | .form-check, 30 | .form-radio { 31 | margin-top: 0; 32 | margin-bottom: -0px; 33 | } 34 | } 35 | &.table-borderless { 36 | border: none; 37 | td, 38 | th, 39 | tr { 40 | border: none; 41 | } 42 | } 43 | &.table-bordered { 44 | thead { 45 | border: 1px solid $border-color; 46 | border-bottom: none; 47 | tr { 48 | th { 49 | border-left: none; 50 | border-right: none; 51 | } 52 | } 53 | } 54 | tbody { 55 | tr { 56 | td {} 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/_tooltips.scss: -------------------------------------------------------------------------------- 1 | /* Tooltips */ 2 | 3 | 4 | .tooltip-static-demo { 5 | .tooltip { 6 | position: relative; 7 | display: inline-block; 8 | opacity: 1; 9 | margin: 0 10px 10px 0; 10 | } 11 | 12 | .bs-tooltip-bottom-demo, 13 | .bs-tooltip-top-demo { 14 | .arrow { 15 | left: 50%; 16 | } 17 | } 18 | 19 | .bs-tooltip-left-demo, 20 | .bs-tooltip-right-demo { 21 | .arrow { 22 | top: 50%; 23 | } 24 | } 25 | } 26 | 27 | .tooltip { 28 | font-size: $tooltip-font-size; 29 | min-width: 5.625rem; 30 | 31 | .tooltip-inner { 32 | font-family: $type-1; 33 | } 34 | z-index: 1029; 35 | } 36 | @each $color, $value in $theme-colors { 37 | .tooltip-#{$color} { 38 | @include tooltip-variant(theme-color($color)); 39 | } 40 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_animation.scss: -------------------------------------------------------------------------------- 1 | /* Animation Mixins */ 2 | @keyframes dropdownAnimation { 3 | from { 4 | opacity: 0; 5 | transform: translate3d(0, -30px, 0); 6 | } 7 | 8 | to { 9 | opacity: 1; 10 | transform: none; 11 | transform: translate3d(0, 0px, 0); 12 | } 13 | } 14 | 15 | .dropdownAnimation { 16 | animation-name: dropdownAnimation; 17 | @include animation-duration($action-transition-duration); 18 | @include animation-fill-mode(both); 19 | } 20 | @mixin transition($settings) { 21 | -webkit-transition: $settings; 22 | -moz-transition: $settings; 23 | -ms-transition: $settings; 24 | -o-transition: $settings; 25 | transition: $settings; 26 | } 27 | @keyframes fadeOut { 28 | from { 29 | opacity: 1; 30 | } 31 | 32 | to { 33 | opacity: 0; 34 | } 35 | } 36 | 37 | .fadeOut { 38 | animation-name: fadeOut; 39 | } 40 | 41 | .infinite-spin { 42 | @keyframes spin { 43 | from { 44 | transform: rotate(0deg); 45 | } 46 | 47 | to { 48 | transform: rotate(360deg); 49 | } 50 | } 51 | animation-name: spin; 52 | animation-duration: 3s; 53 | animation-iteration-count: infinite; 54 | animation-timing-function: linear; 55 | } 56 | @keyframes fadeInUp { 57 | from { 58 | opacity: 0; 59 | transform: translate3d(0, 100%, 0); 60 | } 61 | 62 | to { 63 | opacity: 1; 64 | transform: none; 65 | } 66 | } 67 | 68 | .fadeInUp { 69 | animation-name: fadeInUp; 70 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_background.scss: -------------------------------------------------------------------------------- 1 | // Background Mixins // 2 | @mixin bg($color) { 3 | background: $color; 4 | } 5 | 6 | @mixin bg-gradient($color1, $color2) { 7 | background: $color1; 8 | /* For browsers that do not support gradients */ 9 | background: -webkit-linear-gradient(90deg, $color1, $color2); 10 | /* For Safari 5.1 to 6.0 */ 11 | background: -o-linear-gradient(90deg, $color1, $color2); 12 | /* For Opera 11.1 to 12.0 */ 13 | background: -moz-linear-gradient(90deg, $color1, $color2); 14 | /* For Firefox 3.6 to 15 */ 15 | background: linear-gradient(90deg, $color1, $color2); 16 | /* Standard syntax */ 17 | } 18 | 19 | @mixin bg-inverse-variant($color) { 20 | background: rgba($color, 0.2); 21 | } 22 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_badges.scss: -------------------------------------------------------------------------------- 1 | // Badge variations 2 | @mixin badge-variations($color) { 3 | border: 1px solid $color; 4 | color: $white; 5 | } 6 | 7 | // Badge outlined variations 8 | @mixin badge-outline-variations($color) { 9 | color: $color; 10 | border: 1px solid $color; 11 | } 12 | 13 | @mixin badge-inverse-variations($color) { 14 | background: rgba($color, 0.3); 15 | color: $color; 16 | } 17 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_blockqoute.scss: -------------------------------------------------------------------------------- 1 | // BlockQuote Mixins // 2 | 3 | @mixin blockquote($color) { 4 | border-color: $color; 5 | .blockquote-footer { 6 | color: $color; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_breadcrumbs.scss: -------------------------------------------------------------------------------- 1 | // Breadcrumb color variations 2 | @mixin breadcrumb-inverse-variant($color) { 3 | background: lighten($color, 25%); 4 | border-color: $color; 5 | 6 | .breadcrumb-item { 7 | color: $color; 8 | 9 | &:before { 10 | color: inherit; 11 | } 12 | 13 | a { 14 | color: inherit; 15 | } 16 | } 17 | 18 | &.breadcrumb-custom { 19 | background: transparent; 20 | 21 | .breadcrumb-item { 22 | background: lighten($color, 25%); 23 | 24 | a { 25 | color: $color; 26 | border: none; 27 | 28 | &:before { 29 | border-left-color: lighten($color, 25%); 30 | } 31 | } 32 | 33 | span { 34 | color: $color; 35 | } 36 | 37 | &:last-child { 38 | background: transparent; 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_buttons.scss: -------------------------------------------------------------------------------- 1 | @mixin social-button($color) { 2 | background: $color; 3 | color: color(white); 4 | 5 | &:hover { 6 | background: darken($color, 10%); 7 | } 8 | 9 | &.btn-link { 10 | background: none; 11 | color: $color; 12 | 13 | &:hover { 14 | color: darken($color, 10%); 15 | } 16 | } 17 | } 18 | 19 | @mixin button-inverse-variant($color, $color-hover: $white) { 20 | color: $color; 21 | background-color: rgba($color, 0.2); 22 | background-image: none; 23 | border-color: rgba($color, 0); 24 | @include hover { 25 | color: $color-hover; 26 | background-color: $color; 27 | border-color: $color; 28 | } 29 | 30 | &.focus, 31 | &:focus { 32 | box-shadow: 0 0 0 3px rgba($color, .5); 33 | } 34 | 35 | &.disabled, 36 | &:disabled { 37 | color: $color; 38 | background-color: transparent; 39 | } 40 | 41 | &.active, 42 | &:active, 43 | .show > &.dropdown-toggle { 44 | color: $color-hover; 45 | background-color: $color; 46 | border-color: $color; 47 | } 48 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_cards.scss: -------------------------------------------------------------------------------- 1 | // Cards Mixins 2 | 3 | @mixin card-inverse-variant($bg, $border, $color) { 4 | background: $bg; 5 | border: 1px solid $border; 6 | color: $color; 7 | } 8 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_misc.scss: -------------------------------------------------------------------------------- 1 | /* Miscellaneous Mixins */ 2 | 3 | @mixin placeholder { 4 | &::-webkit-input-placeholder {@content} 5 | &:-moz-placeholder {@content} 6 | &::-moz-placeholder {@content} 7 | &:-ms-input-placeholder {@content} 8 | } 9 | 10 | // generic transform 11 | @mixin transform($transforms) { 12 | -moz-transform: $transforms; 13 | -o-transform: $transforms; 14 | -ms-transform: $transforms; 15 | -webkit-transform: $transforms; 16 | transform: $transforms; 17 | } 18 | // rotate 19 | @mixin rotate ($deg) { 20 | @include transform(rotate(#{$deg}deg)); 21 | } 22 | 23 | // scale 24 | @mixin scale($scale) { 25 | @include transform(scale($scale)); 26 | } 27 | // translate 28 | @mixin translate ($x, $y) { 29 | @include transform(translate($x, $y)); 30 | } 31 | // skew 32 | @mixin skew ($x, $y) { 33 | @include transform(skew(#{$x}deg, #{$y}deg)); 34 | } 35 | //transform origin 36 | @mixin transform-origin ($origin) { 37 | moz-transform-origin: $origin; 38 | -o-transform-origin: $origin; 39 | -ms-transform-origin: $origin; 40 | -webkit-transform-origin: $origin; 41 | transform-origin: $origin; 42 | } 43 | //Ellipsis 44 | %ellipsor{ 45 | text-overflow: ellipsis; 46 | overflow: hidden; 47 | max-width:100%; 48 | white-space: nowrap; 49 | } 50 | -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination variations 2 | @mixin pagination-variants($color) { 3 | .page-item { 4 | &.active { 5 | .page-link { 6 | background: $color; 7 | border-color: $color; 8 | } 9 | } 10 | 11 | .page-link { 12 | &:hover { 13 | background: lighten($color,5%); 14 | border-color: $color; 15 | color: $white; 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_popovers.scss: -------------------------------------------------------------------------------- 1 | // popover color variations // 2 | 3 | @mixin popover-variant($color) { 4 | border-color: $color; 5 | .popover-header { 6 | background: $color; 7 | color: $white; 8 | } 9 | &.bs-popover-top { 10 | .arrow { 11 | &:before, 12 | &:after { 13 | border-top-color: $color; 14 | } 15 | } 16 | } 17 | &.bs-popover-right { 18 | .arrow { 19 | &:before, 20 | &:after { 21 | border-right-color: $color; 22 | } 23 | } 24 | } 25 | &.bs-popover-bottom { 26 | .arrow { 27 | &:before, 28 | &:after { 29 | border-bottom-color: $color; 30 | } 31 | } 32 | } 33 | &.bs-popover-left { 34 | .arrow { 35 | &:before, 36 | &:after { 37 | border-left-color: $color; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /front-end/src/assets/styles/mixins/_tooltips.scss: -------------------------------------------------------------------------------- 1 | // Tooltip color variations 2 | 3 | @mixin tooltip-variant($color) { 4 | .tooltip-inner { 5 | background: $color; 6 | color: $white; 7 | } 8 | &.bs-tooltip-top { 9 | .arrow::before { 10 | border-top-color: $color; 11 | } 12 | } 13 | &.bs-tooltip-right { 14 | .arrow::before { 15 | border-right-color: $color; 16 | } 17 | } 18 | &.bs-tooltip-bottom { 19 | .arrow::before { 20 | border-bottom-color: $color; 21 | } 22 | } 23 | &.bs-tooltip-left { 24 | .arrow::before { 25 | border-left-color: $color; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /front-end/src/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # 5 | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed 6 | 7 | > 0.5% 8 | last 2 versions 9 | Firefox ESR 10 | not dead 11 | not IE 9-11 -------------------------------------------------------------------------------- /front-end/src/environments/constants.ts: -------------------------------------------------------------------------------- 1 | export const constants = { 2 | app_name: 'Ngx Security Starter', 3 | ls_lang: 'lang', 4 | access_token: 'access_token', 5 | home_url: '/dashboard', 6 | auth_url: '/auth/login', 7 | error_500: '/error/500/internal', 8 | error_404: '/error/404/not-found' 9 | }; 10 | -------------------------------------------------------------------------------- /front-end/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | rest_url: 'http://www.domain.com/api/', 4 | auth_url: 'http://www.domain.com/oauth/', 5 | }; 6 | -------------------------------------------------------------------------------- /front-end/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | rest_url: 'http://localhost:8000/api/', 8 | web_url: 'http://localhost:8000/', 9 | auth_url: 'http://localhost:8000/oauth/', 10 | }; 11 | 12 | /* 13 | * For easier debugging in development mode, you can import the following file 14 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 15 | * 16 | * This import should be commented out in production mode because it will have a negative impact 17 | * on performance if an error is thrown. 18 | */ 19 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 20 | -------------------------------------------------------------------------------- /front-end/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/heloufir/ngx-security-starter/3816ea33402a398c541a5f4749e5ce5eedabd094/front-end/src/favicon.ico -------------------------------------------------------------------------------- /front-end/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Ngx Security Starter 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /front-end/src/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../coverage'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; -------------------------------------------------------------------------------- /front-end/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | import 'hammerjs'; 8 | 9 | if (environment.production) { 10 | enableProdMode(); 11 | } 12 | 13 | platformBrowserDynamic().bootstrapModule(AppModule) 14 | .catch(err => console.error(err)); 15 | 16 | -------------------------------------------------------------------------------- /front-end/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /front-end/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "types": [] 6 | }, 7 | "exclude": [ 8 | "test.ts", 9 | "**/*.spec.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /front-end/src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "test.ts", 12 | "polyfills.ts" 13 | ], 14 | "include": [ 15 | "**/*.spec.ts", 16 | "**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /front-end/src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /front-end/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "src", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "module": "es2015", 9 | "moduleResolution": "node", 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "target": "es5", 13 | "typeRoots": [ 14 | "node_modules/@types" 15 | ], 16 | "paths": { 17 | "@services/*": ["app/services/*"], 18 | "@models/*": ["app/models/*"], 19 | "@app/*": ["app/*"], 20 | "@env/*": ["environments/*"], 21 | }, 22 | "lib": [ 23 | "es2017", 24 | "dom" 25 | ] 26 | } 27 | } 28 | --------------------------------------------------------------------------------