@flun/html-template 4.4.1 → 4.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -241,16 +241,28 @@ export const accountRouter = app => {
241
241
  if (publicPaths.some(p => req.path.startsWith(p))) return next();
242
242
  if (!req.session.userId) {
243
243
  if (req.path.startsWith('/api/')) return res.status(401).json({ message: '请先登录' });
244
- return req.session.returnTo = req.originalUrl, res.redirect('/login');
244
+ req.session.returnTo = req.originalUrl;
245
+ return res.redirect('/login');
245
246
  }
246
247
 
248
+ const currentUser = getCurrentUser(req);
249
+ if (!currentUser) {
250
+ req.session.destroy(() => {
251
+ if (req.path.startsWith('/api/')) return res.status(401).json({ message: '用户不存在或已失效' });
252
+ return res.redirect('/login');
253
+ });
254
+ return;
255
+ }
256
+
257
+ const { user } = currentUser;
247
258
  // 检查密码是否在本次登录后被修改
248
- const { user } = getCurrentUser(req);
249
259
  if (user?.passwordChangedAt) {
250
260
  const sessionLoginTime = req.session.loginTime || 0;
251
261
  if (user.passwordChangedAt > sessionLoginTime) {
252
262
  req.session.destroy(() => {
253
- if (req.path.startsWith('/api/')) return res.status(401).json({ message: '密码已修改,请重新登录' });
263
+ if (req.path.startsWith('/api/')) {
264
+ return res.status(401).json({ message: '密码已修改,请重新登录' });
265
+ }
254
266
  return res.redirect('/login');
255
267
  });
256
268
  return;
package/f-CHANGELOG.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # 变更日志
2
- ## [4.4.1] - 2026-05-31 14:39
3
- ### 优化
4
- - 删除了 customize/routes.js 文件中上一次优化造成的冗余路由;
5
- ## [4.4.0] - 2026-05-31 14:25
2
+ ## [4.4.3] - 2026-06-05 22:16
6
3
  ### 优化
7
- - 修改辅助功能(在线编辑css文件)中预览逻辑:删除单预览按钮,增加上、下、左、右和单页面预览按钮,及相关逻辑的全面优化,让体验更好;
8
- ## [4.3.1] - 2026-05-30 11:42
4
+ - 模板中用户页面的移动端样式适配;
5
+ ## [4.4.2] - 2026-05-31 15:08
6
+ ### 修复
7
+ - 修复全局中间件中 `getCurrentUser(req)` 返回 `null` 时解构报错导致服务崩溃的问题,增加空值判断并自动清理无效登录态;
8
+ ## [4.4.1] - 2026-05-31 14:39
9
9
  ### 优化
10
- - https启用成功后,不在打印证书路径,只给出成功提示;
10
+ - 删除了 customize/routes.js 文件中上一次优化造成的冗余路由;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flun/html-template",
3
- "version": "4.4.1",
3
+ "version": "4.4.3",
4
4
  "description": "一个HTML模板工具包,提供开发服务器和模板编译功能,支持自定义标签和快捷输入,变量定义,包含文件引用,帮助开发者模块化处理HTML;",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -126,6 +126,61 @@
126
126
  color: var(--link-hover);
127
127
  text-decoration: underline;
128
128
  }
129
+
130
+ /* ==================== 移动端样式适配 (≤640px) ==================== */
131
+ @media (max-width: 640px) {
132
+ body {
133
+ padding: 16px;
134
+ }
135
+
136
+ .card {
137
+ max-width: 100%;
138
+ padding: 28px 20px;
139
+ border-radius: 16px;
140
+ }
141
+
142
+ .card h2 {
143
+ font-size: 24px;
144
+ margin-bottom: 16px;
145
+ }
146
+
147
+ .card p {
148
+ font-size: 14px;
149
+ margin-bottom: 16px;
150
+ }
151
+
152
+ .form-group input {
153
+ font-size: 16px;
154
+ /* 防止iOS缩放 */
155
+ padding: 12px 12px;
156
+ letter-spacing: 2px;
157
+ }
158
+
159
+ .btn {
160
+ padding: 12px;
161
+ font-size: 16px;
162
+ }
163
+
164
+ .backup-link {
165
+ font-size: 13px;
166
+ margin-top: 18px;
167
+ }
168
+ }
169
+
170
+ /* 极小屏幕 (≤480px) 进一步微调 */
171
+ @media (max-width: 480px) {
172
+ .card {
173
+ padding: 24px 16px;
174
+ }
175
+
176
+ .card h2 {
177
+ font-size: 22px;
178
+ }
179
+
180
+ .form-group input {
181
+ padding: 10px 10px;
182
+ }
183
+ }
129
184
  </style>
130
185
  </head>
131
186
 
@@ -132,6 +132,56 @@
132
132
  .hidden {
133
133
  display: none;
134
134
  }
135
+
136
+ /* ==================== 移动端样式适配 (≤640px) ==================== */
137
+ @media (max-width: 640px) {
138
+ body {
139
+ padding: 16px;
140
+ }
141
+
142
+ .card {
143
+ max-width: 100%;
144
+ padding: 28px 20px;
145
+ border-radius: 16px;
146
+ }
147
+
148
+ .card h2 {
149
+ font-size: 24px;
150
+ margin-bottom: 8px;
151
+ }
152
+
153
+ .card p {
154
+ font-size: 13px;
155
+ margin-bottom: 24px;
156
+ }
157
+
158
+ .form-group input {
159
+ font-size: 16px;
160
+ /* 防止iOS缩放 */
161
+ padding: 12px 14px;
162
+ }
163
+
164
+ .btn {
165
+ padding: 12px;
166
+ font-size: 16px;
167
+ }
168
+
169
+ .links {
170
+ font-size: 13px;
171
+ margin-top: 20px;
172
+ }
173
+ }
174
+
175
+ /* 极小屏幕 (≤480px) 微调 */
176
+ @media (max-width: 480px) {
177
+ .card {
178
+ padding: 24px 16px;
179
+ }
180
+
181
+ .card h2 {
182
+ font-size: 22px;
183
+ }
184
+ }
135
185
  </style>
136
186
  </head>
137
187
 
@@ -127,6 +127,70 @@
127
127
  color: var(--link-hover);
128
128
  text-decoration: underline;
129
129
  }
130
+
131
+ /* ==================== 移动端样式适配 (≤640px) ==================== */
132
+ @media (max-width: 640px) {
133
+ body {
134
+ padding: 16px;
135
+ }
136
+
137
+ .card {
138
+ max-width: 100%;
139
+ padding: 28px 20px;
140
+ border-radius: 16px;
141
+ }
142
+
143
+ .card h2 {
144
+ font-size: 24px;
145
+ margin-bottom: 24px;
146
+ }
147
+
148
+ .form-group {
149
+ margin-bottom: 18px;
150
+ }
151
+
152
+ .form-group label {
153
+ font-size: 13px;
154
+ margin-bottom: 6px;
155
+ }
156
+
157
+ .form-group input {
158
+ font-size: 16px;
159
+ /* 防止iOS缩放 */
160
+ padding: 12px 14px;
161
+ }
162
+
163
+ .btn {
164
+ padding: 12px;
165
+ font-size: 16px;
166
+ }
167
+
168
+ .links {
169
+ margin-top: 20px;
170
+ font-size: 13px;
171
+ }
172
+
173
+ .links a {
174
+ margin: 0 8px;
175
+ }
176
+ }
177
+
178
+ /* 极小屏幕 (≤480px) 微调 */
179
+ @media (max-width: 480px) {
180
+ .card {
181
+ padding: 24px 16px;
182
+ }
183
+
184
+ .card h2 {
185
+ font-size: 22px;
186
+ margin-bottom: 20px;
187
+ }
188
+
189
+ .links a {
190
+ display: inline-block;
191
+ margin: 4px 6px;
192
+ }
193
+ }
130
194
  </style>
131
195
  </head>
132
196
 
@@ -3,7 +3,7 @@
3
3
 
4
4
  <head>
5
5
  <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
7
7
  <title>个人资料 - 安全账户中心</title>
8
8
 
9
9
  <!-- 引入公共主题变量与全局样式 -->
@@ -13,6 +13,7 @@
13
13
  <link rel="stylesheet" href="/static/topImg.css" /> <!-- 返回顶部图标 -->
14
14
 
15
15
  <style>
16
+ /* ========== 基础移动优先增强 ========== */
16
17
  body {
17
18
  background: var(--body-bg);
18
19
  background-color: var(--bg-color);
@@ -82,6 +83,7 @@
82
83
  .info-value {
83
84
  flex: 1;
84
85
  color: var(--text-color);
86
+ word-break: break-word;
85
87
  }
86
88
 
87
89
  /* 通用按钮 */
@@ -96,6 +98,11 @@
96
98
  cursor: pointer;
97
99
  transition: background 0.2s, opacity 0.2s;
98
100
  margin-right: 10px;
101
+ text-align: center;
102
+ display: inline-flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ gap: 6px;
99
106
  }
100
107
 
101
108
  .btn:hover {
@@ -215,6 +222,7 @@
215
222
  background: var(--li-bg);
216
223
  color: var(--text-color);
217
224
  transition: border-color 0.2s, background 0.5s ease, color 0.5s ease;
225
+ box-sizing: border-box;
218
226
  }
219
227
 
220
228
  .form-group input:focus {
@@ -285,6 +293,7 @@
285
293
  display: flex;
286
294
  align-items: center;
287
295
  gap: 8px;
296
+ word-break: break-word;
288
297
  }
289
298
 
290
299
  .btn-small {
@@ -347,6 +356,235 @@
347
356
  color: #666;
348
357
  }
349
358
  }
