Browse Source

20220826 reCaptcha, bootstrap 3 to 5

LuluFJ.Ho 2 years ago
parent
commit
187cfe0d10

+ 32
- 0
app/Http/Controllers/Auth/ForgotPasswordController.php View File

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
7
+
8
+class ForgotPasswordController extends Controller
9
+{
10
+    /*
11
+    |--------------------------------------------------------------------------
12
+    | Password Reset Controller
13
+    |--------------------------------------------------------------------------
14
+    |
15
+    | This controller is responsible for handling password reset emails and
16
+    | includes a trait which assists in sending these notifications from
17
+    | your application to your users. Feel free to explore this trait.
18
+    |
19
+    */
20
+
21
+    use SendsPasswordResetEmails;
22
+
23
+    /**
24
+     * Create a new controller instance.
25
+     *
26
+     * @return void
27
+     */
28
+    public function __construct()
29
+    {
30
+        $this->middleware('guest');
31
+    }
32
+}

+ 66
- 0
app/Http/Controllers/Auth/LoginController.php View File

@@ -0,0 +1,66 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Http\Request;
7
+use Illuminate\Foundation\Auth\AuthenticatesUsers;
8
+use Illuminate\Support\Facades\Auth;
9
+use Illuminate\Validation\ValidationException;
10
+use Redirect;
11
+use Session;
12
+
13
+class LoginController extends Controller
14
+{
15
+    /*
16
+    |--------------------------------------------------------------------------
17
+    | Login Controller
18
+    |--------------------------------------------------------------------------
19
+    |
20
+    | This controller handles authenticating users for the application and
21
+    | redirecting them to your home screen. The controller uses a trait
22
+    | to conveniently provide its functionality to your applications.
23
+    |
24
+    */
25
+
26
+    use AuthenticatesUsers;
27
+
28
+    /**
29
+     * Where to redirect users after login.
30
+     *
31
+     * @var string
32
+     */
33
+    protected $redirectTo = '/backend';
34
+
35
+    protected $maxAttempts = 5;
36
+    protected $decayMinutes = 10;
37
+
38
+    /**
39
+     * Create a new controller instance.
40
+     *
41
+     * @return void
42
+     */
43
+    public function __construct()
44
+    {
45
+        $this->middleware('guest', ['except' => 'logout']);
46
+    }
47
+    
48
+    protected function validateLogin(Request $request)
49
+    {
50
+        $validateRules = [
51
+            'g-recaptcha-response' => 'required',
52
+        ];
53
+
54
+        $validateMessage = [
55
+            'g-recaptcha-response.required' => '請點選我不是機器人',
56
+        ];
57
+
58
+        $request->validate($validateRules, $validateMessage);
59
+
60
+        $recaptcha = new \ReCaptcha\ReCaptcha('6LfDoKIhAAAAABrav1PgguhuAZCHgJibpDD8tbQZ');
61
+        $resp = $recaptcha->verify($request->input('g-recaptcha-response'), $request->ip());
62
+        if (!$resp->isSuccess()) {
63
+            throw ValidationException::withMessages(['error' => 'recaptcha 驗證失敗']);
64
+        }
65
+    }
66
+}

+ 71
- 0
app/Http/Controllers/Auth/RegisterController.php View File

@@ -0,0 +1,71 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\User;
6
+use App\Http\Controllers\Controller;
7
+use Illuminate\Support\Facades\Validator;
8
+use Illuminate\Foundation\Auth\RegistersUsers;
9
+
10
+class RegisterController extends Controller
11
+{
12
+    /*
13
+    |--------------------------------------------------------------------------
14
+    | Register Controller
15
+    |--------------------------------------------------------------------------
16
+    |
17
+    | This controller handles the registration of new users as well as their
18
+    | validation and creation. By default this controller uses a trait to
19
+    | provide this functionality without requiring any additional code.
20
+    |
21
+    */
22
+
23
+    use RegistersUsers;
24
+
25
+    /**
26
+     * Where to redirect users after registration.
27
+     *
28
+     * @var string
29
+     */
30
+    protected $redirectTo = '/backend';
31
+
32
+    /**
33
+     * Create a new controller instance.
34
+     *
35
+     * @return void
36
+     */
37
+    public function __construct()
38
+    {
39
+        $this->middleware('guest');
40
+    }
41
+
42
+    /**
43
+     * Get a validator for an incoming registration request.
44
+     *
45
+     * @param  array  $data
46
+     * @return \Illuminate\Contracts\Validation\Validator
47
+     */
48
+    protected function validator(array $data)
49
+    {
50
+        return Validator::make($data, [
51
+            'name' => 'required|max:255',
52
+            'email' => 'required|email|max:255|unique:users',
53
+            'password' => 'required|min:6|confirmed',
54
+        ]);
55
+    }
56
+
57
+    /**
58
+     * Create a new user instance after a valid registration.
59
+     *
60
+     * @param  array  $data
61
+     * @return User
62
+     */
63
+    protected function create(array $data)
64
+    {
65
+        return User::create([
66
+            'name' => $data['name'],
67
+            'email' => $data['email'],
68
+            'password' => bcrypt($data['password']),
69
+        ]);
70
+    }
71
+}

