slider-captcha-sdk 1.0.9 → 1.0.10

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.
@@ -0,0 +1,207 @@
1
+ import JSEncrypt from 'jsencrypt';
2
+
3
+ /**
4
+ * 密码校验工具类
5
+ * 提供密码加密和校验功能
6
+ */
7
+ class PasswordValidator {
8
+ constructor(options = {}) {
9
+ this.options = {
10
+ // 获取公钥的接口地址
11
+ publicKeyUrl: options.publicKeyUrl || '/microservice/strongPassword/getPublicKey',
12
+ // 密码校验接口地址
13
+ validateUrl: options.validateUrl || '/microservice/strongPassword/checkPassword',
14
+ // 请求超时时间
15
+ timeout: options.timeout || 10000,
16
+ // 自定义请求头
17
+ headers: options.headers || {},
18
+ ...options
19
+ };
20
+
21
+ // 缓存公钥,避免重复请求
22
+ this.publicKeyCache = null;
23
+ this.publicKeyExpiry = null;
24
+ }
25
+
26
+ /**
27
+ * 获取公钥
28
+ * @returns {Promise<string>} 公钥字符串
29
+ */
30
+ async getPublicKey() {
31
+ // 检查缓存是否有效(5分钟有效期)
32
+ if (this.publicKeyCache && this.publicKeyExpiry && Date.now() < this.publicKeyExpiry) {
33
+ return this.publicKeyCache
34
+ }
35
+
36
+ try {
37
+ const response = await this.makeRequest(this.options.publicKeyUrl, {
38
+ method: 'GET'
39
+ });
40
+
41
+ if (response.code !== '0' ) {
42
+ throw new Error('获取公钥失败:' + (response.message || '未知错误'))
43
+ }
44
+
45
+ // 缓存公钥,设置5分钟过期时间
46
+ this.publicKeyCache = response.data;
47
+ this.publicKeyExpiry = Date.now() + 5 * 60 * 1000;
48
+
49
+ return this.publicKeyCache
50
+ } catch (error) {
51
+ console.error('获取公钥失败:', error);
52
+ throw new Error('获取公钥失败: ' + error.message)
53
+ }
54
+ }
55
+
56
+ /**
57
+ * 使用RSA公钥加密密码
58
+ * @param {string} password 原始密码
59
+ * @param {string} publicKey 公钥字符串
60
+ * @returns {string} 加密后的密码
61
+ */
62
+ encryptPassword(password, publicKey) {
63
+ try {
64
+ // 使用导入的JSEncrypt进行RSA加密
65
+ if (!JSEncrypt) {
66
+ throw new Error('JSEncrypt库未正确加载')
67
+ }
68
+
69
+ const encrypt = new JSEncrypt();
70
+ encrypt.setPublicKey(publicKey);
71
+ const encrypted = encrypt.encrypt(password);
72
+
73
+ if (!encrypted) {
74
+ throw new Error('密码加密失败')
75
+ }
76
+
77
+ return encrypted
78
+ } catch (error) {
79
+ console.error('密码加密失败:', error);
80
+ throw new Error('密码加密失败: ' + error.message)
81
+ }
82
+ }
83
+
84
+ /**
85
+ * 校验密码
86
+ * @param {string} password 原始密码
87
+ * @param {string} userName 用户
88
+ * @param {Object} additionalData 额外的校验数据
89
+ * @returns {Promise<Object>} 校验结果
90
+ */
91
+ async validatePassword(password, userName, additionalData = {}) {
92
+ try {
93
+ // 1. 获取公钥
94
+ const publicKey = await this.getPublicKey();
95
+
96
+ // 2. 加密密码
97
+ const encryptedPassword = this.encryptPassword(password, publicKey);
98
+
99
+ // 3. 调用校验接口
100
+ const response = await this.makeRequest(this.options.validateUrl, {
101
+ method: 'POST',
102
+ body: JSON.stringify({
103
+ userName: userName,
104
+ password: encryptedPassword,
105
+ timestamp: Date.now(),
106
+ ...additionalData
107
+ })
108
+ });
109
+
110
+ return {
111
+ success: response.success,
112
+ message: response.message,
113
+ data: response.data,
114
+ code: response.code
115
+ }
116
+ } catch (error) {
117
+ console.error('密码校验失败:', error);
118
+ return {
119
+ success: false,
120
+ message: error.message,
121
+ code: 'VALIDATION_ERROR'
122
+ }
123
+ }
124
+ }
125
+
126
+ /**
127
+ * 发送HTTP请求的通用方法
128
+ * @param {string} url 请求地址
129
+ * @param {Object} options 请求选项
130
+ * @returns {Promise<Object>} 响应结果
131
+ */
132
+ async makeRequest(url, options = {}) {
133
+ const controller = new AbortController();
134
+ const timeoutId = setTimeout(() => controller.abort(), this.options.timeout);
135
+
136
+ try {
137
+ const response = await fetch(url, {
138
+ ...options,
139
+ headers: {
140
+ 'Content-Type': 'application/json',
141
+ ...this.options.headers,
142
+ ...options.headers
143
+ },
144
+ signal: controller.signal
145
+ });
146
+
147
+ clearTimeout(timeoutId);
148
+
149
+ if (!response.ok) {
150
+ throw new Error(`HTTP错误: ${response.status} ${response.statusText}`)
151
+ }
152
+
153
+ return await response.json()
154
+ } catch (error) {
155
+ clearTimeout(timeoutId);
156
+
157
+ if (error.name === 'AbortError') {
158
+ throw new Error('请求超时')
159
+ }
160
+
161
+ throw error
162
+ }
163
+ }
164
+
165
+ /**
166
+ * 清除公钥缓存
167
+ */
168
+ clearCache() {
169
+ this.publicKeyCache = null;
170
+ this.publicKeyExpiry = null;
171
+ }
172
+
173
+ /**
174
+ * 更新配置
175
+ * @param {Object} newOptions 新的配置选项
176
+ */
177
+ updateOptions(newOptions) {
178
+ this.options = { ...this.options, ...newOptions };
179
+ // 清除缓存,使用新配置重新获取
180
+ this.clearCache();
181
+ }
182
+ }
183
+
184
+ /**
185
+ * 创建密码校验器实例的工厂函数
186
+ * @param {Object} options 配置选项
187
+ * @returns {PasswordValidator} 密码校验器实例
188
+ */
189
+ function createPasswordValidator(options) {
190
+ return new PasswordValidator(options)
191
+ }
192
+
193
+ /**
194
+ * 快速校验密码的便捷函数
195
+ * @param {string} password 密码
196
+ * @param {Object} options 配置选项
197
+ * @param {Object} additionalData 额外数据
198
+ * @returns {Promise<Object>} 校验结果
199
+ */
200
+ async function validatePassword(password, options = {}, additionalData = {}) {
201
+ const validator = new PasswordValidator(options);
202
+ // 修复:添加userName参数,可以从additionalData中提取或设为空字符串
203
+ const userName = additionalData.userName || '';
204
+ return await validator.validatePassword(password, userName, additionalData)
205
+ }
206
+
207
+ export { createPasswordValidator, PasswordValidator as default, validatePassword };