359
+
360
+ /* ==================== 移动端样式适配 (≤640px) ==================== */
361
+ @media (max-width: 640px) {
362
+ body {
363
+ padding: 16px 12px;
364
+ }
365
+
366
+ .container {
367
+ max-width: 100%;
368
+ padding: 0;
369
+ }
370
+
371
+ .card {
372
+ padding: 20px 16px;
373
+ border-radius: 16px;
374
+ margin-bottom: 16px;
375
+ }
376
+
377
+ .card h2 {
378
+ font-size: 20px;
379
+ margin-bottom: 16px;
380
+ gap: 8px;
381
+ }
382
+
383
+ .card h2 .btn {
384
+ font-size: 12px;
385
+ padding: 6px 12px;
386
+ white-space: nowrap;
387
+ }
388
+
389
+ /* 信息行改为垂直布局,更易阅读 */
390
+ .info-row {
391
+ flex-direction: column;
392
+ padding: 12px 0;
393
+ }
394
+
395
+ .info-label {
396
+ width: auto;
397
+ margin-bottom: 6px;
398
+ font-weight: 600;
399
+ opacity: 0.8;
400
+ }
401
+
402
+ .info-value {
403
+ width: 100%;
404
+ font-size: 15px;
405
+ }
406
+
407
+ /* 主要操作按钮组 垂直排列 */
408
+ .action-buttons {
409
+ flex-direction: column;
410
+ gap: 12px;
411
+ }
412
+
413
+ .action-buttons .btn {
414
+ width: 100%;
415
+ margin-right: 0;
416
+ justify-content: center;
417
+ padding: 12px 16px;
418
+ font-size: 15px;
419
+ }
420
+
421
+ /* 所有内联 flex 按钮组(修改资料/修改密码/删除账户)强制垂直 + 全宽 */
422
+ #editProfileCard>form>div:first-of-type,
423
+ #changePasswordCard>form>div:first-of-type,
424
+ #deleteAccountForm>div:first-of-type {
425
+ flex-direction: column !important;
426
+ gap: 12px !important;
427
+ width: 100%;
428
+ }
429
+
430
+ #editProfileCard>form>div:first-of-type .btn,
431
+ #changePasswordCard>form>div:first-of-type .btn,
432
+ #deleteAccountForm>div:first-of-type .btn {
433
+ width: 100% !important;
434
+ margin-right: 0 !important;
435
+ margin-left: 0 !important;
436
+ box-sizing: border-box;
437
+ }
438
+
439
+ /* 双因素启用面板的按钮组 (flex-buttons) */
440
+ .flex-buttons {
441
+ flex-direction: column;
442
+ gap: 12px;
443
+ }
444
+
445
+ .flex-buttons .btn {
446
+ width: 100%;
447
+ margin-right: 0;
448
+ }
449
+
450
+ /* 备用码管理面板按钮组垂直排列 */
451
+ .backup-actions {
452
+ flex-direction: column;
453
+ gap: 12px;
454
+ }
455
+
456
+ .backup-actions .btn {
457
+ width: 100%;
458
+ margin-right: 0;
459
+ }
460
+
461
+ /* 硬件验证设备列表 手机端改为垂直紧凑 */
462
+ .device-item {
463
+ flex-direction: column;
464
+ align-items: flex-start;
465
+ gap: 12px;
466
+ padding: 12px 6px;
467
+ }
468
+
469
+ .device-name {
470
+ width: 100%;
471
+ font-size: 14px;
472
+ }
473
+
474
+ .device-item .btn-small {
475
+ align-self: flex-start;
476
+ margin-top: 4px;
477
+ min-width: 80px;
478
+ }
479
+
480
+ /* 二维码适配移动屏幕 */
481
+ .qr-placeholder img {
482
+ max-width: 160px;
483
+ width: 100%;
484
+ height: auto;
485
+ }
486
+
487
+ /* 备用码列表展示优化 */
488
+ .backup-codes {
489
+ padding: 12px;
490
+ text-align: center;
491
+ }
492
+
493
+ .code-item {
494
+ display: inline-block;
495
+ font-size: 14px;
496
+ padding: 6px 10px;
497
+ margin: 6px 4px;
498
+ letter-spacing: 0.5px;
499
+ }
500
+
501
+ /* 表单输入框提升字体 ≥16px 避免 IOS 缩放 */
502
+ .form-group input,
503
+ input[type="text"],
504
+ input[type="email"],
505
+ input[type="password"] {
506
+ font-size: 16px;
507
+ padding: 12px 12px;
508
+ }
509
+
510
+ /* 加宽可点击区域 */
511
+ .btn {
512
+ min-height: 44px;
513
+ padding: 10px 16px;
514
+ }
515
+
516
+ /* 双因素认证 h2 内部按钮优化宽度 */
517
+ #twofaCard h2 .btn {
518
+ white-space: normal;
519
+ word-break: keep-all;
520
+ }
521
+
522
+ /* 管理面板内添加设备按钮自适应 */
523
+ #manageAddDeviceBtn {
524
+ width: 100%;
525
+ justify-content: center;
526
+ }
527
+
528
+ /* 注销账户区块调整间距 */
529
+ #deleteAccountForm {
530
+ margin-top: 4px;
531
+ }
532
+
533
+ /* 硬件验证消息容器内边距 */
534
+ .webauthn-panel {
535
+ margin-top: 12px;
536
+ }
537
+
538
+ /* 备用码生成区域文案 */
539
+ #backupCodesPanel p.info {
540
+ font-size: 13px;
541
+ }
542
+
543
+ /* secret 密钥区域长文本换行 */
544
+ code#secretCode {
545
+ word-break: break-all;
546
+ display: inline-block;
547
+ max-width: 100%;
548
+ }
549
+ }
550
+
551
+ /* 针对极小屏幕 (≤480px) 微调边距 */
552
+ @media (max-width: 480px) {
553
+ body {
554
+ padding: 12px 10px;
555
+ }
556
+
557
+ .card {
558
+ padding: 16px 14px;
559
+ }
560
+
561
+ .card h2 {
562
+ font-size: 18px;
563
+ gap: 6px;
564
+ }
565
+
566
+ .info-label {
567
+ font-size: 13px;
568
+ }
569
+
570
+ .info-value {
571
+ font-size: 14px;
572
+ }
573
+
574
+ .btn {
575
+ font-size: 14px;
576
+ padding: 10px 12px;
577
+ }
578
+
579
+ .code-item {
580
+ font-size: 13px;
581
+ padding: 5px 8px;
582
+ }
583
+
584
+ .qr-placeholder img {
585
+ max-width: 140px;
586
+ }
587
+ }
350
588
  </style>
