R88 贯通企微直登设备指纹
这个提交包含在:
@@ -1,4 +1,28 @@
|
||||
const DEVICE_FINGERPRINT_KEY = "hyb_oa_device_fingerprint";
|
||||
export const DEVICE_FINGERPRINT_KEY = "hyb_oa_device_fingerprint";
|
||||
|
||||
function readCookieFingerprint() {
|
||||
if (typeof document === "undefined") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const prefix = `${DEVICE_FINGERPRINT_KEY}=`;
|
||||
const item = document.cookie
|
||||
.split(";")
|
||||
.map((value) => value.trim())
|
||||
.find((value) => value.startsWith(prefix));
|
||||
|
||||
if (!item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const rawValue = item.slice(prefix.length);
|
||||
try {
|
||||
const decoded = decodeURIComponent(rawValue);
|
||||
return decoded.trim() ? decoded : null;
|
||||
} catch {
|
||||
return rawValue.trim() ? rawValue : null;
|
||||
}
|
||||
}
|
||||
|
||||
function fallbackFingerprint() {
|
||||
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
||||
@@ -17,6 +41,12 @@ export function getDeviceFingerprint() {
|
||||
return "server-render";
|
||||
}
|
||||
|
||||
const cookieFingerprint = readCookieFingerprint();
|
||||
if (cookieFingerprint) {
|
||||
window.localStorage.setItem(DEVICE_FINGERPRINT_KEY, cookieFingerprint);
|
||||
return cookieFingerprint;
|
||||
}
|
||||
|
||||
const existing = window.localStorage.getItem(DEVICE_FINGERPRINT_KEY);
|
||||
if (existing) {
|
||||
return existing;
|
||||
|
||||
@@ -140,9 +140,12 @@ export function resolveWecomBindNotice(value: string | null): WecomNotice | null
|
||||
return null;
|
||||
}
|
||||
|
||||
export function buildWecomLoginUrl(loginUrl: string, returnTo: string) {
|
||||
export function buildWecomLoginUrl(loginUrl: string, returnTo: string, deviceFingerprint?: string) {
|
||||
const baseOrigin = typeof window !== "undefined" ? window.location.origin : "http://127.0.0.1";
|
||||
const url = new URL(loginUrl, baseOrigin);
|
||||
url.searchParams.set("returnTo", returnTo);
|
||||
if (deviceFingerprint) {
|
||||
url.searchParams.set("deviceFingerprint", deviceFingerprint);
|
||||
}
|
||||
return url.origin === baseOrigin ? `${url.pathname}${url.search}` : url.toString();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { fetchSsoProviders, fetchWecomConfig } from "../api/auth";
|
||||
import { mapApiErrorMessage } from "../api/errorMessages";
|
||||
import { isApiError } from "../api/types";
|
||||
import { useAuth } from "../auth/AuthContext";
|
||||
import { getDeviceFingerprint } from "../auth/deviceFingerprint";
|
||||
import { Button } from "../components/ui/button";
|
||||
import { Input } from "../components/ui/input";
|
||||
import { Label } from "../components/ui/label";
|
||||
@@ -99,7 +100,7 @@ export function LoginPage() {
|
||||
if (!wecomEntry?.loginUrl) {
|
||||
return;
|
||||
}
|
||||
window.location.assign(buildWecomLoginUrl(wecomEntry.loginUrl, redirectTo));
|
||||
window.location.assign(buildWecomLoginUrl(wecomEntry.loginUrl, redirectTo, getDeviceFingerprint()));
|
||||
}
|
||||
|
||||
function renderPasswordPanel(testId: string, primary: boolean) {
|
||||
|
||||
在新工单中引用
屏蔽一个用户