chore: 准备前端开源安全状态
This commit is contained in:
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Wang Yuanyou
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -71,3 +71,7 @@ pnpm build
|
|||||||
- 事故复盘草稿
|
- 事故复盘草稿
|
||||||
|
|
||||||
模型调用、脱敏、审计、白名单知识库和密钥管理由后端代理实现。
|
模型调用、脱敏、审计、白名单知识库和密钥管理由后端代理实现。
|
||||||
|
|
||||||
|
## 开源许可
|
||||||
|
|
||||||
|
本仓库使用 MIT License。提交公开仓库前请确认 `.env`、部署密钥和真实第三方 token 未进入 Git 历史或提交内容。
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"name": "devops-platform-web",
|
"name": "devops-platform-web",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import type {
|
|||||||
JenkinsSyncSummary,
|
JenkinsSyncSummary,
|
||||||
LoginPayload,
|
LoginPayload,
|
||||||
LoginResult,
|
LoginResult,
|
||||||
|
MemberCredentialResult,
|
||||||
MemberSummary,
|
MemberSummary,
|
||||||
NotificationOutboxMessage,
|
NotificationOutboxMessage,
|
||||||
PipelineStep,
|
PipelineStep,
|
||||||
@@ -309,8 +310,10 @@ export const devopsApi = {
|
|||||||
return Array.isArray(data) ? data : []
|
return Array.isArray(data) ? data : []
|
||||||
},
|
},
|
||||||
|
|
||||||
async createMember(payload: CreateMemberPayload): Promise<MemberSummary> {
|
async createMember(
|
||||||
const { data } = await http.post<MemberSummary>('/members', payload)
|
payload: CreateMemberPayload,
|
||||||
|
): Promise<MemberCredentialResult> {
|
||||||
|
const { data } = await http.post<MemberCredentialResult>('/members', payload)
|
||||||
lastDataSource = 'backend'
|
lastDataSource = 'backend'
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
@@ -327,8 +330,10 @@ export const devopsApi = {
|
|||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
async resetMemberPassword(memberId: string): Promise<MemberSummary> {
|
async resetMemberPassword(
|
||||||
const { data } = await http.post<MemberSummary>(
|
memberId: string,
|
||||||
|
): Promise<MemberCredentialResult> {
|
||||||
|
const { data } = await http.post<MemberCredentialResult>(
|
||||||
`/members/${memberId}/reset-password`,
|
`/members/${memberId}/reset-password`,
|
||||||
)
|
)
|
||||||
lastDataSource = 'backend'
|
lastDataSource = 'backend'
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ export interface MemberSummary {
|
|||||||
projectPermissions: MemberProjectPermission[]
|
projectPermissions: MemberProjectPermission[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MemberCredentialResult extends MemberSummary {
|
||||||
|
temporaryPassword: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface ProjectPermissionPayload {
|
export interface ProjectPermissionPayload {
|
||||||
projectKey: string
|
projectKey: string
|
||||||
level: ProjectPermissionLevel
|
level: ProjectPermissionLevel
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const redirect = computed(() =>
|
|||||||
const roleHint = computed(() =>
|
const roleHint = computed(() =>
|
||||||
loginRole.value === 'super_admin'
|
loginRole.value === 'super_admin'
|
||||||
? '超级管理员不提供忘记密码入口,请通过服务器运维方式重置。'
|
? '超级管理员不提供忘记密码入口,请通过服务器运维方式重置。'
|
||||||
: '普通成员首次登录或重置密码后,必须先修改初始密码。',
|
: '普通成员首次登录或重置密码后,必须先修改临时密码。',
|
||||||
)
|
)
|
||||||
const isSuperAdminLogin = computed(() => loginRole.value === 'super_admin')
|
const isSuperAdminLogin = computed(() => loginRole.value === 'super_admin')
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import type {
|
|||||||
AuthRole,
|
AuthRole,
|
||||||
AuthStatus,
|
AuthStatus,
|
||||||
CreateMemberPayload,
|
CreateMemberPayload,
|
||||||
|
MemberCredentialResult,
|
||||||
MemberSummary,
|
MemberSummary,
|
||||||
PlatformMessageState,
|
PlatformMessageState,
|
||||||
PlatformMessageSummary,
|
PlatformMessageSummary,
|
||||||
@@ -262,7 +263,7 @@ async function createMember() {
|
|||||||
const member = await devopsApi.createMember(payload)
|
const member = await devopsApi.createMember(payload)
|
||||||
upsertMember(member)
|
upsertMember(member)
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
ElMessage.success('成员已创建,初始密码为 111111')
|
await showTemporaryPassword(member, '成员已创建')
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updatePermissions() {
|
async function updatePermissions() {
|
||||||
@@ -282,7 +283,7 @@ async function updatePermissions() {
|
|||||||
|
|
||||||
async function resetPassword(member: MemberSummary) {
|
async function resetPassword(member: MemberSummary) {
|
||||||
await ElMessageBox.confirm(
|
await ElMessageBox.confirm(
|
||||||
`确认将 ${member.displayName} 的密码重置为 111111?`,
|
`确认为 ${member.displayName} 生成一次性临时密码?`,
|
||||||
'重置密码',
|
'重置密码',
|
||||||
{
|
{
|
||||||
confirmButtonText: '重置',
|
confirmButtonText: '重置',
|
||||||
@@ -293,7 +294,21 @@ async function resetPassword(member: MemberSummary) {
|
|||||||
const updated = await devopsApi.resetMemberPassword(member.id)
|
const updated = await devopsApi.resetMemberPassword(member.id)
|
||||||
upsertMember(updated)
|
upsertMember(updated)
|
||||||
await loadMessages()
|
await loadMessages()
|
||||||
ElMessage.success('密码已重置')
|
await showTemporaryPassword(updated, '临时密码已生成')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function showTemporaryPassword(
|
||||||
|
member: MemberCredentialResult,
|
||||||
|
title: string,
|
||||||
|
) {
|
||||||
|
await ElMessageBox.alert(
|
||||||
|
`请将以下临时密码安全发送给 ${member.displayName},成员首次登录后必须修改密码。\n\n${member.temporaryPassword}`,
|
||||||
|
title,
|
||||||
|
{
|
||||||
|
confirmButtonText: '我已记录',
|
||||||
|
type: 'success',
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function toggleStatus(member: MemberSummary) {
|
async function toggleStatus(member: MemberSummary) {
|
||||||
|
|||||||
Reference in New Issue
Block a user