diff --git a/src/api/auth.ts b/src/api/auth.ts index 5597967ef..99aeefc5c 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import http from '@/common/http' -import { AuthzSetting, ImportResult, Metrics } from '@/types/auth' +import { AuthnItem, AuthzSetting, ImportResult, Metrics } from '@/types/auth' -export function listAuthn(params = {}) { +export function listAuthn(params = {}): Promise { return http.get('/authentication', { params }) } diff --git a/src/hooks/Auth/useAuthn.ts b/src/hooks/Auth/useAuthn.ts index 2446a6294..e83ad364d 100644 --- a/src/hooks/Auth/useAuthn.ts +++ b/src/hooks/Auth/useAuthn.ts @@ -1,7 +1,7 @@ import { listAuthn, queryAuthnItemMetrics } from '@/api/auth' -import { AuthnItem, Metrics } from '@/types/auth' -import { SortableEvent } from 'sortablejs' import jwtIcon from '@/assets/img/jwt.png' +import { AuthnItem, Metrics } from '@/types/auth' +import { AuthnMechanismType } from '@/types/enum' export type AuthnItemInTable = AuthnItem & { metrics?: Metrics @@ -10,14 +10,9 @@ export type AuthnItemInTable = AuthnItem & { export default (): { isListLoading: Ref authnList: Ref - tableCom: Ref getAuthnItemBackendForShow: (item: AuthnItemInTable) => string getAuthnList: (isInit?: boolean) => Promise updateAuthnItemMetrics: (authn: AuthnItem) => Promise - moveAuthnUp: (index: number) => Promise - moveAuthnDown: (index: number) => Promise - moveAuthnToTop: (authn: AuthnItem) => any - moveAuthnToBottom: (authn: AuthnItem) => any } => { const isListLoading = ref(false) const authnList: Ref> = ref([]) @@ -45,13 +40,13 @@ export default (): { const res: AuthnItem[] = await listAuthn() authnList.value = res.map((item) => { const ret: AuthnItemInTable = item - if (ret.mechanism !== 'jwt' && ret.mechanism !== 'cinfo') { + if (ret.mechanism !== 'jwt' && ret.mechanism !== AuthnMechanismType.CINFO) { try { ret.img = getImg(`img/${ret.backend}.png`) } catch { ret.img = '' } - } else if (ret.mechanism === 'cinfo') { + } else if (ret.mechanism === AuthnMechanismType.CINFO) { ret.img = getImg(`img/cinfo.png`) } else { ret.img = jwtIcon @@ -60,8 +55,6 @@ export default (): { return item }) setAddedAuthn() - await nextTick() - initSortable() } catch (error) { console.error(error) } finally { @@ -108,67 +101,13 @@ export default (): { } } - const { - moveAuthnBeforeAnotherAuthn, - moveAuthnAfterAnotherAuthn, - moveAuthnToTop: requestMoveAuthnToTop, - moveAuthnToBottom: requestMoveAuthnToBottom, - } = useHandleAuthnItem() - const moveAuthnUp = async (index: number) => handleDragEvent(index - 1, index, authnList.value) - const moveAuthnDown = async (index: number) => handleDragEvent(index + 1, index, authnList.value) - const moveAuthnToTop = async (row: AuthnItem) => { - try { - await requestMoveAuthnToTop(row) - } catch (error) { - // empty the array first when an error occurs, otherwise the view will not be updated - authnList.value = [] - } finally { - getAuthnList() - } - } - const moveAuthnToBottom = async (row: AuthnItem) => { - try { - await requestMoveAuthnToBottom(row) - } catch (error) { - // empty the array first when an error occurs, otherwise the view will not be updated - authnList.value = [] - } finally { - getAuthnList() - } - } - const { handleDragEvent } = useMove( - { - moveToBottom: moveAuthnToBottom, - moveToTop: moveAuthnToTop, - moveBeforeAnotherTarget: moveAuthnBeforeAnotherAuthn, - moveAfterAnotherTarget: moveAuthnAfterAnotherAuthn, - }, - undefined, - getAuthnList, - ) - - const handleOrderChanged = async (evt: SortableEvent) => { - const { newIndex, oldIndex } = evt - if (newIndex === undefined || oldIndex === undefined) { - return - } - handleDragEvent(newIndex, oldIndex, authnList.value) - } - - const { tableCom, initSortable } = useSortableTable(handleOrderChanged) - initTableData() return { isListLoading, authnList, - tableCom, getAuthnItemBackendForShow, getAuthnList, updateAuthnItemMetrics, - moveAuthnUp, - moveAuthnDown, - moveAuthnToTop, - moveAuthnToBottom, } } diff --git a/src/hooks/Auth/useBuiltInDatabaseAuthn.ts b/src/hooks/Auth/useBuiltInDatabaseAuthn.ts new file mode 100644 index 000000000..eb8f1c258 --- /dev/null +++ b/src/hooks/Auth/useBuiltInDatabaseAuthn.ts @@ -0,0 +1,20 @@ +import { AuthnMechanismType, DatabasesType } from '@/types/enum' + +const useBuiltInDatabaseAuthn = () => { + const defaultAuthnId = `${AuthnMechanismType.PasswordBased}:${DatabasesType.BuiltInDatabase}` + + const { t } = useI18n() + const getFiledLabel = (field: 'clientid' | 'username') => { + const fieldMap = { + clientid: t('Base.clientid'), + username: t('Base.username'), + } + return fieldMap[field] + } + return { + defaultAuthnId, + getFiledLabel, + } +} + +export default useBuiltInDatabaseAuthn diff --git a/src/i18n/Auth.ts b/src/i18n/Auth.ts index f3793a09c..f4af7a3cc 100644 --- a/src/i18n/Auth.ts +++ b/src/i18n/Auth.ts @@ -63,10 +63,6 @@ export default { zh: '数据库', en: 'Database', }, - noBackendDataSourceDesc: { - zh: '{ mechanism } 认证无需选择数据源,请继续下一步配置', - en: '{ mechanism } authentication does not require a backend, continue to the next step', - }, reconnect: { zh: '自动重连', en: 'Reconnect', @@ -898,4 +894,8 @@ Find more information about Variform expressions in EMQX doc.`, zh: '存在重复的权限配置', en: 'Duplicated permission configuration', }, + extended: { + zh: '扩展', + en: 'Extended', + }, } diff --git a/src/i18n/components.ts b/src/i18n/components.ts index f0a991184..8c6965b1e 100644 --- a/src/i18n/components.ts +++ b/src/i18n/components.ts @@ -55,6 +55,14 @@ export default { zh: '客户端认证', en: 'Authentication', }, + 'authentication-default': { + zh: '默认认证', + en: 'Default Authentication', + }, + 'authentication-extended': { + zh: '扩展认证', + en: 'Extended Authentication', + }, authorization: { zh: '客户端授权', en: 'Authorization', diff --git a/src/router/index.ts b/src/router/index.ts index f9c2f89a5..3fc858cb0 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -233,15 +233,21 @@ export const routes: Array = [ { path: '/authentication', component: Layout, + redirect: { name: 'authentication-default' }, meta: { hideKey: 'authentication', authRequired: true, }, children: [ { - path: '', - name: 'authentication', - component: () => import('@/views/Auth/Authn.vue'), + path: 'default', + name: 'authentication-default', + component: () => import('@/views/Auth/AuthnDefault.vue'), + }, + { + path: 'extended', + name: 'authentication-extended', + component: () => import('@/views/Auth/AuthnExtended.vue'), }, { path: 'create', diff --git a/src/types/auth.d.ts b/src/types/auth.d.ts index 322871b39..bd9f248af 100644 --- a/src/types/auth.d.ts +++ b/src/types/auth.d.ts @@ -71,12 +71,15 @@ export interface BuiltInDBItem { username: string } -export interface DataManagerItem { +export interface AuthnUser { user_id: string - password: string is_superuser: boolean } +export interface DataManagerItem extends AuthnUser { + password: string +} + export type Metrics = MetricsDataWithExtraData<{ node_status: Array<{ node: string diff --git a/src/views/Auth/AuthnCreate.vue b/src/views/Auth/AuthnCreate.vue index c729afceb..8498ae181 100644 --- a/src/views/Auth/AuthnCreate.vue +++ b/src/views/Auth/AuthnCreate.vue @@ -1,7 +1,7 @@ -

- {{ - $t('Auth.noBackendDataSourceDesc', { - mechanism: getMechanismLabel(mechanism as AuthnMechanismType), - }) - }} -

-
- - {{ $t('Base.backStep') }} - - - {{ $t('Base.nextStep') }} - -
- - -
- - - - -
-
- {{ isWork ? $t('Auth.testSuccess') : $t('Auth.testFailed') }} +
+ {{ isWork ? $t('Auth.testSuccess') : $t('Auth.testFailed') }} +
@@ -183,6 +175,7 @@
+ @@ -258,7 +251,7 @@ const { authnMechanismTypeList } = useAuthnMechanismType() const supportBackendMap: BackendMap = { password_based: { - built_in_database: tl('builtInDatabase'), + ...(props.gateway ? { built_in_database: tl('builtInDatabase') } : {}), mysql: 'MySQL', mongodb: 'MongoDB', postgresql: 'PostgreSQL', @@ -309,7 +302,7 @@ const hasDatabaseToChoose = computed(() => { const needSelectInSecondStep = computed(() => databases.value.length + others.value.length > 0) const getGuideList = function () { - return [t('Auth.mechanism'), t('Auth.dataSource'), t('Auth.config')] + return [t('Auth.mechanism'), t('Auth.config')] } const findFirstDatabaseDidNotAdd = () => { @@ -385,16 +378,23 @@ const beforeNext = function () { setDefaultBackendForGateway() } guideDescList.value.push(getMechanismLabel(mechanism.value as AuthnMechanismType)) - } else if (step.value === 1) { - const data = factory(mechanism.value, backend.value) - configData.value = checkPresetDataAndSet(data) - if (mechanism.value !== 'jwt') { - guideDescList.value.push(titleMap[backend.value]) - } } } const { step, activeGuidesIndex, guideDescList, handleNext, handleBack } = useGuide(beforeNext) +const showConfig = ref(true) +const handleBackendChange = async (newBackend: DatabaseAndServer | 'built_in_database') => { + showConfig.value = false + const data = factory(mechanism.value, newBackend) + configData.value = checkPresetDataAndSet(data) + if (mechanism.value !== 'jwt') { + guideDescList.value.push(titleMap[newBackend]) + } + backend.value = newBackend + await nextTick() + showConfig.value = true +} + const handleCreate = async function () { const isVerified = (await formCom.value.validate().catch(() => { jumpToErrorFormItem() @@ -433,7 +433,7 @@ const cancelCreate = async function () { if (props.gateway) { props.cancelFunc() } else { - router.push('/authentication') + router.push({ name: 'authentication-extended' }) } } diff --git a/src/views/Auth/AuthnDefault.vue b/src/views/Auth/AuthnDefault.vue new file mode 100644 index 000000000..75a53b848 --- /dev/null +++ b/src/views/Auth/AuthnDefault.vue @@ -0,0 +1,192 @@ + + + + + diff --git a/src/views/Auth/AuthnDetails.vue b/src/views/Auth/AuthnDetails.vue index 4e117ce39..b0859aac6 100644 --- a/src/views/Auth/AuthnDetails.vue +++ b/src/views/Auth/AuthnDetails.vue @@ -3,7 +3,7 @@
+ + + + diff --git a/src/views/Auth/AuthzCreate.vue b/src/views/Auth/AuthzCreate.vue index e2a4ebcb4..9d73f32a2 100644 --- a/src/views/Auth/AuthzCreate.vue +++ b/src/views/Auth/AuthzCreate.vue @@ -2,75 +2,73 @@
- -
+

{{ tl('dataSourceAuthzDesc') }}

- - - + + - - {{ item.label }} - - - -
- - - {{ $t('Base.nextStep') }} - + + + + + + {{ item.label }} + + + + + + + + +
+ + + + + +
-
- -
- - - - - -
- - {{ $t('Base.backStep') }} - + ('file') const configData = ref({}) const saveLoading = ref(false) @@ -127,17 +122,19 @@ const typeList = ref([ { label: 'LDAP', value: 'ldap', img: ldapIcon }, { label: tl('HTTPServer'), value: 'http', img: httpIcon }, ]) -const { titleMap } = useAuth() -const { step, activeGuidesIndex, handleNext, handleBack, guideDescList } = useGuide(() => { - if (step.value === 0) { - if (!type.value) { - return - } - const data = factory(type.value) - configData.value = data - guideDescList.value.push(titleMap[type.value]) + +const isConfigShow = ref(true) +const handleBackendChange = async (newBackend: string) => { + if (!newBackend) { + return } -}) + isConfigShow.value = false + const data = factory(newBackend) + configData.value = data + type.value = newBackend + await nextTick() + isConfigShow.value = true +} const addedAuthz = computed>(() => { const stored = sessionStorage.getItem('addedAuthz') diff --git a/src/views/Auth/components/AuthnManager.vue b/src/views/Auth/components/AuthnManager.vue index b5f542518..1877a89a3 100644 --- a/src/views/Auth/components/AuthnManager.vue +++ b/src/views/Auth/components/AuthnManager.vue @@ -30,100 +30,37 @@ {{ t('Base.add') }}
- - - - - - - - - - - - + - - - - - - - - - -
- -

- {{ $t('Auth.isSuperuserDesc') }} -

-
-
-
- -
+ :authn-id="id" + :field="field" + :user="currentItem" + :gateway="gateway" + @save="loadData" + />
+ + diff --git a/src/views/Auth/components/AuthnUserDialog.vue b/src/views/Auth/components/AuthnUserDialog.vue new file mode 100644 index 000000000..5c9f8add2 --- /dev/null +++ b/src/views/Auth/components/AuthnUserDialog.vue @@ -0,0 +1,178 @@ + + + + + diff --git a/src/views/Auth/components/AuthnUserTable.vue b/src/views/Auth/components/AuthnUserTable.vue new file mode 100644 index 000000000..70ecec217 --- /dev/null +++ b/src/views/Auth/components/AuthnUserTable.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/src/views/Auth/components/TableDropdown.vue b/src/views/Auth/components/TableDropdown.vue index 17a298576..ff688098b 100644 --- a/src/views/Auth/components/TableDropdown.vue +++ b/src/views/Auth/components/TableDropdown.vue @@ -18,31 +18,6 @@