system-phone 3.1.92 → 3.1.94
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/.serena/project.yml +87 -0
- package/build/dev-server.js +0 -6
- package/package.json +1 -1
- package/src/components/LoginApp.vue +8 -4
- package/src/components/ModifyPassWord.vue +62 -3
- package/src/filiale/gongyi/LoginApp.vue +8 -4
- package/src/filiale/kelamayi/LoginAppV4.vue +9 -4
- package/src/filiale/liaoyuan/LoginApp.vue +8 -4
- package/src/filiale/yuansheng/LoginApp.vue +8 -4
- package/src/filiale/yulinyuchuan/LoginApp.vue +9 -4
- package/src/filiale/yulinyuchuanTY/LoginApp.vue +9 -4
- package/src/plugins/validateStrongPasswordPhone.js +138 -125
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# list of languages for which language servers are started; choose from:
|
|
2
|
+
# al bash clojure cpp csharp csharp_omnisharp
|
|
3
|
+
# dart elixir elm erlang fortran fsharp
|
|
4
|
+
# go groovy haskell java julia kotlin
|
|
5
|
+
# lua markdown nix pascal perl php
|
|
6
|
+
# powershell python python_jedi r rego ruby
|
|
7
|
+
# ruby_solargraph rust scala swift terraform toml
|
|
8
|
+
# typescript typescript_vts yaml zig
|
|
9
|
+
# Note:
|
|
10
|
+
# - For C, use cpp
|
|
11
|
+
# - For JavaScript, use typescript
|
|
12
|
+
# - For Free Pascal / Lazarus, use pascal
|
|
13
|
+
# Special requirements:
|
|
14
|
+
# - csharp: Requires the presence of a .sln file in the project folder.
|
|
15
|
+
# - pascal: Requires Free Pascal Compiler (fpc) and optionally Lazarus.
|
|
16
|
+
# When using multiple languages, the first language server that supports a given file will be used for that file.
|
|
17
|
+
# The first language is the default language and the respective language server will be used as a fallback.
|
|
18
|
+
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
|
|
19
|
+
languages:
|
|
20
|
+
- vue
|
|
21
|
+
|
|
22
|
+
# the encoding used by text files in the project
|
|
23
|
+
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
|
|
24
|
+
encoding: "utf-8"
|
|
25
|
+
|
|
26
|
+
# whether to use the project's gitignore file to ignore files
|
|
27
|
+
# Added on 2025-04-07
|
|
28
|
+
ignore_all_files_in_gitignore: true
|
|
29
|
+
|
|
30
|
+
# list of additional paths to ignore
|
|
31
|
+
# same syntax as gitignore, so you can use * and **
|
|
32
|
+
# Was previously called `ignored_dirs`, please update your config if you are using that.
|
|
33
|
+
# Added (renamed) on 2025-04-07
|
|
34
|
+
ignored_paths: []
|
|
35
|
+
|
|
36
|
+
# whether the project is in read-only mode
|
|
37
|
+
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
|
|
38
|
+
# Added on 2025-04-18
|
|
39
|
+
read_only: false
|
|
40
|
+
|
|
41
|
+
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
|
|
42
|
+
# Below is the complete list of tools for convenience.
|
|
43
|
+
# To make sure you have the latest list of tools, and to view their descriptions,
|
|
44
|
+
# execute `uv run scripts/print_tool_overview.py`.
|
|
45
|
+
#
|
|
46
|
+
# * `activate_project`: Activates a project by name.
|
|
47
|
+
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
|
|
48
|
+
# * `create_text_file`: Creates/overwrites a file in the project directory.
|
|
49
|
+
# * `delete_lines`: Deletes a range of lines within a file.
|
|
50
|
+
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
|
|
51
|
+
# * `execute_shell_command`: Executes a shell command.
|
|
52
|
+
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
|
|
53
|
+
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
|
|
54
|
+
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
|
55
|
+
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
|
|
56
|
+
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
|
|
57
|
+
# * `initial_instructions`: Gets the initial instructions for the current project.
|
|
58
|
+
# Should only be used in settings where the system prompt cannot be set,
|
|
59
|
+
# e.g. in clients you have no control over, like Claude Desktop.
|
|
60
|
+
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
|
|
61
|
+
# * `insert_at_line`: Inserts content at a given line in a file.
|
|
62
|
+
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
|
|
63
|
+
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
|
|
64
|
+
# * `list_memories`: Lists memories in Serena's project-specific memory store.
|
|
65
|
+
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
|
|
66
|
+
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
|
|
67
|
+
# * `read_file`: Reads a file within the project directory.
|
|
68
|
+
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
|
|
69
|
+
# * `remove_project`: Removes a project from the Serena configuration.
|
|
70
|
+
# * `replace_lines`: Replaces a range of lines within a file with new content.
|
|
71
|
+
# * `replace_symbol_body`: Replaces the full definition of a symbol.
|
|
72
|
+
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
|
|
73
|
+
# * `search_for_pattern`: Performs a search for a pattern in the project.
|
|
74
|
+
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
|
|
75
|
+
# * `switch_modes`: Activates modes by providing a list of their names
|
|
76
|
+
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
|
|
77
|
+
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
|
|
78
|
+
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
|
|
79
|
+
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
|
|
80
|
+
excluded_tools: []
|
|
81
|
+
|
|
82
|
+
# initial prompt for the project. It will always be given to the LLM upon activating the project
|
|
83
|
+
# (contrary to the memories, which are loaded on demand).
|
|
84
|
+
initial_prompt: ""
|
|
85
|
+
|
|
86
|
+
project_name: "SystemPhone"
|
|
87
|
+
included_optional_tools: []
|
package/build/dev-server.js
CHANGED
|
@@ -11,12 +11,6 @@ var compiler = webpack(config)
|
|
|
11
11
|
// Define HTTP proxies to your custom API backend
|
|
12
12
|
// https://github.com/chimurai/http-proxy-middleware
|
|
13
13
|
var proxyTable = {
|
|
14
|
-
'/rs/logic/getLogin': {
|
|
15
|
-
pathRewrite: {
|
|
16
|
-
'^/rs/logic/getLogin': '/getLogin'
|
|
17
|
-
},
|
|
18
|
-
target: 'http://127.0.0.1:8077/'
|
|
19
|
-
},
|
|
20
14
|
// '/rs/weixin': {
|
|
21
15
|
// target: 'http://121.36.106.17:8400/'
|
|
22
16
|
// },
|
package/package.json
CHANGED
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
import Vue from 'vue'
|
|
107
107
|
import * as Util from '../Util'
|
|
108
108
|
import cryptJS from './EncryptUtil'
|
|
109
|
+
import { validateStrongPasswordPhone } from '../plugins/validateStrongPasswordPhone.js'
|
|
109
110
|
//获取json配置文件
|
|
110
111
|
let asyncReady = async function (self, url) {
|
|
111
112
|
// 获取配置信息
|
|
@@ -481,10 +482,13 @@ export default {
|
|
|
481
482
|
console.log('获取参数结束')
|
|
482
483
|
this.loaderShow = false
|
|
483
484
|
// 弱口令验证
|
|
484
|
-
if (this.weakPassword
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
485
|
+
if (this.weakPassword) {
|
|
486
|
+
const pwdResult = validateStrongPasswordPhone(this.password)
|
|
487
|
+
if (!pwdResult.isValid) {
|
|
488
|
+
await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
|
|
489
|
+
this.modifyPassword = true
|
|
490
|
+
return
|
|
491
|
+
}
|
|
488
492
|
}
|
|
489
493
|
this.$goto('nav-bottom')
|
|
490
494
|
},
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
<!--<span class="glyphicon glyphicon-menu-left">返回</span>-->
|
|
4
4
|
<!--</div>-->
|
|
5
5
|
<div class="auto">
|
|
6
|
+
<div v-if="weakPassword" class="password-alert">
|
|
7
|
+
{{ passwordRuleHint }}
|
|
8
|
+
</div>
|
|
6
9
|
<div class="row app-row">
|
|
7
10
|
<div class="col-xs-4">
|
|
8
11
|
<img src="../assets/姓名.png" style="width: 20px;margin-bottom: 5px" alt="">
|
|
@@ -29,7 +32,12 @@
|
|
|
29
32
|
</div>
|
|
30
33
|
<div class="col-xs-8">
|
|
31
34
|
<input type="password" id="newpassword1" class="search_input input-font" v-model="model.password"
|
|
32
|
-
|
|
35
|
+
placeholder="请输入新密码"/>
|
|
36
|
+
<div v-if="weakPassword && passwordStrength.visible" class="password-strength">
|
|
37
|
+
<span class="strength-label">密码强度</span>
|
|
38
|
+
<span class="strength-tag" :class="passwordStrength.type">{{ passwordStrength.label }}</span>
|
|
39
|
+
<span class="strength-desc">{{ passwordStrength.desc }}</span>
|
|
40
|
+
</div>
|
|
33
41
|
</div>
|
|
34
42
|
</div>
|
|
35
43
|
<div class="row app-row">
|
|
@@ -104,7 +112,7 @@ let asyncCheck = async function (self, url) {
|
|
|
104
112
|
}
|
|
105
113
|
}
|
|
106
114
|
}
|
|
107
|
-
import { validateStrongPasswordPhone } from '../plugins/validateStrongPasswordPhone.js'
|
|
115
|
+
import { validateStrongPasswordPhone, getPasswordStrength, PASSWORD_RULE_HINT } from '../plugins/validateStrongPasswordPhone.js'
|
|
108
116
|
export default {
|
|
109
117
|
title: '修改密码',
|
|
110
118
|
data() {
|
|
@@ -117,7 +125,13 @@ export default {
|
|
|
117
125
|
password: '',
|
|
118
126
|
newpassword: ''
|
|
119
127
|
},
|
|
120
|
-
showpass: false
|
|
128
|
+
showpass: false,
|
|
129
|
+
passwordRuleHint: PASSWORD_RULE_HINT
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
computed: {
|
|
133
|
+
passwordStrength () {
|
|
134
|
+
return getPasswordStrength(this.model.password)
|
|
121
135
|
}
|
|
122
136
|
},
|
|
123
137
|
props: {
|
|
@@ -204,6 +218,51 @@ export default {
|
|
|
204
218
|
color: #333333;
|
|
205
219
|
}
|
|
206
220
|
|
|
221
|
+
.password-alert {
|
|
222
|
+
margin: 10px 10px 0;
|
|
223
|
+
padding: 10px 12px;
|
|
224
|
+
border-radius: 6px;
|
|
225
|
+
background: #f5f7fa;
|
|
226
|
+
border: 1px solid #e4e7ed;
|
|
227
|
+
color: #606266;
|
|
228
|
+
font-size: 13px;
|
|
229
|
+
line-height: 1.6;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.password-strength {
|
|
233
|
+
margin-top: 8px;
|
|
234
|
+
font-size: 12px;
|
|
235
|
+
line-height: 1.6;
|
|
236
|
+
color: #606266;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.password-strength .strength-label {
|
|
240
|
+
margin-right: 6px;
|
|
241
|
+
color: #909399;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.password-strength .strength-tag {
|
|
245
|
+
display: inline-block;
|
|
246
|
+
margin-right: 8px;
|
|
247
|
+
padding: 1px 8px;
|
|
248
|
+
border-radius: 3px;
|
|
249
|
+
font-size: 12px;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.password-strength .strength-tag.success {
|
|
253
|
+
color: #2e7d32;
|
|
254
|
+
background: #e8f5e9;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.password-strength .strength-tag.error {
|
|
258
|
+
color: #c62828;
|
|
259
|
+
background: #ffebee;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.password-strength .strength-desc {
|
|
263
|
+
color: #606266;
|
|
264
|
+
}
|
|
265
|
+
|
|
207
266
|
.app-botton {
|
|
208
267
|
position: fixed;
|
|
209
268
|
background: #87b2dd;
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
import Vue from 'vue'
|
|
64
64
|
import * as Util from '../../Util'
|
|
65
65
|
import JSEncrypt from 'jsencrypt'
|
|
66
|
+
import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
|
|
66
67
|
//获取json配置文件
|
|
67
68
|
let asyncReady = async function (self, url) {
|
|
68
69
|
// 获取配置信息
|
|
@@ -308,10 +309,13 @@ export default {
|
|
|
308
309
|
console.log('获取参数结束')
|
|
309
310
|
this.loaderShow = false
|
|
310
311
|
// 弱口令验证
|
|
311
|
-
if (this.weakPassword
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
312
|
+
if (this.weakPassword) {
|
|
313
|
+
const pwdResult = validateStrongPasswordPhone(this.password)
|
|
314
|
+
if (!pwdResult.isValid) {
|
|
315
|
+
await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
|
|
316
|
+
this.modifyPassword = true
|
|
317
|
+
return
|
|
318
|
+
}
|
|
315
319
|
}
|
|
316
320
|
this.$goto('nav-bottom')
|
|
317
321
|
} catch (e) {
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
import Vue from 'vue'
|
|
63
63
|
import * as Util from '../../Util'
|
|
64
64
|
import JSEncrypt from 'jsencrypt'
|
|
65
|
+
import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
|
|
65
66
|
//获取json配置文件
|
|
66
67
|
let asyncReady = async function (self, url) {
|
|
67
68
|
// 获取配置信息
|
|
@@ -321,10 +322,14 @@ export default {
|
|
|
321
322
|
console.log('获取参数结束')
|
|
322
323
|
this.loaderShow = false
|
|
323
324
|
// 弱口令验证
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
325
|
+
// 弱口令验证
|
|
326
|
+
if (this.weakPassword) {
|
|
327
|
+
const pwdResult = validateStrongPasswordPhone(this.password)
|
|
328
|
+
if (!pwdResult.isValid) {
|
|
329
|
+
await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
|
|
330
|
+
this.modifyPassword = true
|
|
331
|
+
return
|
|
332
|
+
}
|
|
328
333
|
}
|
|
329
334
|
this.$goto('nav-bottom')
|
|
330
335
|
} catch (e) {
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
import Vue from 'vue'
|
|
64
64
|
import * as Util from '../../Util'
|
|
65
65
|
import JSEncrypt from 'jsencrypt'
|
|
66
|
+
import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
|
|
66
67
|
//获取json配置文件
|
|
67
68
|
let asyncReady = async function (self, url) {
|
|
68
69
|
// 获取配置信息
|
|
@@ -337,10 +338,13 @@ export default {
|
|
|
337
338
|
console.log('获取参数结束')
|
|
338
339
|
this.loaderShow = false
|
|
339
340
|
// 弱口令验证
|
|
340
|
-
if (this.weakPassword
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
341
|
+
if (this.weakPassword) {
|
|
342
|
+
const pwdResult = validateStrongPasswordPhone(this.password)
|
|
343
|
+
if (!pwdResult.isValid) {
|
|
344
|
+
await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
|
|
345
|
+
this.modifyPassword = true
|
|
346
|
+
return
|
|
347
|
+
}
|
|
344
348
|
}
|
|
345
349
|
this.$goto('nav-bottom')
|
|
346
350
|
} catch (e) {
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
import Vue from 'vue'
|
|
65
65
|
import * as Util from '../../Util'
|
|
66
66
|
import JSEncrypt from 'jsencrypt'
|
|
67
|
+
import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
|
|
67
68
|
//获取json配置文件
|
|
68
69
|
let asyncReady = async function (self, url) {
|
|
69
70
|
// 获取配置信息
|
|
@@ -368,10 +369,13 @@ export default {
|
|
|
368
369
|
console.log('获取参数结束')
|
|
369
370
|
this.loaderShow = false
|
|
370
371
|
// 弱口令验证
|
|
371
|
-
if (this.weakPassword
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
372
|
+
if (this.weakPassword) {
|
|
373
|
+
const pwdResult = validateStrongPasswordPhone(this.password)
|
|
374
|
+
if (!pwdResult.isValid) {
|
|
375
|
+
await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
|
|
376
|
+
this.modifyPassword = true
|
|
377
|
+
return
|
|
378
|
+
}
|
|
375
379
|
}
|
|
376
380
|
this.$goto('nav-bottom')
|
|
377
381
|
},
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
import Vue from 'vue'
|
|
64
64
|
import * as Util from '../../Util'
|
|
65
65
|
import JSEncrypt from 'jsencrypt'
|
|
66
|
+
import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
|
|
66
67
|
//获取json配置文件
|
|
67
68
|
let asyncReady = async function (self, url) {
|
|
68
69
|
try {
|
|
@@ -361,10 +362,14 @@ export default {
|
|
|
361
362
|
console.log('获取参数结束')
|
|
362
363
|
this.loaderShow = false
|
|
363
364
|
// 弱口令验证
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
365
|
+
// 弱口令验证
|
|
366
|
+
if (this.weakPassword) {
|
|
367
|
+
const pwdResult = validateStrongPasswordPhone(this.password)
|
|
368
|
+
if (!pwdResult.isValid) {
|
|
369
|
+
await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
|
|
370
|
+
this.modifyPassword = true
|
|
371
|
+
return
|
|
372
|
+
}
|
|
368
373
|
}
|
|
369
374
|
this.$androidUtil.setPreference('current_create_current_address', JSON.stringify({
|
|
370
375
|
f_address: '',
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
import Vue from 'vue'
|
|
64
64
|
import * as Util from '../../Util'
|
|
65
65
|
import JSEncrypt from 'jsencrypt'
|
|
66
|
+
import { validateStrongPasswordPhone } from '../../plugins/validateStrongPasswordPhone.js'
|
|
66
67
|
//获取json配置文件
|
|
67
68
|
let asyncReady = async function (self, url) {
|
|
68
69
|
try {
|
|
@@ -331,10 +332,14 @@ export default {
|
|
|
331
332
|
console.log('获取参数结束')
|
|
332
333
|
this.loaderShow = false
|
|
333
334
|
// 弱口令验证
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
335
|
+
// 弱口令验证
|
|
336
|
+
if (this.weakPassword) {
|
|
337
|
+
const pwdResult = validateStrongPasswordPhone(this.password)
|
|
338
|
+
if (!pwdResult.isValid) {
|
|
339
|
+
await this.$showMessage('登录系统: 此账户的密码过于简单,' + (pwdResult.errors[0] || '请修改密码后重新登陆!!!'), ['confirm'])
|
|
340
|
+
this.modifyPassword = true
|
|
341
|
+
return
|
|
342
|
+
}
|
|
338
343
|
}
|
|
339
344
|
this.$androidUtil.setPreference('current_create_current_address', JSON.stringify({
|
|
340
345
|
f_address: '',
|
|
@@ -1,172 +1,185 @@
|
|
|
1
1
|
const REG_STRONG_PWD =
|
|
2
|
-
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()
|
|
2
|
+
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*(),.?":{}|<>~`+=_\\-])[A-Za-z\d!@#$%^&*(),.?":{}|<>~`+=_\\-]{12,16}$/
|
|
3
3
|
|
|
4
|
-
// 常见密码列表(可以根据需要扩展)
|
|
5
4
|
const COMMON_PASSWORDS = [
|
|
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
|
-
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
5
|
+
'password',
|
|
6
|
+
'password123',
|
|
7
|
+
'123456',
|
|
8
|
+
'12345678',
|
|
9
|
+
'qwerty',
|
|
10
|
+
'abc123',
|
|
11
|
+
'Password1',
|
|
12
|
+
'password1',
|
|
13
|
+
'123456789',
|
|
14
|
+
'welcome',
|
|
15
|
+
'admin',
|
|
16
|
+
'letmein',
|
|
17
|
+
'monkey',
|
|
18
|
+
'dragon',
|
|
19
|
+
'master',
|
|
20
|
+
'superman',
|
|
21
|
+
'qwerty123',
|
|
22
|
+
'admin123',
|
|
23
|
+
'root',
|
|
24
|
+
'pass',
|
|
25
|
+
'test',
|
|
26
|
+
'guest',
|
|
27
|
+
'user',
|
|
28
|
+
'000000',
|
|
29
|
+
'111111',
|
|
30
|
+
'666666',
|
|
31
|
+
'888888',
|
|
32
|
+
'999999',
|
|
33
|
+
'iloveyou',
|
|
34
|
+
'welcome123',
|
|
35
|
+
'password!',
|
|
36
|
+
'Passw0rd!',
|
|
37
|
+
'Passw0rd',
|
|
38
|
+
'Password!',
|
|
39
|
+
'passw0rd',
|
|
40
|
+
'P@ssw0rd',
|
|
41
|
+
'P@ssword',
|
|
42
|
+
'Password@123'
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
export const PASSWORD_RULE_HINT = '密码长度须为 12-16 位,包含大小写字母、数字与特殊符号。'
|
|
46
|
+
|
|
47
|
+
export const PASSWORD_DEFAULT_ERROR = '新密码必须包含大小写字母、数字和特殊字符,且长度为12-16位'
|
|
48
|
+
|
|
49
|
+
function hasConsecutiveNumbers (password) {
|
|
48
50
|
for (let i = 0; i <= password.length - 3; i++) {
|
|
49
|
-
const substr = password.substring(i, i + 3)
|
|
51
|
+
const substr = password.substring(i, i + 3)
|
|
50
52
|
if (/^\d{3,}$/.test(substr)) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
let isConsecutive = true;
|
|
53
|
+
const digits = substr.split('').map(Number)
|
|
54
|
+
let isConsecutive = true
|
|
54
55
|
for (let j = 1; j < digits.length; j++) {
|
|
55
56
|
if (digits[j] !== digits[j - 1] + 1) {
|
|
56
|
-
isConsecutive = false
|
|
57
|
-
break
|
|
57
|
+
isConsecutive = false
|
|
58
|
+
break
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
|
-
if (isConsecutive) return true
|
|
61
|
+
if (isConsecutive) return true
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
|
-
return false
|
|
64
|
-
}
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
const lowerPassword = password.toLowerCase();
|
|
67
|
+
function hasConsecutiveLetters (password) {
|
|
68
|
+
const lowerPassword = password.toLowerCase()
|
|
69
69
|
for (let i = 0; i <= lowerPassword.length - 3; i++) {
|
|
70
|
-
const substr = lowerPassword.substring(i, i + 3)
|
|
70
|
+
const substr = lowerPassword.substring(i, i + 3)
|
|
71
71
|
if (/^[a-z]{3,}$/.test(substr)) {
|
|
72
|
-
|
|
73
|
-
let isConsecutive = true;
|
|
72
|
+
let isConsecutive = true
|
|
74
73
|
for (let j = 1; j < substr.length; j++) {
|
|
75
74
|
if (substr.charCodeAt(j) !== substr.charCodeAt(j - 1) + 1) {
|
|
76
|
-
isConsecutive = false
|
|
77
|
-
break
|
|
75
|
+
isConsecutive = false
|
|
76
|
+
break
|
|
78
77
|
}
|
|
79
78
|
}
|
|
80
|
-
if (isConsecutive) return true
|
|
79
|
+
if (isConsecutive) return true
|
|
81
80
|
}
|
|
82
81
|
}
|
|
83
|
-
return false
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
const lowerPassword = password.toLowerCase();
|
|
82
|
+
return false
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function hasRepeatedChars (password) {
|
|
86
|
+
return /(.)\1{2,}/.test(password)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function hasKeyboardPattern (password) {
|
|
90
|
+
const keyboardRows = ['qwertyuiop', 'asdfghjkl', 'zxcvbnm', '1234567890']
|
|
91
|
+
const lowerPassword = password.toLowerCase()
|
|
92
|
+
|
|
95
93
|
for (const row of keyboardRows) {
|
|
96
94
|
for (let i = 0; i <= row.length - 3; i++) {
|
|
97
|
-
const pattern = row.substring(i, i + 3)
|
|
95
|
+
const pattern = row.substring(i, i + 3)
|
|
98
96
|
if (lowerPassword.includes(pattern)) {
|
|
99
|
-
return true
|
|
97
|
+
return true
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
100
|
}
|
|
103
|
-
return false
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* 密码校验结果对象
|
|
108
|
-
* @typedef {Object} PasswordValidationResult
|
|
109
|
-
* @property {boolean} isValid
|
|
110
|
-
* @property {string[]} errors
|
|
111
|
-
*/
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* 增强的密码校验函数
|
|
115
|
-
* @param {string} password
|
|
116
|
-
* @returns {PasswordValidationResult}
|
|
117
|
-
*/
|
|
101
|
+
return false
|
|
102
|
+
}
|
|
103
|
+
|
|
118
104
|
export const validateStrongPasswordPhone = (password) => {
|
|
119
105
|
const result = {
|
|
120
106
|
isValid: true,
|
|
121
|
-
errors: []
|
|
122
|
-
}
|
|
107
|
+
errors: []
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!password) {
|
|
111
|
+
result.isValid = false
|
|
112
|
+
result.errors.push('不能为空')
|
|
113
|
+
return result
|
|
114
|
+
}
|
|
123
115
|
|
|
124
|
-
// 1. 基本格式校验
|
|
125
116
|
if (!REG_STRONG_PWD.test(password)) {
|
|
126
|
-
result.isValid = false
|
|
127
|
-
result.errors.push(
|
|
128
|
-
|
|
129
|
-
);
|
|
130
|
-
return result;
|
|
117
|
+
result.isValid = false
|
|
118
|
+
result.errors.push('密码长度须为12-16位,且包含大写字母、小写字母、数字和特殊字符')
|
|
119
|
+
return result
|
|
131
120
|
}
|
|
132
121
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
) {
|
|
138
|
-
result.isValid = false;
|
|
139
|
-
result.errors.push("不能使用常见密码");
|
|
140
|
-
return result;
|
|
122
|
+
if (COMMON_PASSWORDS.includes(password) || COMMON_PASSWORDS.includes(password.toLowerCase())) {
|
|
123
|
+
result.isValid = false
|
|
124
|
+
result.errors.push('不能使用常见密码')
|
|
125
|
+
return result
|
|
141
126
|
}
|
|
142
127
|
|
|
143
|
-
// 3. 检查连续数字
|
|
144
128
|
if (hasConsecutiveNumbers(password)) {
|
|
145
|
-
result.isValid = false
|
|
146
|
-
result.errors.push(
|
|
147
|
-
return result
|
|
129
|
+
result.isValid = false
|
|
130
|
+
result.errors.push('不能包含连续数字')
|
|
131
|
+
return result
|
|
148
132
|
}
|
|
149
133
|
|
|
150
|
-
// 4. 检查连续字母
|
|
151
134
|
if (hasConsecutiveLetters(password)) {
|
|
152
|
-
result.isValid = false
|
|
153
|
-
result.errors.push(
|
|
154
|
-
return result
|
|
135
|
+
result.isValid = false
|
|
136
|
+
result.errors.push('不能包含连续字母')
|
|
137
|
+
return result
|
|
155
138
|
}
|
|
156
139
|
|
|
157
|
-
// 5. 检查重复字符
|
|
158
140
|
if (hasRepeatedChars(password)) {
|
|
159
|
-
result.isValid = false
|
|
160
|
-
result.errors.push(
|
|
161
|
-
return result
|
|
141
|
+
result.isValid = false
|
|
142
|
+
result.errors.push('不能包含3个或以上相同字符')
|
|
143
|
+
return result
|
|
162
144
|
}
|
|
163
145
|
|
|
164
|
-
// 6. 检查键盘模式
|
|
165
146
|
if (hasKeyboardPattern(password)) {
|
|
166
|
-
result.isValid = false
|
|
167
|
-
result.errors.push(
|
|
168
|
-
return result
|
|
147
|
+
result.isValid = false
|
|
148
|
+
result.errors.push('不能包含键盘连续按键模式')
|
|
149
|
+
return result
|
|
169
150
|
}
|
|
170
151
|
|
|
171
|
-
return result
|
|
172
|
-
}
|
|
152
|
+
return result
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function isStrongPassword (password) {
|
|
156
|
+
return validateStrongPasswordPhone(password).isValid
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function getPasswordStrength (password) {
|
|
160
|
+
if (!password) {
|
|
161
|
+
return {
|
|
162
|
+
label: '未输入',
|
|
163
|
+
type: 'default',
|
|
164
|
+
desc: '请输入密码以查看强度',
|
|
165
|
+
visible: false
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const { isValid, errors } = validateStrongPasswordPhone(password)
|
|
170
|
+
if (isValid) {
|
|
171
|
+
return {
|
|
172
|
+
label: '强',
|
|
173
|
+
type: 'success',
|
|
174
|
+
desc: '密码满足复杂度要求',
|
|
175
|
+
visible: true
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
label: '弱',
|
|
181
|
+
type: 'error',
|
|
182
|
+
desc: errors[0] || '密码不满足安全要求',
|
|
183
|
+
visible: true
|
|
184
|
+
}
|
|
185
|
+
}
|