351
589
  </head>
352
590
 
@@ -133,6 +133,61 @@
133
133
  .hidden {
134
134
  display: none;
135
135
  }
136
+
137
+ /* ==================== 移动端样式适配 (≤640px) ==================== */
138
+ @media (max-width: 640px) {
139
+ body {
140
+ padding: 16px;
141
+ }
142
+
143
+ .card {
144
+ max-width: 100%;
145
+ padding: 28px 20px;
146
+ border-radius: 16px;
147
+ }
148
+
149
+ .card h2 {
150
+ font-size: 24px;
151
+ margin-bottom: 24px;
152
+ }
153
+
154
+ .form-group {
155
+ margin-bottom: 18px;
156
+ }
157
+
158
+ .form-group label {
159
+ font-size: 13px;
160
+ margin-bottom: 6px;
161
+ }
162
+
163
+ .form-group input {
164
+ font-size: 16px;
165
+ /* 防止iOS缩放 */
166
+ padding: 12px 14px;
167
+ }
168
+
169
+ .btn {
170
+ padding: 12px;
171
+ font-size: 16px;
172
+ }
173
+
174
+ .links {
175
+ margin-top: 20px;
176
+ font-size: 13px;
177
+ }
178
+ }
179
+
180
+ /* 极小屏幕 (≤480px) 微调 */
181
+ @media (max-width: 480px) {
182
+ .card {
183
+ padding: 24px 16px;
184
+ }
185
+
186
+ .card h2 {
187
+ font-size: 22px;
188
+ margin-bottom: 20px;
189
+ }
190
+ }
136
191
  </style>
