@dsh-plus/access-gate 0.2.4 → 0.3.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/lib/client.js +119 -41
- package/lib/index.d.ts +10 -0
- package/lib/index.js +231 -5
- package/lib/style.css +72 -72
- package/package.json +10 -10
- package/src/client/card.tsx +24 -0
- package/src/client/i18n.ts +14 -0
- package/src/config.ts +7 -0
- package/src/cookie.ts +208 -0
- package/src/decision.ts +12 -4
- package/src/index.ts +52 -1
- package/src/interceptor.ts +81 -2
- package/src/routes.ts +4 -0
package/lib/style.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.
|
|
1
|
+
.nVxsMW_block {
|
|
2
2
|
--dsl-diff-radius: 12px;
|
|
3
3
|
--dsl-diff-line-height: 22px;
|
|
4
4
|
color: var(--dsw-alias-label-primary);
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
position: relative;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
.
|
|
11
|
+
.nVxsMW_copyButton {
|
|
12
12
|
z-index: 1;
|
|
13
13
|
color: var(--dsw-alias-label-secondary);
|
|
14
14
|
cursor: pointer;
|
|
@@ -22,46 +22,46 @@
|
|
|
22
22
|
right: 12px;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
.
|
|
25
|
+
.nVxsMW_body {
|
|
26
26
|
font: var(--dsw-font-markdown-code-block);
|
|
27
27
|
padding: 12px 14px;
|
|
28
28
|
overflow: auto hidden;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
.
|
|
31
|
+
.nVxsMW_line {
|
|
32
32
|
min-height: var(--dsl-diff-line-height);
|
|
33
33
|
white-space: pre;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
.
|
|
36
|
+
.nVxsMW_path {
|
|
37
37
|
color: var(--dsw-alias-label-primary);
|
|
38
38
|
padding-right: 56px;
|
|
39
39
|
font-weight: 600;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
.
|
|
42
|
+
.nVxsMW_gap {
|
|
43
43
|
color: var(--dsw-alias-label-tertiary);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
.
|
|
46
|
+
.nVxsMW_del:before {
|
|
47
47
|
content: "- ";
|
|
48
48
|
color: var(--dsw-alias-state-error-primary);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
.
|
|
51
|
+
.nVxsMW_del {
|
|
52
52
|
color: var(--dsw-alias-state-error-primary);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
.
|
|
55
|
+
.nVxsMW_add:before {
|
|
56
56
|
content: "+ ";
|
|
57
57
|
color: var(--dsw-alias-state-success-primary);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
.
|
|
60
|
+
.nVxsMW_add {
|
|
61
61
|
color: var(--dsw-alias-state-success-primary);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
.
|
|
64
|
+
.nVxsMW_expand {
|
|
65
65
|
width: 100%;
|
|
66
66
|
color: var(--dsw-alias-label-tertiary);
|
|
67
67
|
cursor: pointer;
|
|
@@ -73,16 +73,16 @@
|
|
|
73
73
|
display: block;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
.
|
|
76
|
+
.nVxsMW_expand:hover {
|
|
77
77
|
color: var(--dsw-alias-label-secondary);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
.
|
|
80
|
+
.nVxsMW_footer {
|
|
81
81
|
font: var(--dsw-font-markdown-code-block);
|
|
82
82
|
color: var(--dsw-alias-label-tertiary);
|
|
83
83
|
padding: 0 14px 12px;
|
|
84
84
|
}
|
|
85
|
-
.
|
|
85
|
+
.Hbqh2W_block {
|
|
86
86
|
--dsl-code-block-banner-background-color: var(--dsw-alias-markdown-code-block-banner);
|
|
87
87
|
--dsl-code-block-border-radius: 12px;
|
|
88
88
|
--dsl-code-block-banner-font: 11px/18px var(--dsw-font-family);
|
|
@@ -94,11 +94,11 @@
|
|
|
94
94
|
position: relative;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
.
|
|
97
|
+
.Hbqh2W_block:not(:last-child) {
|
|
98
98
|
margin-bottom: 11px;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
.
|
|
101
|
+
.Hbqh2W_bannerWrap {
|
|
102
102
|
z-index: 6;
|
|
103
103
|
background-color: var(--dsw-alias-bg-base);
|
|
104
104
|
border-top-left-radius: var(--dsl-code-block-border-radius);
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
top: 0;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
.
|
|
110
|
+
.Hbqh2W_banner {
|
|
111
111
|
background: var(--dsl-code-block-banner-background-color);
|
|
112
112
|
font: var(--dsl-code-block-banner-font);
|
|
113
113
|
border-top-left-radius: var(--dsl-code-block-border-radius);
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
display: flex;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
.
|
|
122
|
+
.Hbqh2W_infostring {
|
|
123
123
|
color: var(--dsw-alias-label-primary);
|
|
124
124
|
font-family: var(--ds-font-family-code);
|
|
125
125
|
text-overflow: ellipsis;
|
|
@@ -130,13 +130,13 @@
|
|
|
130
130
|
overflow: hidden;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
.
|
|
133
|
+
.Hbqh2W_action {
|
|
134
134
|
flex-shrink: 0;
|
|
135
135
|
align-items: center;
|
|
136
136
|
display: flex;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
.
|
|
139
|
+
.Hbqh2W_copyButton {
|
|
140
140
|
color: inherit;
|
|
141
141
|
cursor: pointer;
|
|
142
142
|
font: inherit;
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
padding: 0;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
.
|
|
149
|
+
.Hbqh2W_block :where(pre) {
|
|
150
150
|
font: var(--dsl-code-block-content-font);
|
|
151
151
|
white-space: pre-wrap;
|
|
152
152
|
word-break: break-all;
|
|
@@ -158,72 +158,72 @@
|
|
|
158
158
|
margin: 0 !important;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
.
|
|
161
|
+
.Hbqh2W_block :where(pre.Hbqh2W_shiki) {
|
|
162
162
|
background: var(--dsw-alias-markdown-code-block) !important;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
.
|
|
165
|
+
.Hbqh2W_block :where(pre) code {
|
|
166
166
|
font: inherit;
|
|
167
167
|
background: none;
|
|
168
168
|
padding: 0;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
.
|
|
171
|
+
.Hbqh2W_plain {
|
|
172
172
|
color: var(--dsw-alias-label-primary);
|
|
173
173
|
}
|
|
174
|
-
.
|
|
174
|
+
.BL43XG_markdown {
|
|
175
175
|
overflow-wrap: anywhere;
|
|
176
176
|
min-width: 0;
|
|
177
177
|
font: var(--dsw-font-markdown-base);
|
|
178
178
|
color: var(--dsw-alias-label-primary);
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
.
|
|
181
|
+
.BL43XG_markdown strong {
|
|
182
182
|
font-weight: 600;
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
.
|
|
185
|
+
.BL43XG_markdown h1 {
|
|
186
186
|
font: var(--dsw-font-markdown-h1);
|
|
187
187
|
margin: 32px 0 16px;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
.
|
|
190
|
+
.BL43XG_markdown h2 {
|
|
191
191
|
font: var(--dsw-font-markdown-h2);
|
|
192
192
|
margin: 32px 0 16px;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
.
|
|
195
|
+
.BL43XG_markdown h3 {
|
|
196
196
|
font: var(--dsw-font-markdown-h3);
|
|
197
197
|
margin: 32px 0 16px;
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
.
|
|
200
|
+
.BL43XG_markdown h4 {
|
|
201
201
|
font: var(--dsw-font-markdown-h4);
|
|
202
202
|
margin: 16px 0;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
-
.
|
|
205
|
+
.BL43XG_markdown :where(h5, h6) {
|
|
206
206
|
font: var(--dsw-font-markdown-base-strong);
|
|
207
207
|
margin: 16px 0;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
.
|
|
210
|
+
.BL43XG_markdown :where(h1, h2, h3, h4, h5, h6) strong {
|
|
211
211
|
font-weight: inherit;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
.
|
|
214
|
+
.BL43XG_markdown p {
|
|
215
215
|
margin: 16px 0;
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
.
|
|
218
|
+
.BL43XG_markdown :where(h4, h5, h6) + :where(ul, ol) {
|
|
219
219
|
margin-top: 8px;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
.
|
|
222
|
+
.BL43XG_markdown :where(h4, h5, h6):has( + :where(ul, ol)) {
|
|
223
223
|
margin-bottom: 8px;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
.
|
|
226
|
+
.BL43XG_markdown a {
|
|
227
227
|
color: var(--dsw-alias-link);
|
|
228
228
|
transition: box-shadow var(--ds-transition-duration) var(--ds-ease-in-out);
|
|
229
229
|
border: 2px solid #fff0;
|
|
@@ -235,17 +235,17 @@
|
|
|
235
235
|
position: relative;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
.
|
|
238
|
+
.BL43XG_markdown a:hover, .BL43XG_markdown a:focus {
|
|
239
239
|
text-decoration: underline dotted var(--dsw-alias-link);
|
|
240
240
|
text-underline-offset: 3px;
|
|
241
241
|
outline: none;
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
.
|
|
244
|
+
.BL43XG_markdown a:focus-visible {
|
|
245
245
|
box-shadow: 0 0 0 2px var(--dsw-alias-state-business-primary);
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
.
|
|
248
|
+
.BL43XG_linkIcon {
|
|
249
249
|
vertical-align: -.25em;
|
|
250
250
|
flex: none;
|
|
251
251
|
width: 1.1em;
|
|
@@ -253,46 +253,46 @@
|
|
|
253
253
|
margin-right: 5px;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
.
|
|
256
|
+
.BL43XG_markdown :where(ul, ol) {
|
|
257
257
|
margin: 16px 0;
|
|
258
258
|
padding-left: 18px;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
.
|
|
261
|
+
.BL43XG_markdown li:not(:first-child) {
|
|
262
262
|
margin-top: 6px;
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
.
|
|
265
|
+
.BL43XG_markdown li > :where(ul, ol) {
|
|
266
266
|
margin-top: 4px;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
.
|
|
269
|
+
.BL43XG_markdown li::marker {
|
|
270
270
|
color: var(--dsw-alias-label-secondary);
|
|
271
271
|
line-height: 24px;
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
-
.
|
|
274
|
+
.BL43XG_markdown :where(ul, ol) ol {
|
|
275
275
|
padding-left: 0;
|
|
276
276
|
list-style-position: inside;
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
-
.
|
|
279
|
+
.BL43XG_markdown :where(ul, ol) ol li p {
|
|
280
280
|
display: inline;
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
-
.
|
|
283
|
+
.BL43XG_markdown li > p {
|
|
284
284
|
margin: 8px 0;
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
-
.
|
|
287
|
+
.BL43XG_markdown li > :first-child {
|
|
288
288
|
margin-top: 0;
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
.
|
|
291
|
+
.BL43XG_markdown li > :last-child:not(.md-code-block) {
|
|
292
292
|
margin-bottom: 0;
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
.
|
|
295
|
+
.BL43XG_markdown hr {
|
|
296
296
|
background: var(--dsw-alias-border-l2);
|
|
297
297
|
border: none;
|
|
298
298
|
height: .5px;
|
|
@@ -300,19 +300,19 @@
|
|
|
300
300
|
display: block;
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
-
.
|
|
303
|
+
.BL43XG_markdown blockquote {
|
|
304
304
|
border-left: 2px solid var(--dsw-alias-label-caption);
|
|
305
305
|
margin: 16px 0 0;
|
|
306
306
|
padding-left: 14px;
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
-
.
|
|
309
|
+
.BL43XG_markdown pre {
|
|
310
310
|
font-family: var(--ds-font-family-code);
|
|
311
311
|
margin: 16px 0;
|
|
312
312
|
overflow: auto;
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
.
|
|
315
|
+
.BL43XG_markdown :not(pre) > code {
|
|
316
316
|
box-sizing: border-box;
|
|
317
317
|
font: var(--dsw-font-markdown-code);
|
|
318
318
|
font-family: var(--ds-font-family-code);
|
|
@@ -325,54 +325,54 @@
|
|
|
325
325
|
font-size: .875em !important;
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
.
|
|
328
|
+
.BL43XG_markdown :where(h1, h2, h3, h4, h5, h6) code {
|
|
329
329
|
font: inherit;
|
|
330
330
|
font-family: var(--ds-font-family-code);
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
-
.
|
|
333
|
+
.BL43XG_markdown .katex-display {
|
|
334
334
|
max-width: 100%;
|
|
335
335
|
overflow: auto hidden;
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
-
.
|
|
338
|
+
.BL43XG_markdown input[type="checkbox"] {
|
|
339
339
|
accent-color: var(--dsw-alias-label-secondary);
|
|
340
340
|
margin: 0 8px 0 0;
|
|
341
341
|
}
|
|
342
342
|
|
|
343
|
-
.
|
|
343
|
+
.BL43XG_tableScroll {
|
|
344
344
|
overscroll-behavior-x: contain;
|
|
345
345
|
max-width: 100%;
|
|
346
346
|
overflow-x: auto;
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
-
.
|
|
349
|
+
.BL43XG_tableScroll.md-table-wide {
|
|
350
350
|
padding-bottom: var(--dsh-scrollbar-width, 8px);
|
|
351
351
|
overflow-x: hidden;
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
-
.
|
|
354
|
+
.BL43XG_tableScroll.md-table-wide:hover, .BL43XG_tableScroll.md-table-wide:focus-visible {
|
|
355
355
|
padding-bottom: 0;
|
|
356
356
|
overflow-x: auto;
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
-
.
|
|
359
|
+
.BL43XG_tableScroll:focus-visible {
|
|
360
360
|
box-shadow: 0 0 0 2px var(--dsw-alias-state-business-primary);
|
|
361
361
|
outline: none;
|
|
362
362
|
}
|
|
363
363
|
|
|
364
|
-
.
|
|
364
|
+
.BL43XG_tableScroll table {
|
|
365
365
|
border-collapse: collapse;
|
|
366
366
|
width: max-content;
|
|
367
367
|
max-width: max-content;
|
|
368
368
|
}
|
|
369
369
|
|
|
370
|
-
.
|
|
370
|
+
.BL43XG_tableFill table {
|
|
371
371
|
width: 100%;
|
|
372
372
|
max-width: none;
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
.
|
|
375
|
+
.BL43XG_tableScroll th {
|
|
376
376
|
text-align: start;
|
|
377
377
|
border-bottom: .5px solid var(--dsw-alias-border-l3);
|
|
378
378
|
font: var(--dsw-font-markdown-table-head);
|
|
@@ -382,7 +382,7 @@
|
|
|
382
382
|
padding: 10px 16px;
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
-
.
|
|
385
|
+
.BL43XG_tableScroll td {
|
|
386
386
|
border-bottom: .5px solid var(--dsw-alias-border-l2);
|
|
387
387
|
font: var(--dsw-font-markdown-table);
|
|
388
388
|
min-width: 100px;
|
|
@@ -390,32 +390,32 @@
|
|
|
390
390
|
padding: 10px 16px;
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
.
|
|
393
|
+
.BL43XG_tableScroll th:first-child, .BL43XG_tableScroll td:first-child {
|
|
394
394
|
padding-left: 0;
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
-
.
|
|
397
|
+
.BL43XG_tableScroll td:last-child {
|
|
398
398
|
padding-right: 0;
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
-
.
|
|
401
|
+
.BL43XG_tableScroll table code {
|
|
402
402
|
font-size: 11px;
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
-
.
|
|
405
|
+
.BL43XG_markdown > :first-child, .BL43XG_markdown p:first-child {
|
|
406
406
|
margin-top: 0 !important;
|
|
407
407
|
}
|
|
408
408
|
|
|
409
|
-
.
|
|
409
|
+
.BL43XG_markdown > :last-child, .BL43XG_markdown p:last-child {
|
|
410
410
|
margin-bottom: 0 !important;
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
-
.
|
|
413
|
+
.BL43XG_imageAlt {
|
|
414
414
|
color: var(--dsw-alias-label-tertiary);
|
|
415
415
|
font-style: italic;
|
|
416
416
|
}
|
|
417
417
|
|
|
418
|
-
.
|
|
418
|
+
.BL43XG_image {
|
|
419
419
|
background: var(--dsw-alias-bg-base);
|
|
420
420
|
object-fit: contain;
|
|
421
421
|
border-radius: 8px;
|
|
@@ -426,7 +426,7 @@
|
|
|
426
426
|
display: block;
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
-
.
|
|
429
|
+
.BL43XG_fileMention {
|
|
430
430
|
font: inherit;
|
|
431
431
|
color: var(--dsw-alias-link);
|
|
432
432
|
cursor: pointer;
|
|
@@ -438,7 +438,7 @@
|
|
|
438
438
|
text-decoration: none;
|
|
439
439
|
}
|
|
440
440
|
|
|
441
|
-
.
|
|
441
|
+
.BL43XG_fileMention:hover, .BL43XG_fileMention:focus {
|
|
442
442
|
text-decoration: underline dotted var(--dsw-alias-link);
|
|
443
443
|
text-underline-offset: 3px;
|
|
444
444
|
outline: none;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-plus/access-gate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "dsh-plus service+ui plugin: dsh web 全量访问围栏——与官方 browser-auth 合并:官方 cookie 为唯一凭据,可选 IP 附加围栏,未认证导航渲染 token 输入页(PWA 可恢复),loopback 管理通道",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -31,20 +31,20 @@
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@dsh-plus/shared": "0.1.
|
|
34
|
+
"@dsh-plus/shared": "0.1.11"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
38
|
-
"@deepseek-ai/dsh-home-paths": "
|
|
39
|
-
"@deepseek-ai/dsh-settings": "
|
|
40
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
37
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
38
|
+
"@deepseek-ai/dsh-home-paths": "*",
|
|
39
|
+
"@deepseek-ai/dsh-settings": "*",
|
|
40
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@deepseek-ai/cordis": "4.0.2",
|
|
44
|
-
"@deepseek-ai/dsh-client-connection": "0.1.
|
|
45
|
-
"@deepseek-ai/dsh-home-paths": "0.1.
|
|
46
|
-
"@deepseek-ai/dsh-host-webserver": "0.1.
|
|
47
|
-
"@deepseek-ai/dsh-settings": "0.1.
|
|
44
|
+
"@deepseek-ai/dsh-client-connection": "0.1.5-alpha.1",
|
|
45
|
+
"@deepseek-ai/dsh-home-paths": "0.1.5-alpha.1",
|
|
46
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.5-alpha.1",
|
|
47
|
+
"@deepseek-ai/dsh-settings": "0.1.5-alpha.1",
|
|
48
48
|
"@deepseek-ai/schemastery": "3.18.2",
|
|
49
49
|
"@types/react": "~18.3.31",
|
|
50
50
|
"react": "^18.2.0"
|
package/src/client/card.tsx
CHANGED
|
@@ -33,12 +33,14 @@ export interface ConfigValue {
|
|
|
33
33
|
enabled: boolean
|
|
34
34
|
allowedIps: string[]
|
|
35
35
|
trustForwardedFor: boolean
|
|
36
|
+
autoLoginTrustedIps: boolean
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
interface Draft {
|
|
39
40
|
enabled: boolean
|
|
40
41
|
allowedIpsText: string
|
|
41
42
|
trustForwardedFor: boolean
|
|
43
|
+
autoLoginTrustedIps: boolean
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
interface Diag {
|
|
@@ -50,6 +52,8 @@ interface Diag {
|
|
|
50
52
|
ipFenceActive: boolean
|
|
51
53
|
invalidEntries: string[]
|
|
52
54
|
allowedCount: number
|
|
55
|
+
autoLoginActive: boolean
|
|
56
|
+
autoLoginReady: boolean
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
function draftFromValue(value: ConfigValue): Draft {
|
|
@@ -57,6 +61,7 @@ function draftFromValue(value: ConfigValue): Draft {
|
|
|
57
61
|
enabled: value.enabled,
|
|
58
62
|
allowedIpsText: value.allowedIps.join('\n'),
|
|
59
63
|
trustForwardedFor: value.trustForwardedFor,
|
|
64
|
+
autoLoginTrustedIps: value.autoLoginTrustedIps,
|
|
60
65
|
}
|
|
61
66
|
}
|
|
62
67
|
|
|
@@ -68,6 +73,7 @@ function toPatch(draft: Draft): Record<string, unknown> {
|
|
|
68
73
|
.map((s) => s.trim())
|
|
69
74
|
.filter((s) => s.length > 0),
|
|
70
75
|
trustForwardedFor: draft.trustForwardedFor,
|
|
76
|
+
autoLoginTrustedIps: draft.autoLoginTrustedIps,
|
|
71
77
|
}
|
|
72
78
|
}
|
|
73
79
|
|
|
@@ -75,12 +81,14 @@ function toPatch(draft: Draft): Record<string, unknown> {
|
|
|
75
81
|
const REASON_KEYS: Record<string, string> = {
|
|
76
82
|
local: 'diagLocal',
|
|
77
83
|
cookie: 'diagCookie',
|
|
84
|
+
'trusted-ip': 'diagTrustedIp',
|
|
78
85
|
}
|
|
79
86
|
|
|
80
87
|
function verdictLabel(t: (key: string) => string, diag: Diag): string {
|
|
81
88
|
if (!diag.enabled) return t('diagOff')
|
|
82
89
|
if (diag.verdict === 'pass') return t('diagPass')
|
|
83
90
|
if (diag.verdict === 'token-page') return t('diagTokenPage')
|
|
91
|
+
if (diag.verdict === 'autologin') return t('diagAutoLogin')
|
|
84
92
|
return t('diagBlock')
|
|
85
93
|
}
|
|
86
94
|
|
|
@@ -213,6 +221,14 @@ export function AccessGateCard(props: CardProps): ReactElement | null {
|
|
|
213
221
|
/>
|
|
214
222
|
<p className="dag-hint">{t('allowedIpsHint')}</p>
|
|
215
223
|
</div>
|
|
224
|
+
<CheckRow
|
|
225
|
+
prefix="dag"
|
|
226
|
+
id="dag-autologin"
|
|
227
|
+
label={t('autoLoginHint')}
|
|
228
|
+
checked={draft.autoLoginTrustedIps}
|
|
229
|
+
disabled={disabled}
|
|
230
|
+
onEdit={(v) => edit('autoLoginTrustedIps', v)}
|
|
231
|
+
/>
|
|
216
232
|
<CheckRow
|
|
217
233
|
prefix="dag"
|
|
218
234
|
id="dag-xff"
|
|
@@ -244,6 +260,14 @@ export function AccessGateCard(props: CardProps): ReactElement | null {
|
|
|
244
260
|
{diag.officialAuthed ? t('diagOfficialYes') : t('diagOfficialNo')}
|
|
245
261
|
</span>
|
|
246
262
|
</div>
|
|
263
|
+
{diag.autoLoginActive ? (
|
|
264
|
+
<div className="dag-diagRow">
|
|
265
|
+
<span className="dag-diagKey">{t('diagAutoLogin')}</span>
|
|
266
|
+
<span className="dag-diagVal">
|
|
267
|
+
{diag.autoLoginReady ? t('diagAutoLoginReady') : t('diagAutoLoginNoSecret')}
|
|
268
|
+
</span>
|
|
269
|
+
</div>
|
|
270
|
+
) : null}
|
|
247
271
|
{diag.invalidEntries.length > 0 ? (
|
|
248
272
|
<div className="dag-diagRow">
|
|
249
273
|
<span className="dag-diagKey">!</span>
|
package/src/client/i18n.ts
CHANGED
|
@@ -18,6 +18,8 @@ const ownZh = {
|
|
|
18
18
|
allowedIps: '附加 IP 围栏白名单',
|
|
19
19
|
allowedIpsHint:
|
|
20
20
|
'每行一个:精确 IP 或 CIDR(IPv4/IPv6 皆可)。非空时仅白名单来源可通行与登录;留空 = 不限制来源 IP(仅官方登录保护)。',
|
|
21
|
+
autoLoginHint:
|
|
22
|
+
'IP 信任自动登录:白名单来源未认证时自动签发官方登录 cookie,免输启动令牌。开启即视为信任白名单内全部设备(tailnet 内),请确保白名单准确。',
|
|
21
23
|
trustForwardedFor: '信任 x-forwarded-for 还原客户端 IP',
|
|
22
24
|
trustForwardedForHint:
|
|
23
25
|
'仅当入口代理强制覆盖该头时开启(tailscale serve 满足);直连暴露场景必须关闭。',
|
|
@@ -27,12 +29,17 @@ const ownZh = {
|
|
|
27
29
|
diagReason: '放行原因',
|
|
28
30
|
diagLocal: '本机直连',
|
|
29
31
|
diagCookie: '官方 cookie',
|
|
32
|
+
diagTrustedIp: 'IP 信任白名单',
|
|
30
33
|
diagOfficial: '官方登录状态',
|
|
31
34
|
diagOfficialYes: '已登录',
|
|
32
35
|
diagOfficialNo: '未登录',
|
|
33
36
|
diagPass: '放行',
|
|
34
37
|
diagBlock: '拦截',
|
|
35
38
|
diagTokenPage: '令牌输入页',
|
|
39
|
+
diagAutoLogin: '自动登录',
|
|
40
|
+
diagAutoLoginVerdict: '自动登录(免 token 进入)',
|
|
41
|
+
diagAutoLoginReady: '已就绪(签名密钥可读)',
|
|
42
|
+
diagAutoLoginNoSecret: '不可用(签名密钥读取失败,已降级)',
|
|
36
43
|
diagOff: '围栏未启用',
|
|
37
44
|
diagInvalid: '白名单存在无法解析的条目:',
|
|
38
45
|
}
|
|
@@ -49,6 +56,8 @@ const ownEn = {
|
|
|
49
56
|
allowedIps: 'Additional IP fence allowlist',
|
|
50
57
|
allowedIpsHint:
|
|
51
58
|
'One per line: exact IP or CIDR (IPv4/IPv6). When non-empty only listed sources may pass or log in; empty = no IP restriction (official login only).',
|
|
59
|
+
autoLoginHint:
|
|
60
|
+
'Trusted-IP auto login: mint the official login cookie automatically for unauthenticated allowlisted sources, no launch token needed. Enabling trusts every allowlisted device (inside the tailnet); keep the allowlist accurate.',
|
|
52
61
|
trustForwardedFor: 'Trust x-forwarded-for for client IP',
|
|
53
62
|
trustForwardedForHint:
|
|
54
63
|
'Enable only when the entry proxy overwrites that header (tailscale serve does); must be off for direct exposure.',
|
|
@@ -58,12 +67,17 @@ const ownEn = {
|
|
|
58
67
|
diagReason: 'Reason',
|
|
59
68
|
diagLocal: 'loopback',
|
|
60
69
|
diagCookie: 'official cookie',
|
|
70
|
+
diagTrustedIp: 'trusted IP allowlist',
|
|
61
71
|
diagOfficial: 'Official login',
|
|
62
72
|
diagOfficialYes: 'authenticated',
|
|
63
73
|
diagOfficialNo: 'not authenticated',
|
|
64
74
|
diagPass: 'pass',
|
|
65
75
|
diagBlock: 'blocked',
|
|
66
76
|
diagTokenPage: 'token page',
|
|
77
|
+
diagAutoLogin: 'Auto login',
|
|
78
|
+
diagAutoLoginVerdict: 'auto login (token-free entry)',
|
|
79
|
+
diagAutoLoginReady: 'ready (signing secret readable)',
|
|
80
|
+
diagAutoLoginNoSecret: 'unavailable (signing secret unreadable, degraded)',
|
|
67
81
|
diagOff: 'gate disabled',
|
|
68
82
|
diagInvalid: 'Allowlist entries that failed to parse:',
|
|
69
83
|
}
|
package/src/config.ts
CHANGED
|
@@ -34,6 +34,12 @@ export const Config = z.object({
|
|
|
34
34
|
'是否信任 x-forwarded-for 还原真实客户端 IP(仅当入口代理强制覆盖该头时开启;tailscale serve 满足)',
|
|
35
35
|
)
|
|
36
36
|
.default(true),
|
|
37
|
+
autoLoginTrustedIps: z
|
|
38
|
+
.boolean()
|
|
39
|
+
.description(
|
|
40
|
+
'IP 信任自动登录:来源命中 allowedIps 白名单且未认证时,服务端自动签发官方登录 cookie(免启动 token,仅对白名单来源生效);默认关闭,需显式开启',
|
|
41
|
+
)
|
|
42
|
+
.default(false),
|
|
37
43
|
})
|
|
38
44
|
|
|
39
45
|
export type AccessGateConfig = Schemastery.TypeT<typeof Config>
|
|
@@ -43,4 +49,5 @@ export interface GatePolicy {
|
|
|
43
49
|
readonly enabled: boolean
|
|
44
50
|
readonly allowedIps: readonly string[]
|
|
45
51
|
readonly trustForwardedFor: boolean
|
|
52
|
+
readonly autoLoginTrustedIps: boolean
|
|
46
53
|
}
|