+ 39
- 0
app/Http/Controllers/Auth/ResetPasswordController.php View File

@@ -0,0 +1,39 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Foundation\Auth\ResetsPasswords;
7
+
8
+class ResetPasswordController extends Controller
9
+{
10
+    /*
11
+    |--------------------------------------------------------------------------
12
+    | Password Reset Controller
13
+    |--------------------------------------------------------------------------
14
+    |
15
+    | This controller is responsible for handling password reset requests
16
+    | and uses a simple trait to include this behavior. You're free to
17
+    | explore this trait and override any methods you wish to tweak.
18
+    |
19
+    */
20
+
21
+    use ResetsPasswords;
22
+
23
+    /**
24
+     * Where to redirect users after resetting their password.
25
+     *
26
+     * @var string
27
+     */
28
+    protected $redirectTo = '/backend';
29
+
30
+    /**
31
+     * Create a new controller instance.
32
+     *
33
+     * @return void
34
+     */
35
+    public function __construct()
36
+    {
37
+        $this->middleware('guest');
38
+    }
39
+}

+ 2
- 2
config/app.php View File

@@ -67,7 +67,7 @@ return [
67 67
     |
68 68
     */
69 69
 
70
-    'timezone' => 'UTC',
70
+    'timezone' => 'Asia/Taipei',
71 71
 
72 72
     /*
73 73
     |--------------------------------------------------------------------------
@@ -80,7 +80,7 @@ return [
80 80
     |
81 81
     */
82 82
 
83
-    'locale' => 'en',
83
+    'locale' => 'zh-TW',
84 84
 
85 85
     /*
86 86
     |--------------------------------------------------------------------------

+ 186
- 13
public/assets/css/bootstrap-override.css View File

@@ -138,7 +138,6 @@ h4, .h4 {
138 138
    font-size: 12px;
139 139
    padding: 7px 10px;
140 140
    height: auto;
141
-   margin-top: 3px;
142 141
 }
143 142
 
144 143
 .input-lg {
@@ -165,7 +164,7 @@ h4, .h4 {
165 164
    padding: 5px 10px;
166 165
 }
167 166
 
168
-.btn-xs {
167
+.btn-sm {
169 168
    padding: 2px 10px;
170 169
 }
171 170
 
@@ -173,16 +172,16 @@ h4, .h4 {
173 172
    padding: 12px 20px;
174 173
 }
175 174
 
176
-.btn-default {
175
+.btn-secondary {
177 176
    background: #e4e7ea;
178 177
    color: #636e7b;
179 178
 }
180 179
 
181
-.btn-default:hover,
182
-.btn-default:focus,
183
-.btn-default:active,
184
-.btn-default.active,
185
-.open .dropdown-toggle.btn-default {
180
+.btn-secondary:hover,
181
+.btn-secondary:focus,
182
+.btn-secondary:active,
183
+.btn-secondary.active,
184
+.open .dropdown-toggle.btn-secondary {
186 185
    background: #f7f7f7;
187 186
    border-color: #ccc;
188 187
    -moz-box-shadow: none;
@@ -228,7 +227,7 @@ h4, .h4 {
228 227
    background: #f7f7f7;
229 228
 }
230 229
 
231
-.btn-default-alt {
230
+.btn-secondary-alt {
232 231
    border: 2px solid #999;
233 232
    color: #999;
234 233
    text-transform: uppercase;
@@ -236,9 +235,9 @@ h4, .h4 {
236 235
    font-size: 12px;
237 236
 }
238 237
 
239
-.btn-default-alt:hover,
240
-.btn-default-alt:active,
241
-.btn-default-alt:focus {
238
+.btn-secondary-alt:hover,
239
+.btn-secondary-alt:active,
240
+.btn-secondary-alt:focus {
242 241
    border-color: #666;
243 242
    color: #666;
244 243
 }
@@ -575,10 +574,18 @@ h4, .h4 {
575 574
    box-shadow: 0 3px 0 rgba(12,12,12,0.03);
576 575
 }
577 576
 
577
+.panel-footer {
578
+   padding: 10px 15px;
579
+   background-color: #f5f5f5;
580
+   border-top: 1px solid #ddd;
581
+   border-bottom-right-radius: 3px;
582
+   border-bottom-left-radius: 3px;
583
+}
584
+
578 585
 .panel-heading,
579 586
 .panel-footer {
580 587
    background: #fff;
581
-   border-color: #eee;
588
+   /*border-color: #eee;*/
582 589
 }