137
192
  </head>
138
193
 
@@ -134,6 +134,57 @@
134
134
  .hidden {
135
135
  display: none;
136
136
  }
137
+
138
+ /* ==================== 移动端样式适配 (≤640px) ==================== */
139
+ @media (max-width: 640px) {
140
+ body {
141
+ padding: 16px;
142
+ }
143
+
144
+ .card {
145
+ width: 100%;
146
+ min-width: auto;
147
+ padding: 28px 20px;
148
+ border-radius: 16px;
149
+ }
150
+
151
+ .card h2 {
152
+ font-size: 24px;
153
+ margin-bottom: 24px;
154
+ }
155
+
156
+ .form-group input {
157
+ font-size: 16px;
158
+ /* 防止iOS缩放 */
159
+ padding: 12px 14px;
160
+ }
161
+
162
+ .btn {
163
+ padding: 12px;
164
+ font-size: 16px;
165
+ }
166
+
167
+ .big-success {
168
+ font-size: 24px;
169
+ margin: 30px 0;
170
+ }
171
+ }
172
+
173
+ /* 极小屏幕 (≤480px) 微调 */
174
+ @media (max-width: 480px) {
175
+ .card {
176
+ padding: 24px 16px;
177
+ }
178
+
179
+ .card h2 {
180
+ font-size: 22px;
181
+ margin-bottom: 20px;
182
+ }
183
+
184
+ .big-success {
185
+ font-size: 20px;
186
+ }
187
+ }
137
188
  </style>
