Skip to content

Commit 8a48a6b

Browse files
committed
refactor: replace node-forge with jsencrypt for RSA encryption
1 parent 0af31dd commit 8a48a6b

4 files changed

Lines changed: 34 additions & 31 deletions

File tree

ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@
3636
"highlight.js": "^11.11.1",
3737
"html-to-image": "^1.11.13",
3838
"html2canvas": "^1.4.1",
39+
"jsencrypt": "^3.5.4",
3940
"jspdf": "^4.1.0",
4041
"katex": "^0.16.10",
4142
"marked": "^12.0.2",
4243
"md-editor-v3": "^5.8.2",
4344
"mermaid": "^11.12.0",
4445
"moment": "^2.30.1",
4546
"nanoid": "^5.1.5",
46-
"node-forge": "^1.3.1",
4747
"nprogress": "^0.2.0",
4848
"pdfjs-dist": "^5.6.205",
4949
"pinia": "^3.0.1",

ui/src/views/chat/user-login/index.vue

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ import QrCodeTab from '@/views/chat/user-login/scanCompinents/QrCodeTab.vue'
180180
import {MsgConfirm, MsgError} from '@/utils/message.ts'
181181
import PasswordAuth from '@/views/chat/auth/component/password.vue'
182182
import {isAppIcon, loadScript} from '@/utils/common'
183-
import forge from "node-forge";
184183
import * as dd from "dingtalk-jsapi";
184+
import JSEncrypt from "jsencrypt";
185185
186186
useResize()
187187
const router = useRouter()
@@ -251,11 +251,13 @@ const loginHandle = () => {
251251
})
252252
})
253253
} else {
254-
const publicKey = forge.pki.publicKeyFromPem(chatUser?.chat_profile?.rsaKey as any);
254+
// JSEncrypt 在有些打包环境可能作为 default export 或直接导出,兼容两种情况
255+
const JSEncryptCtor = (JSEncrypt as any)?.default ? (JSEncrypt as any).default : JSEncrypt;
256+
const js = new (JSEncryptCtor as any)();
257+
js.setPublicKey(chatUser?.chat_profile?.rsaKey as any);
255258
const jsonData = JSON.stringify(loginForm.value);
256-
const utf8Bytes = forge.util.encodeUtf8(jsonData);
257-
const encrypted = publicKey.encrypt(utf8Bytes, 'RSAES-PKCS1-V1_5');
258-
const encryptedBase64 = forge.util.encode64(encrypted);
259+
const encryptedBase64 = js.encrypt(jsonData);
260+
259261
chatUser.login({
260262
encryptedData: encryptedBase64,
261263
username: loginForm.value.username

ui/src/views/login/index.vue

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ import QrCodeTab from '@/views/login/scanCompinents/QrCodeTab.vue'
141141
import {MsgConfirm, MsgError} from '@/utils/message.ts'
142142
import * as dd from 'dingtalk-jsapi'
143143
import {loadScript} from '@/utils/common'
144-
import forge from 'node-forge';
144+
import JSEncrypt from 'jsencrypt';
145145
146146
const router = useRouter()
147147
const {login, user, theme} = useStore()
@@ -200,12 +200,13 @@ const loginHandle = () => {
200200
loading.value = false
201201
})
202202
} else {
203-
const publicKey = forge.pki.publicKeyFromPem(user.rsaKey);
204-
// 转换为UTF-8编码后再加密
203+
// JSEncrypt 在有些打包环境可能作为 default export 或直接导出,兼容两种情况
204+
const JSEncryptCtor = (JSEncrypt as any)?.default ? (JSEncrypt as any).default : JSEncrypt;
205+
const js = new (JSEncryptCtor as any)();
206+
js.setPublicKey(user.rsaKey);
205207
const jsonData = JSON.stringify(loginForm.value);
206-
const utf8Bytes = forge.util.encodeUtf8(jsonData);
207-
const encrypted = publicKey.encrypt(utf8Bytes, 'RSAES-PKCS1-V1_5');
208-
const encryptedBase64 = forge.util.encode64(encrypted);
208+
const encryptedBase64 = js.encrypt(jsonData);
209+
209210
login
210211
.asyncLogin({encryptedData: encryptedBase64, username: loginForm.value.username})
211212
.then(() => {

ui/src/views/system/user-manage/component/UserDrawer.vue

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -115,21 +115,21 @@
115115
</el-dialog>
116116
</template>
117117
<script setup lang="ts">
118-
import { ref, reactive, watch, onBeforeMount, computed } from 'vue'
119-
import type { FormInstance } from 'element-plus'
118+
import {computed, onBeforeMount, reactive, ref, watch} from 'vue'
119+
import type {FormInstance} from 'element-plus'
120120
import userManageApi from '@/api/system/user-manage'
121-
import { MsgSuccess } from '@/utils/message'
122-
import { t } from '@/locales'
123-
import type { FormItemModel } from '@/api/type/role'
121+
import {MsgSuccess} from '@/utils/message'
122+
import {t} from '@/locales'
123+
import type {FormItemModel} from '@/api/type/role'
124124
import WorkspaceApi from '@/api/workspace/workspace'
125125
import MemberFormContent from '@/views/system/role/component/MemberFormContent.vue'
126-
import { AuthorizationEnum, RoleTypeEnum } from '@/enums/system'
126+
import {AuthorizationEnum, RoleTypeEnum} from '@/enums/system'
127127
import useStore from '@/stores'
128-
import { hasPermission } from '@/utils/permission'
129-
import { EditionConst } from '@/utils/permission/data.ts'
130-
import forge from 'node-forge'
128+
import {hasPermission} from '@/utils/permission'
129+
import {EditionConst} from '@/utils/permission/data.ts'
130+
import JSEncrypt from "jsencrypt";
131131
132-
const { user } = useStore()
132+
const {user} = useStore()
133133
const props = defineProps({
134134
title: String,
135135
})
@@ -289,7 +289,7 @@ onBeforeMount(async () => {
289289
}
290290
formItemModel.value = [...roleFormItem.value, ...workspaceFormItem.value]
291291
}
292-
list.value = [{ role_id: '', workspace_ids: [] }]
292+
list.value = [{role_id: '', workspace_ids: []}]
293293
})
294294
295295
const rules = reactive({
@@ -361,7 +361,7 @@ watch(visible, (bool) => {
361361
nick_name: '',
362362
}
363363
isEdit.value = false
364-
list.value = [{ role_id: '', workspace_ids: [] }]
364+
list.value = [{role_id: '', workspace_ids: []}]
365365
userFormRef.value?.clearValidate()
366366
}
367367
})
@@ -405,12 +405,12 @@ const submit = async (formEl: FormInstance | undefined) => {
405405
406406
// 如果是管理员角色,则设置为 ['None']
407407
if (isAdminRole) {
408-
return { ...item, workspace_ids: ['None'] }
408+
return {...item, workspace_ids: ['None']}
409409
}
410410
411411
// 如果是普通用户且是 PE 类型,则设置为 ['default']
412412
if (user.isPE()) {
413-
return { ...item, workspace_ids: ['default'] }
413+
return {...item, workspace_ids: ['default']}
414414
}
415415
416416
// 其他情况保持原样
@@ -431,10 +431,10 @@ const submit = async (formEl: FormInstance | undefined) => {
431431
})
432432
} else {
433433
params.defaultPermission = defaultPermission.value
434-
const publicKey = forge.pki.publicKeyFromPem(user.rsaKey)
435-
const utf8Bytes = forge.util.encodeUtf8(params.password)
436-
const encrypted = publicKey.encrypt(utf8Bytes, 'RSAES-PKCS1-V1_5')
437-
params.password = forge.util.encode64(encrypted)
434+
const JSEncryptCtor = (JSEncrypt as any)?.default ? (JSEncrypt as any).default : JSEncrypt;
435+
const js = new (JSEncryptCtor as any)();
436+
js.setPublicKey(user.rsaKey);
437+
params.password = js.encrypt(params.password);
438438
params.encrypted = true
439439
userManageApi.postUserManage(params, loading).then((res) => {
440440
return user.profile(loading).then(() => {
@@ -461,7 +461,7 @@ const submitDialog = () => {
461461
closeDialog()
462462
}
463463
464-
defineExpose({ open })
464+
defineExpose({open})
465465
</script>
466466
<style lang="scss" scoped>
467467
.dialog-header {

0 commit comments

Comments
 (0)