Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/chat/serializers/chat_user_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def _get_login_policy(cls, access_token):
)
portal = Portal.objects.first()
if portal is None or not portal.enable_auth:
raise AppApiException(500, _("Portal authentication is not enabled"))
return ("portal", 1, 5, 10)
auth_config = portal.auth_config or {}
if "LOCAL" not in auth_config.get("login_value", ["LOCAL"]):
raise AppApiException(500, _("Portal local login is not enabled"))
Expand Down
13 changes: 11 additions & 2 deletions ui/src/conversation-panel/left-sidebar/account-menu/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, ref, useTemplateRef } from 'vue'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { useStore } from '@/stores/chat'
import { formatTokenNumber } from '@/utils/number'
import { QUOTA_TYPE } from '@/api/enums'
Expand All @@ -13,6 +13,7 @@ defineOptions({ name: 'ConversationAccountMenu' })
const { account } = useConversationListStore()
const { auth } = useStore()
const router = useRouter()
const route = useRoute()

const menuVisible = ref(false)
const displayName = computed(() => account.value?.nickName || account.value?.username || '用户')
Expand All @@ -34,6 +35,14 @@ const handleLogout = () => {
.then(() => router.replace({ path: router.currentRoute.value.fullPath, force: true }))
.catch(() => {})
}

// 匿名用户主动登录,登录成功后回到当前地址;透传钉钉客户端入口参数
const goLogin = () => {
const query = { redirect: route.fullPath, client: route.query.client, corpId: route.query.corpId }
return router.push(
route.meta.portal ? { name: 'portal-login', query } : { name: 'chat-login', params: { accessToken: route.params.accessToken }, query },
)
}
</script>

<template>
Expand Down Expand Up @@ -101,7 +110,7 @@ const handleLogout = () => {
</template>
</MkDropdown>
<!-- 匿名登陆 -->
<el-button v-else type="primary" class="w-full">立即登录</el-button>
<el-button v-else type="primary" class="w-full" @click="goLogin">立即登录</el-button>
<UserPwdDialog ref="userPwdDialogRef" />
<ApiKeyDialog ref="apiKeyDialogRef" />
</template>
Expand Down
4 changes: 2 additions & 2 deletions ui/src/router/ROUTE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ Chat 导航守卫(`chat/index.ts`):
2. 获取目标场景的认证前置配置(`AuthProfile`),与当前场景相同时复用。accessToken 无效、应用已停用或门户
未开放导致获取失败时,进入 `chat-not-found` 并保留原地址;匿名认证失败时同样处理。
3. 判断时只读取目标场景在本地存储中的 token,不切换 Store 的当前场景。
4. `enable_auth` 为 false 时登录页无用:进入登录页会被重定向到 `redirect` 记录的原地址,没有时进入
当前场景首页(`portal-home` 或 `chat-home`),再按下一条匿名认证。
4. 登录页始终放行:`enable_auth` 为 true 时必须登录;为 false 时匿名用户也可从账户菜单主动登录,
登录成功后回到 `redirect` 记录的原地址。
5. 进入登录页或已有可用 token 时,调用 `auth.activate()` 切换当前场景后放行。`enable_auth` 为 true 时,
匿名认证颁发的 token(载荷 `login_type` 为 `ANNOTATION`,由 `isAnonymousToken` 判断)不可用,
即使本地已保存也跳转登录页;该 token 保留在本地存储,登录时携带。
Expand Down
9 changes: 1 addition & 8 deletions ui/src/router/chat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ function getLoginRoute(scope: string, to: RouteLocationNormalized) {
return scope === PORTAL_AUTH_SCOPE ? { name: 'portal-login', query } : { name: 'chat-login', params: { accessToken: scope }, query }
}

/** 未开启认证时登录页无用,回到 `redirect` 记录的原地址,没有时进入当前场景首页。 */
function getLoginRedirectRoute(scope: string, to: RouteLocationNormalized) {
const { redirect } = to.query
if (typeof redirect === 'string' && redirect.startsWith('/')) return { path: redirect, replace: true }
return scope === PORTAL_AUTH_SCOPE ? { name: 'portal-home', replace: true } : { name: 'chat-home', params: { accessToken: scope }, replace: true }
}

/** 渲染 404 页面并保留原地址,刷新时可重新尝试。 */
function getNotFoundRoute(to: RouteLocationNormalized) {
return { name: 'chat-not-found', params: { pathMatch: to.path.substring(1).split('/') }, query: to.query, hash: to.hash }
Expand All @@ -56,8 +49,8 @@ chatRouter.beforeEach(async (to) => {
return getNotFoundRoute(to)
}

// 登录页始终放行:开启认证时必须登录,未开启认证时匿名用户也可主动登录
const isLoginRoute = LOGIN_ROUTE_NAMES.has(String(to.name))
if (isLoginRoute && !authProfile.enable_auth) return getLoginRedirectRoute(scope, to)

// 判断时只读取目标场景已保存的 token,放行前再切换当前场景,避免导航未完成时请求带上目标场景的 token
// 开启认证后,此前保存的匿名 token 不再放行,需要登录;本地存储保留,登录时携带以沿用同一对话用户
Expand Down
Loading