138
189
  </head>
139
190
 
@@ -104,6 +104,60 @@
104
104
  .hidden {
105
105
  display: none;
106
106
  }
107
+
108
+ /* ==================== 移动端样式适配 (≤640px) ==================== */
109
+ @media (max-width: 640px) {
110
+ body {
111
+ padding: 16px;
112
+ }
113
+
114
+ .card {
115
+ width: 100%;
116
+ min-width: auto;
117
+ padding: 28px 20px;
118
+ border-radius: 16px;
119
+ }
120
+
121
+ .card h2 {
122
+ font-size: 24px;
123
+ margin-bottom: 16px;
124
+ }
125
+
126
+ .message {
127
+ font-size: 14px;
128
+ margin: 16px 0;
129
+ }
130
+
131
+ .big-success {
132
+ font-size: 24px;
133
+ margin: 30px 0;
134
+ white-space: normal;
135
+ }
136
+
137
+ .btn {
138
+ padding: 10px 20px;
139
+ font-size: 15px;
140
+ }
141
+
142
+ .link {
143
+ font-size: 13px;
144
+ }
145
+ }
146
+
147
+ /* 极小屏幕 (≤480px) 微调 */
148
+ @media (max-width: 480px) {
149
+ .card {
150
+ padding: 24px 16px;
151
+ }
152
+
153
+ .card h2 {
154
+ font-size: 22px;
155
+ }
156
+
157
+ .big-success {
158
+ font-size: 20px;
159
+ }
160
+ }
107
161
  </style>
108
162
  </head>
109
163