优化钉钉工作台自动免登
This commit is contained in:
parent
73f574add4
commit
1d39ff253a
@ -3,14 +3,43 @@ import dd from "dingtalk-jsapi";
|
|||||||
import { getDingTalkConfig, loginWithDingTalk } from "@/api/auth";
|
import { getDingTalkConfig, loginWithDingTalk } from "@/api/auth";
|
||||||
import type { AuthTokenData } from "@/types/auth";
|
import type { AuthTokenData } from "@/types/auth";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
dingtalk?: { platform?: { invokeAPI?: unknown } };
|
||||||
|
DingTalkJSBridge?: unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function isDingTalkContainer() {
|
export function isDingTalkContainer() {
|
||||||
return (
|
if (typeof window === "undefined" || typeof navigator === "undefined")
|
||||||
typeof navigator !== "undefined" && /DingTalk/i.test(navigator.userAgent)
|
return false;
|
||||||
|
const userAgent =
|
||||||
|
navigator.userAgent ||
|
||||||
|
(navigator as Navigator & { swuserAgent?: string }).swuserAgent ||
|
||||||
|
"";
|
||||||
|
return Boolean(
|
||||||
|
/DingTalk|dingtalk-win|dd-web/i.test(userAgent) ||
|
||||||
|
window.DingTalkJSBridge ||
|
||||||
|
window.dingtalk?.platform?.invokeAPI ||
|
||||||
|
// DingTalk desktop can expose its container identity through window.name
|
||||||
|
// even when the embedded browser omits DingTalk from userAgent.
|
||||||
|
/dingtalk/i.test(window.name || ""),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function waitForDingTalkContainer(timeoutMs = 5000) {
|
||||||
|
if (isDingTalkContainer()) return true;
|
||||||
|
const startedAt = Date.now();
|
||||||
|
while (Date.now() - startedAt < timeoutMs) {
|
||||||
|
await new Promise((resolve) => window.setTimeout(resolve, 100));
|
||||||
|
if (isDingTalkContainer()) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
export async function authenticateWithDingTalk(): Promise<AuthTokenData> {
|
export async function authenticateWithDingTalk(): Promise<AuthTokenData> {
|
||||||
if (!isDingTalkContainer()) throw new Error("请从钉钉工作台打开此应用");
|
if (!(await waitForDingTalkContainer()))
|
||||||
|
throw new Error("请从钉钉工作台打开此应用");
|
||||||
const configResponse = await getDingTalkConfig();
|
const configResponse = await getDingTalkConfig();
|
||||||
const config = configResponse.data.data;
|
const config = configResponse.data.data;
|
||||||
if (!config) throw new Error("钉钉免登配置不完整");
|
if (!config) throw new Error("钉钉免登配置不完整");
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {
|
|||||||
import { computed, onMounted, ref } from "vue";
|
import { computed, onMounted, ref } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
import { isDingTalkContainer } from "@/api/dingtalk";
|
import { waitForDingTalkContainer } from "@/api/dingtalk";
|
||||||
import { useAuthStore } from "@/stores/auth.store";
|
import { useAuthStore } from "@/stores/auth.store";
|
||||||
|
|
||||||
const auth = useAuthStore();
|
const auth = useAuthStore();
|
||||||
@ -19,6 +19,7 @@ const useDevelopmentLogin = ref(true);
|
|||||||
const username = ref("local-admin");
|
const username = ref("local-admin");
|
||||||
const password = ref("risk-admin-2026");
|
const password = ref("risk-admin-2026");
|
||||||
const autoDingTalkAttempted = ref(false);
|
const autoDingTalkAttempted = ref(false);
|
||||||
|
const autoDingTalk = ref(false);
|
||||||
|
|
||||||
// 登录后的统一落点是智能对话页,避免从其他受保护页面跳转到登录后
|
// 登录后的统一落点是智能对话页,避免从其他受保护页面跳转到登录后
|
||||||
// 又回到原页面,保证用户进入系统后先看到对话工作台。
|
// 又回到原页面,保证用户进入系统后先看到对话工作台。
|
||||||
@ -49,11 +50,14 @@ async function submitDingTalk() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
if (!isDingTalkContainer() || autoDingTalkAttempted.value) return;
|
if (autoDingTalkAttempted.value) return;
|
||||||
|
const inDingTalk = await waitForDingTalkContainer();
|
||||||
|
if (!inDingTalk || autoDingTalkAttempted.value) return;
|
||||||
autoDingTalkAttempted.value = true;
|
autoDingTalkAttempted.value = true;
|
||||||
|
autoDingTalk.value = true;
|
||||||
mode.value = "dingtalk";
|
mode.value = "dingtalk";
|
||||||
void submitDingTalk();
|
await submitDingTalk();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -144,6 +148,7 @@ onMounted(() => {
|
|||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
|
v-if="!autoDingTalk || auth.error"
|
||||||
class="login-submit"
|
class="login-submit"
|
||||||
type="button"
|
type="button"
|
||||||
:disabled="auth.loading"
|
:disabled="auth.loading"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user