@chenpu17/tcpmapping 2.0.0 → 2.0.1
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.
- package/README.md +178 -54
- package/package.json +1 -1
- package/public/dashboard.html +388 -125
- package/public/login.html +157 -67
package/public/login.html
CHANGED
|
@@ -14,19 +14,32 @@
|
|
|
14
14
|
body {
|
|
15
15
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
16
16
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
17
|
-
height: 100vh;
|
|
17
|
+
min-height: 100vh;
|
|
18
18
|
display: flex;
|
|
19
19
|
align-items: center;
|
|
20
20
|
justify-content: center;
|
|
21
|
+
padding: 1rem;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
.login-container {
|
|
24
25
|
background: white;
|
|
25
|
-
padding:
|
|
26
|
-
border-radius:
|
|
27
|
-
box-shadow: 0
|
|
26
|
+
padding: 2.5rem;
|
|
27
|
+
border-radius: 20px;
|
|
28
|
+
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
|
|
28
29
|
width: 100%;
|
|
29
|
-
max-width:
|
|
30
|
+
max-width: 420px;
|
|
31
|
+
animation: slideUp 0.5s ease;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@keyframes slideUp {
|
|
35
|
+
from {
|
|
36
|
+
opacity: 0;
|
|
37
|
+
transform: translateY(30px);
|
|
38
|
+
}
|
|
39
|
+
to {
|
|
40
|
+
opacity: 1;
|
|
41
|
+
transform: translateY(0);
|
|
42
|
+
}
|
|
30
43
|
}
|
|
31
44
|
|
|
32
45
|
.login-header {
|
|
@@ -34,14 +47,33 @@
|
|
|
34
47
|
margin-bottom: 2rem;
|
|
35
48
|
}
|
|
36
49
|
|
|
50
|
+
.login-header .logo {
|
|
51
|
+
width: 70px;
|
|
52
|
+
height: 70px;
|
|
53
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
54
|
+
border-radius: 20px;
|
|
55
|
+
display: flex;
|
|
56
|
+
align-items: center;
|
|
57
|
+
justify-content: center;
|
|
58
|
+
margin: 0 auto 1.5rem;
|
|
59
|
+
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.login-header .logo svg {
|
|
63
|
+
width: 36px;
|
|
64
|
+
height: 36px;
|
|
65
|
+
color: white;
|
|
66
|
+
}
|
|
67
|
+
|
|
37
68
|
.login-header h1 {
|
|
38
|
-
color: #
|
|
69
|
+
color: #2d3436;
|
|
39
70
|
font-size: 24px;
|
|
71
|
+
font-weight: 700;
|
|
40
72
|
margin-bottom: 0.5rem;
|
|
41
73
|
}
|
|
42
74
|
|
|
43
75
|
.login-header p {
|
|
44
|
-
color: #
|
|
76
|
+
color: #636e72;
|
|
45
77
|
font-size: 14px;
|
|
46
78
|
}
|
|
47
79
|
|
|
@@ -52,125 +84,176 @@
|
|
|
52
84
|
.form-group label {
|
|
53
85
|
display: block;
|
|
54
86
|
margin-bottom: 0.5rem;
|
|
55
|
-
color: #
|
|
56
|
-
font-weight:
|
|
87
|
+
color: #2d3436;
|
|
88
|
+
font-weight: 600;
|
|
89
|
+
font-size: 14px;
|
|
57
90
|
}
|
|
58
91
|
|
|
59
92
|
.form-group input {
|
|
60
93
|
width: 100%;
|
|
61
|
-
padding: 0.
|
|
62
|
-
border:
|
|
63
|
-
border-radius:
|
|
64
|
-
font-size:
|
|
65
|
-
transition:
|
|
94
|
+
padding: 0.9rem 1rem;
|
|
95
|
+
border: 2px solid #e9ecef;
|
|
96
|
+
border-radius: 12px;
|
|
97
|
+
font-size: 15px;
|
|
98
|
+
transition: all 0.3s ease;
|
|
66
99
|
}
|
|
67
100
|
|
|
68
101
|
.form-group input:focus {
|
|
69
102
|
outline: none;
|
|
70
103
|
border-color: #667eea;
|
|
71
|
-
box-shadow: 0 0 0
|
|
104
|
+
box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.15);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.form-group input::placeholder {
|
|
108
|
+
color: #b2bec3;
|
|
72
109
|
}
|
|
73
110
|
|
|
74
111
|
.login-btn {
|
|
75
112
|
width: 100%;
|
|
76
|
-
padding: 0.
|
|
113
|
+
padding: 0.95rem;
|
|
77
114
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
78
115
|
color: white;
|
|
79
116
|
border: none;
|
|
80
|
-
border-radius:
|
|
117
|
+
border-radius: 12px;
|
|
81
118
|
font-size: 16px;
|
|
82
119
|
font-weight: 600;
|
|
83
120
|
cursor: pointer;
|
|
84
|
-
transition:
|
|
121
|
+
transition: all 0.3s ease;
|
|
122
|
+
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.4);
|
|
85
123
|
}
|
|
86
124
|
|
|
87
125
|
.login-btn:hover {
|
|
88
|
-
transform: translateY(-
|
|
126
|
+
transform: translateY(-3px);
|
|
127
|
+
box-shadow: 0 15px 35px rgba(102, 126, 234, 0.5);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.login-btn:active {
|
|
131
|
+
transform: translateY(-1px);
|
|
89
132
|
}
|
|
90
133
|
|
|
91
134
|
.login-btn:disabled {
|
|
92
|
-
opacity: 0.
|
|
135
|
+
opacity: 0.7;
|
|
93
136
|
cursor: not-allowed;
|
|
94
137
|
transform: none;
|
|
138
|
+
box-shadow: none;
|
|
95
139
|
}
|
|
96
140
|
|
|
97
141
|
.error-message {
|
|
98
|
-
color: #
|
|
142
|
+
color: #ee5a5a;
|
|
99
143
|
font-size: 14px;
|
|
100
|
-
margin-top:
|
|
144
|
+
margin-top: 1rem;
|
|
145
|
+
padding: 0.85rem 1rem;
|
|
146
|
+
background: #fff5f5;
|
|
147
|
+
border-radius: 10px;
|
|
101
148
|
display: none;
|
|
149
|
+
text-align: center;
|
|
102
150
|
}
|
|
103
151
|
|
|
104
152
|
.success-message {
|
|
105
|
-
color: #
|
|
153
|
+
color: #2ed573;
|
|
106
154
|
font-size: 14px;
|
|
107
|
-
margin-top:
|
|
155
|
+
margin-top: 1rem;
|
|
156
|
+
padding: 0.85rem 1rem;
|
|
157
|
+
background: #f0fff4;
|
|
158
|
+
border-radius: 10px;
|
|
108
159
|
display: none;
|
|
160
|
+
text-align: center;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.help-info {
|
|
164
|
+
background: linear-gradient(135deg, #f8f9fa 0%, #f1f3f4 100%);
|
|
165
|
+
border-radius: 12px;
|
|
166
|
+
padding: 1rem 1.25rem;
|
|
167
|
+
margin-top: 1.5rem;
|
|
168
|
+
font-size: 13px;
|
|
169
|
+
color: #636e72;
|
|
170
|
+
line-height: 1.6;
|
|
109
171
|
}
|
|
110
172
|
|
|
111
|
-
.
|
|
112
|
-
background: #
|
|
113
|
-
|
|
173
|
+
.help-info code {
|
|
174
|
+
background: #e9ecef;
|
|
175
|
+
padding: 0.2rem 0.5rem;
|
|
114
176
|
border-radius: 5px;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
color: #666;
|
|
177
|
+
font-family: 'SFMono-Regular', Consolas, monospace;
|
|
178
|
+
font-size: 12px;
|
|
179
|
+
color: #764ba2;
|
|
119
180
|
}
|
|
120
181
|
|
|
121
|
-
.
|
|
122
|
-
|
|
182
|
+
.footer {
|
|
183
|
+
text-align: center;
|
|
184
|
+
margin-top: 2rem;
|
|
185
|
+
color: rgba(255,255,255,0.7);
|
|
186
|
+
font-size: 13px;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.footer a {
|
|
190
|
+
color: rgba(255,255,255,0.9);
|
|
191
|
+
text-decoration: none;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.footer a:hover {
|
|
195
|
+
text-decoration: underline;
|
|
123
196
|
}
|
|
124
197
|
</style>
|
|
125
198
|
</head>
|
|
126
199
|
<body>
|
|
127
|
-
<div
|
|
128
|
-
<div class="login-
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
<
|
|
136
|
-
<
|
|
200
|
+
<div>
|
|
201
|
+
<div class="login-container">
|
|
202
|
+
<div class="login-header">
|
|
203
|
+
<div class="logo">
|
|
204
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
205
|
+
<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>
|
|
206
|
+
</svg>
|
|
207
|
+
</div>
|
|
208
|
+
<h1>TCP转发服务器</h1>
|
|
209
|
+
<p>管理界面登录</p>
|
|
137
210
|
</div>
|
|
138
|
-
|
|
139
|
-
<
|
|
140
|
-
<
|
|
141
|
-
|
|
211
|
+
|
|
212
|
+
<form id="loginForm">
|
|
213
|
+
<div class="form-group">
|
|
214
|
+
<label for="username">用户名</label>
|
|
215
|
+
<input type="text" id="username" name="username" placeholder="请输入用户名" required autocomplete="username">
|
|
216
|
+
</div>
|
|
217
|
+
|
|
218
|
+
<div class="form-group">
|
|
219
|
+
<label for="password">密码</label>
|
|
220
|
+
<input type="password" id="password" name="password" placeholder="请输入密码" required autocomplete="current-password">
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
<button type="submit" class="login-btn" id="loginBtn">登录</button>
|
|
224
|
+
|
|
225
|
+
<div class="error-message" id="errorMessage"></div>
|
|
226
|
+
<div class="success-message" id="successMessage"></div>
|
|
227
|
+
</form>
|
|
228
|
+
|
|
229
|
+
<div class="help-info">
|
|
230
|
+
忘记密码?运行 <code>tcpmapping setup-password</code> 或 <code>npm run reset-password</code> 重置
|
|
142
231
|
</div>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
<
|
|
147
|
-
<div class="success-message" id="successMessage"></div>
|
|
148
|
-
</form>
|
|
149
|
-
|
|
150
|
-
<div class="default-info">
|
|
151
|
-
<strong>提示:</strong><br>
|
|
152
|
-
如忘记密码,请运行 <code>npm run reset-password</code> 重置
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
<div class="footer">
|
|
235
|
+
<a href="https://github.com/chenpu17/TcpMapping" target="_blank">TcpMapping</a> - TCP端口转发服务器
|
|
153
236
|
</div>
|
|
154
237
|
</div>
|
|
155
238
|
|
|
156
239
|
<script>
|
|
157
240
|
document.getElementById('loginForm').addEventListener('submit', async (e) => {
|
|
158
241
|
e.preventDefault();
|
|
159
|
-
|
|
242
|
+
|
|
160
243
|
const loginBtn = document.getElementById('loginBtn');
|
|
161
244
|
const errorMessage = document.getElementById('errorMessage');
|
|
162
245
|
const successMessage = document.getElementById('successMessage');
|
|
163
246
|
const username = document.getElementById('username').value;
|
|
164
247
|
const password = document.getElementById('password').value;
|
|
165
|
-
|
|
248
|
+
|
|
166
249
|
// 重置消息
|
|
167
250
|
errorMessage.style.display = 'none';
|
|
168
251
|
successMessage.style.display = 'none';
|
|
169
|
-
|
|
252
|
+
|
|
170
253
|
// 禁用按钮
|
|
171
254
|
loginBtn.disabled = true;
|
|
172
255
|
loginBtn.textContent = '登录中...';
|
|
173
|
-
|
|
256
|
+
|
|
174
257
|
try {
|
|
175
258
|
const response = await fetch('/api/login', {
|
|
176
259
|
method: 'POST',
|
|
@@ -179,16 +262,16 @@
|
|
|
179
262
|
},
|
|
180
263
|
body: JSON.stringify({ username, password })
|
|
181
264
|
});
|
|
182
|
-
|
|
265
|
+
|
|
183
266
|
const data = await response.json();
|
|
184
|
-
|
|
267
|
+
|
|
185
268
|
if (data.success) {
|
|
186
|
-
successMessage.textContent =
|
|
269
|
+
successMessage.textContent = '登录成功,正在跳转...';
|
|
187
270
|
successMessage.style.display = 'block';
|
|
188
|
-
|
|
271
|
+
|
|
189
272
|
setTimeout(() => {
|
|
190
273
|
window.location.href = '/dashboard';
|
|
191
|
-
},
|
|
274
|
+
}, 800);
|
|
192
275
|
} else {
|
|
193
276
|
errorMessage.textContent = data.message;
|
|
194
277
|
errorMessage.style.display = 'block';
|
|
@@ -202,6 +285,13 @@
|
|
|
202
285
|
loginBtn.textContent = '登录';
|
|
203
286
|
}
|
|
204
287
|
});
|
|
288
|
+
|
|
289
|
+
// 回车提交
|
|
290
|
+
document.addEventListener('keypress', (e) => {
|
|
291
|
+
if (e.key === 'Enter') {
|
|
292
|
+
document.getElementById('loginForm').dispatchEvent(new Event('submit'));
|
|
293
|
+
}
|
|
294
|
+
});
|
|
205
295
|
</script>
|
|
206
296
|
</body>
|
|
207
|
-
</html>
|
|
297
|
+
</html>
|