583 590
 
584 591
 .panel-heading {
@@ -1044,6 +1051,18 @@ h4, .h4 {
1044 1051
    color: #fff;
1045 1052
 }
1046 1053
 
1054
+.nav-primary {
1055
+    background: #428BCA;
1056
+ }
1057
+ 
1058
+ .nav-primary > li > a {
1059
+    color: #fff;
1060
+ }
1061
+ 
1062
+ .nav-primary > li > a:hover {
1063
+    color: #1d2939;
1064
+ }
1065
+
1047 1066
 .nav-tabs.nav-justified > li > a {
1048 1067
    border-bottom: 0;
1049 1068
 }
@@ -1308,3 +1327,157 @@ small.media-desc {
1308 1327
    -webkit-box-shadow: none;
1309 1328
    box-shadow: none;
1310 1329
 }
1330
+
1331
+
1332
+
1333
+
1334
+/* add by Yong reference bootstrap3 */
1335
+.btn-group-vertical>.btn-group:after, .btn-group-vertical>.btn-group:before, .btn-toolbar:after, .btn-toolbar:before, .clearfix:after, .clearfix:before, .container-fluid:after, .container-fluid:before, .container:after, .container:before, .dl-horizontal dd:after, .dl-horizontal dd:before, .form-horizontal .form-group:after, .form-horizontal .form-group:before, .modal-footer:after, .modal-footer:before, ._nav:after, ._nav:before, .navbar-collapse:after, .navbar-collapse:before, .navbar-header:after, .navbar-header:before, .navbar:after, .navbar:before, .pager:after, .pager:before, .panel-body:after, .panel-body:before, .row:after, .row:before {
1336
+   display: table;
1337
+   content: " ";
1338
+}
1339
+
1340
+@font-face {
1341
+   font-family: 'Glyphicons Halflings';
1342
+
1343
+   src: url('../fonts/glyphicons-halflings-regular.eot');
1344
+   src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
1345
+}
1346
+._glyphicon {
1347
+   position: relative;
1348
+   top: 1px;
1349
+   display: inline-block;
1350
+   font-family: 'Glyphicons Halflings';
1351
+   font-style: normal;
1352
+   font-weight: normal;
1353
+   line-height: 1;
1354
+
1355
+   -webkit-font-smoothing: antialiased;
1356
+   -moz-osx-font-smoothing: grayscale;
1357
+}
1358
+._glyphicon-log-out:before {
1359
+   content: "\e163";
1360
+}
1361
+._glyphicon-search:before {
1362
+   content: "\e003";
1363
+}
1364
+._glyphicon-pencil:before {
1365
+   content: "\270f";
1366
+}
1367
+._glyphicon-calendar:before {
1368
+   content: "\e109";
1369
+}
1370
+._glyphicon-plus:before {
1371
+   content: "\2b";
1372
+}
1373
+._glyphicon-minus:before {
1374
+   content: "\2212";
1375
+}
1376
+._glyphicon-alert:before {
1377
+   content: "\e209";
1378
+}
1379
+._glyphicon-tag:before {
1380
+   content: "\e041";
1381
+}
1382
+._glyphicon-remove:before {
1383
+   content: "\e014";
1384
+}
1385
+._glyphicon-pencil:before {
1386
+   content: "\270f";
1387
+}
1388
+._glyphicon-book:before {
1389
+   content: "\e043";
1390
+}
1391
+._glyphicon-user:before {
1392
+   content: "\e008";
1393
+}
1394
+._glyphicon-log-out:before {
1395
+   content: "\e163";
1396
+}
1397
+._glyphicon-object-align-vertical:before {
1398
+   content: "\e248";
1399
+}
1400
+._glyphicon-bullhorn:before {
1401
+   content: "\e122";
1402
+}
1403
+._glyphicon-list:before {
1404
+   content: "\e056";
1405
+}
1406
+._glyphicon-ok:before {
1407
+   content: "\e013";
1408
+}
1409
+._glyphicon-edit:before {
1410
+   content: "\e065";
1411
+}
1412
+._glyphicon-eye-open:before {
1413
+   content: "\e105";
1414
+}
1415
+._glyphicon-eye-close:before {
1416
+   content: "\e106";
1417
+}
1418
+
1419
+
1420
+
1421
+._nav {
1422
+   padding-left: 0;
1423
+   margin-bottom: 0;
1424
+   list-style: none;
1425
+}
1426
+._nav-pills>li {
1427
+   float: left;
1428
+}
1429
+._nav-stacked>li {
1430
+   float: none;
1431
+}
1432
+._nav>li {
1433
+   position: relative;
1434
+   display: block;
1435
+}
1436
+._nav>li>a {
1437
+   position: relative;
1438
+   display: block;
1439
+   padding: 10px 15px;
1440
+}
1441
+
1442
+
1443
+
1444
+._panel-heading {
1445
+   border-bottom: 1px solid transparent;
1446
+   border-top-left-radius: 3px;
1447
+   border-top-right-radius: 3px;
1448
+}
1449
+
1450
+._panel-primary>._panel-heading {
1451
+   color: #fff;
1452
+   background-color: #337ab7;
1453
+   border-color: #337ab7;
1454
+}
1455
+
1456
+._panel-primary .panel-title, .panel-success .panel-title, .panel-warning .panel-title, .panel-danger .panel-title, .panel-info .panel-title, .panel-dark .panel-title {
1457
+   color: #fff;
1458
+}
1459
+
1460
+._form-group {
1461
+   margin-bottom: 15px;
1462
+}
1463
+
1464
+a {
1465
+   color: #337ab7;
1466
+   text-decoration: none;
1467
+}
1468
+
1469
+._btn-info {
1470
+   color: #fff;
1471
+   background-color: #5bc0de;
1472
+   border-color: #46b8da;
1473
+}
1474
+
1475
+._btn-warning {
1476
+   color: #fff;
1477
+   background-color: #f0ad4e;
1478
+   border-color: #eea236;
1479
+}
1480
+
1481
+._fz-12 {
1482
+   font-size: 12px;
1483
+}

public/assets/css/bootstrap.min.css → public/assets/css/bootstrap.min.v3.css View File


+ 7
- 0
public/assets/css/bootstrap.min.v5.css
File diff suppressed because it is too large
View File


+ 4614
- 0
public/assets/css/style.default.v3.css
File diff suppressed because it is too large
View File


+ 4614
- 0
public/assets/css/style.default.v5.css
File diff suppressed because it is too large
View File


+ 7
- 0
public/assets/js/bootstrap.bundle.min.v5.js
File diff suppressed because it is too large
View File


+ 4412
- 1713
public/assets/js/bootstrap.js
File diff suppressed because it is too large
View File


public/assets/js/bootstrap.min.js → public/assets/js/bootstrap.min.v3.js View File


+ 7
- 0
public/assets/js/bootstrap.min.v5.js
File diff suppressed because it is too large
View File


+ 5016
- 0
public/assets/js/bootstrapV3.js
File diff suppressed because it is too large
View File


+ 5
- 1
resources/views/admin/uc/foot.blade.php View File

@@ -1,4 +1,8 @@
1
-<script src="{{url('assets/js/bootstrap.min.js')}}"></script>
1
++@if (request('v') == 3)
2
++    <script src="{{url('assets/js/bootstrap.min.v3.js')}}"></script>
3
++@else
4
++    <script src="{{url('assets/js/bootstrap.bundle.min.v5.js')}}"></script>
5
++@endif
2 6
 <script src="{{url('assets/js/modernizr.min.js')}}"></script>
3 7
 <script src="{{url('assets/js/jquery.sparkline.min.js')}}"></script>
4 8
 <script src="{{url('assets/js/toggles.min.js')}}"></script>

+ 3
- 1
resources/views/admin/uc/head.blade.php View File

@@ -3,7 +3,9 @@
3 3
 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
4 4
 <link rel="shortcut icon" href="{{url('assets/images/favicon.png')}}" type="image/png" />
5 5
 <title>{{ env('APP_NAME') }}</title>
6
-<link rel="Stylesheet" type="text/css" href="{{url('assets/css/style.default.css')}}"/>
6
+
7
+<link rel="Stylesheet" type="text/css" href="{{ asset('assets/css/style.default.v5.css') }}"/>  
8
+
7 9
 <!--<link rel="Stylesheet" type="text/css" href="{{url('assets/css/style.darkknight.css')}}"/>-->
8 10
 <script src="{{url('assets/js/jquery-1.11.1.min.js')}}"></script>
9 11
 <script src="{{url('assets/js/jquery-migrate-1.2.1.min.js')}}"></script>

+ 6
- 6
resources/views/admin/uc/leftmenu.blade.php View File

@@ -14,15 +14,15 @@
14 14
 				</div>
15 15
 			</div>
16 16
 		</div>
17
-        <h5 class="sidebartitle">Navigation</h5>
18
-		<ul id="navLeftMenu" class="nav nav-pills nav-stacked nav-bracket">
17
+        <h5 class="sidebartitle mt-2">Navigation</h5>
18
+		<ul id="navLeftMenu" class="_nav _nav-pills _nav-stacked nav-bracket">
19 19
 			<!-- 選單區段 -->
20
-			<li class='nav-link' id="Dashboard"><a href='{{ url('backend/') }}' class="dashboard"><i class='fa fa-dashboard'></i><span>DashBoard</span></a></li>
20
+			<li class='' id="Dashboard"><a href='{{ url('backend/') }}' class="dashboard text-decoration-none"><i class='fa fa-dashboard'></i><span>Dashboard</span></a></li>
21 21
             @foreach($leftmenu as $data)
22
-                <li class='nav-parent'><a href='' class='parent-name'><i class='{{ $data->icon }}'></i><span>{{ $data->menuname }}</span></a><ul class='children'>
22
+                <li class='nav-parent'><a href='' class='parent-name text-decoration-none'><i class='{{ $data->icon }}'></i><span>{{ $data->menuname }}</span></a><ul class='children'>
23 23
                 @for($i = 0; $i< count(explode(",",$data->submenuname)); $i++)
24 24
                     <li id='{{ str_replace("/", "_", explode(",",$data->submenulink)[$i]) }}' data-level='two'>
25
-                        <a href='{{ url('backend/'.explode(",",$data->submenulink)[$i]) }}'>
25
+                        <a class="text-decoration-none" href='{{ url('backend/'.explode(",",$data->submenulink)[$i]) }}'>
26 26
                             <i class='fa fa-caret-right'></i>
27 27
                             <span>{{ explode(",",$data->submenuname)[$i] }}</span>
28 28
                         </a>
@@ -33,4 +33,4 @@
33 33
 		</ul>
34 34
 	</div>
35 35
 	<!-- leftpanelinner -->
36
-</div>
36
+</div>

+ 15
- 3
resources/views/auth/login.blade.php View File

@@ -4,6 +4,16 @@
4 4
 		@include('admin.uc.head')
5 5
 	</head>
6 6
 	<body class="signin">
7
+	@if ($errors->any())
8
+		<div class="alert alert-danger">
9
+			<ul>
10
+				@foreach ($errors->all() as $error)
11
+					<li>{{ $error }}</li>
12
+				@endforeach
13
+			</ul>
14
+		</div>
15
+	@endif
16
+
7 17
 		<section>
8 18
 			<div class="signinpanel">
9 19
 				<div class="row">
@@ -17,13 +27,15 @@
17 27
 							<label class="error" for="email"></label>
18 28
 							<input id="qpassword" name="password" placeholder="Password" class="form-control pword" maxlength="20" type="password" />
19 29
 							<label class="error" for="password"></label>
30
+							<br>
31
+							<div>
32
+								<div id="recaptcha" class="g-recaptcha" data-sitekey="6LfvggUgAAAAALUwCxdJd372UNW3xrMrVfgNJEOF"></div>
33
+							</div>
20 34
 							<input id="btnSignIn" name="btnSignIn" value="Login" class="btn btn-block btn-success" type="submit" onclick="submitForm();" />
21 35
 						</form>
22 36
 					</div>
23 37
 					<div class="col-md-3"></div>
24
-					<!-- col-sm-5 -->
25 38
 				</div>
26
-				<!-- row -->
27 39
 				<div class="signup-footer">
28 40
 					<div class="pull-left">
29 41
 						<?php echo env('COPY_RIGHT')?>
@@ -33,10 +45,10 @@
33 45
 					</div>
34 46
 				</div>
35 47
 			</div>
36
-			<!-- signin -->
37 48
 		</section>
38 49
 		@include('admin.uc.foot')
39 50
 		<!-- 表單JS -->
51
+		<script src="https://www.google.com/recaptcha/api.js" async defer></script>
40 52
 		<script>
41 53
 			//逐個偵錯
42 54
 			$(function () {