mirror of https://gitee.com/godoos/godoos.git
7 changed files with 100 additions and 379 deletions
@ -1,101 +0,0 @@ |
|||||
function getOSInfo() { |
|
||||
const userAgent = navigator.userAgent; |
|
||||
if (/windows phone/i.test(userAgent)) { |
|
||||
return 'Windows Phone'; |
|
||||
} |
|
||||
if (/win/i.test(userAgent)) { |
|
||||
return 'Windows'; |
|
||||
} |
|
||||
if (/mac/i.test(userAgent)) { |
|
||||
return 'Mac'; |
|
||||
} |
|
||||
if (/x11/i.test(userAgent)) { |
|
||||
return 'UNIX'; |
|
||||
} |
|
||||
if (/android/i.test(userAgent)) { |
|
||||
return 'Android'; |
|
||||
} |
|
||||
if (/iphone|ipad|ipod/i.test(userAgent)) { |
|
||||
return 'iOS'; |
|
||||
} |
|
||||
return 'Unknown'; |
|
||||
} |
|
||||
|
|
||||
function bin2hex(s) { |
|
||||
s = encodeURI(s); // 只会有0-127的ascii不转化
|
|
||||
let m = s.match(/%[\dA-F]{2}/g), a = s.split(/%[\dA-F]{2}/), i, j, n, t; |
|
||||
m.push(""); |
|
||||
for (i in a) { |
|
||||
if (a[i] === "") { a[i] = m[i]; continue; } |
|
||||
n = ""; |
|
||||
for (j in a[i]) { |
|
||||
t = a[i][j].charCodeAt().toString(16).toUpperCase(); |
|
||||
if (t.length === 1) t = "0" + t; |
|
||||
n += "%" + t; |
|
||||
} |
|
||||
a[i] = n + m[i]; |
|
||||
} |
|
||||
return a.join("").split("%").join(""); |
|
||||
} |
|
||||
|
|
||||
function getBrowserFingerprint() { |
|
||||
const canvas = document.createElement('canvas'); |
|
||||
const ctx = canvas.getContext('2d'); // 移除类型声明
|
|
||||
const txt = window.location.hostname; |
|
||||
ctx.textBaseline = 'top'; |
|
||||
ctx.font = '14px \'Arial\''; |
|
||||
ctx.textBaseline = 'alphabetic'; |
|
||||
ctx.fillStyle = '#f60'; |
|
||||
ctx.fillRect(125, 1, 62, 20); |
|
||||
ctx.fillStyle = '#069'; |
|
||||
ctx.fillText(txt, 2, 15); |
|
||||
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)'; |
|
||||
ctx.fillText(txt, 4, 17); |
|
||||
|
|
||||
const b64 = canvas.toDataURL().replace("data:image/png;base64,", ""); |
|
||||
const bin = window.atob(b64); |
|
||||
const hash = bin2hex(bin.slice(-16, -12)); |
|
||||
|
|
||||
const fingerprint = [ |
|
||||
navigator.platform, |
|
||||
navigator.product, |
|
||||
navigator.productSub, |
|
||||
navigator.appName, |
|
||||
navigator.appVersion, |
|
||||
navigator.javaEnabled(), |
|
||||
navigator.userAgent, |
|
||||
screen.width, |
|
||||
screen.height, |
|
||||
new Date().getTimezoneOffset(), |
|
||||
hash, |
|
||||
screen.colorDepth, |
|
||||
navigator.language, |
|
||||
navigator.hardwareConcurrency, |
|
||||
getOSInfo(), |
|
||||
navigator.maxTouchPoints, |
|
||||
navigator.doNotTrack, |
|
||||
navigator.cookieEnabled |
|
||||
].join('|'); |
|
||||
|
|
||||
return fingerprint; |
|
||||
} |
|
||||
|
|
||||
function djb2Hash(str) { |
|
||||
let hash = 5381; |
|
||||
for (let i = 0; i < str.length; i++) { |
|
||||
const char = str.charCodeAt(i); |
|
||||
hash = ((hash << 5) + hash) + char; /* hash * 33 + c */ |
|
||||
} |
|
||||
return hash.toString(36); // Convert to base 36 for shorter string
|
|
||||
} |
|
||||
|
|
||||
function GetClientId() { |
|
||||
let uuid = localStorage.getItem("ClientID"); |
|
||||
if (!uuid) { |
|
||||
const fingerprint = getBrowserFingerprint(); |
|
||||
uuid = djb2Hash(fingerprint).slice(0, 36); |
|
||||
localStorage.setItem("ClientID", uuid); |
|
||||
} |
|
||||
|
|
||||
return uuid; |
|
||||
} |
|
@ -1,167 +0,0 @@ |
|||||
const getSystemConfig = (ifset = false) => { |
|
||||
const configSetting = localStorage.getItem('GodoOS-config') || '{}'; |
|
||||
let config = JSON.parse(configSetting); |
|
||||
|
|
||||
config.version ??= '1.0.4'; |
|
||||
config.isFirstRun ??= false; |
|
||||
config.lang ??= ''; |
|
||||
config.apiUrl ??= `${window.location.protocol}//${window.location.hostname}:56780`; |
|
||||
config.userType ??= 'person'; |
|
||||
config.editorType ??= 'local'; |
|
||||
config.onlyoffice ??= { url: '', secret: '' }; |
|
||||
config.file ??= { isPwd: 0, pwd: '' }; |
|
||||
config.fileInputPwd ??= []; |
|
||||
config.userInfo ??= { |
|
||||
url: '', |
|
||||
username: '', |
|
||||
password: '', |
|
||||
id: 0, |
|
||||
nickname: '', |
|
||||
avatar: '', |
|
||||
email: '', |
|
||||
phone: '', |
|
||||
desc: '', |
|
||||
job_number: '', |
|
||||
work_place: '', |
|
||||
hired_date: '', |
|
||||
ding_id: '', |
|
||||
role_id: 0, |
|
||||
roleName: '', |
|
||||
dept_id: 0, |
|
||||
deptName: '', |
|
||||
token: '', |
|
||||
user_auths: '', |
|
||||
user_shares: '', |
|
||||
isPwd: false |
|
||||
}; |
|
||||
|
|
||||
config.isApp = window.go ? true : false; |
|
||||
config.systemInfo ??= {}; |
|
||||
config.theme ??= 'light'; |
|
||||
config.storeType ??= localStorage.getItem('GodoOS-storeType') || 'local'; |
|
||||
config.storePath ??= ''; |
|
||||
config.netPath ??= ''; |
|
||||
config.netPort ??= '56780'; |
|
||||
config.background ??= { |
|
||||
url: '/image/bg/bg6.jpg', |
|
||||
type: 'image', |
|
||||
color: 'rgba(30, 144, 255, 1)', |
|
||||
imageList: [ |
|
||||
'/image/bg/bg1.jpg', |
|
||||
'/image/bg/bg2.jpg', |
|
||||
'/image/bg/bg3.jpg', |
|
||||
'/image/bg/bg4.jpg', |
|
||||
'/image/bg/bg5.jpg', |
|
||||
'/image/bg/bg6.jpg', |
|
||||
'/image/bg/bg7.jpg', |
|
||||
'/image/bg/bg8.jpg', |
|
||||
'/image/bg/bg9.jpg', |
|
||||
] |
|
||||
}; |
|
||||
|
|
||||
config.account ??= { ad: false, username: '', password: '' }; |
|
||||
if (config.userType === 'member') { |
|
||||
config.account.ad = false; |
|
||||
} |
|
||||
config.storenet ??= { url: '', username: '', password: '', isCors: '' }; |
|
||||
config.webdavClient ??= { url: '', username: '', password: '' }; |
|
||||
config.dbInfo ??= { url: '', username: '', password: '', dbname: '' }; |
|
||||
config.chatConf ??= { |
|
||||
checkTime: '15', |
|
||||
first: '192', |
|
||||
second: '168', |
|
||||
thirdStart: '1', |
|
||||
thirdEnd: '1', |
|
||||
fourthStart: '2', |
|
||||
fourthEnd: '254' |
|
||||
}; |
|
||||
|
|
||||
config.desktopList ??= []; |
|
||||
config.menuList ??= []; |
|
||||
config.token ??= generateRandomString(16); |
|
||||
config = parseAiConfig(config); |
|
||||
|
|
||||
if (ifset) { |
|
||||
setSystemConfig(config); |
|
||||
} |
|
||||
|
|
||||
return config; |
|
||||
}; |
|
||||
|
|
||||
const setSystemConfig = (config) => { |
|
||||
localStorage.setItem('GodoOS-config', JSON.stringify(config)); |
|
||||
localStorage.setItem('GodoOS-storeType', config.storeType); |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
function generateRandomString(length) { |
|
||||
let result = ''; |
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
|
||||
const charactersLength = characters.length; |
|
||||
for (let i = 0; i < length; i++) { |
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength)); |
|
||||
} |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
const parseAiConfig = (config) => { |
|
||||
if (!config.ollamaUrl) { |
|
||||
config.ollamaUrl = `${window.location.protocol}//${window.location.hostname}:11434` |
|
||||
} |
|
||||
if (!config.ollamaDir) { |
|
||||
config.ollamaDir = '' |
|
||||
} |
|
||||
if (!config.aiDir) { |
|
||||
config.aiDir = '' |
|
||||
} |
|
||||
if (!config.aiUrl) { |
|
||||
config.aiUrl = config.apiUrl |
|
||||
} |
|
||||
//openai
|
|
||||
if (!config.openaiUrl) { |
|
||||
config.openaiUrl = 'https://api.openai.com/v1' |
|
||||
} |
|
||||
if (!config.openaiSecret) { |
|
||||
config.openaiSecret = "" |
|
||||
} |
|
||||
//gitee
|
|
||||
if (!config.giteeSecret) { |
|
||||
config.giteeSecret = "" |
|
||||
} |
|
||||
//cloudflare
|
|
||||
if (!config.cloudflareUserId) { |
|
||||
config.cloudflareUserId = "" |
|
||||
} |
|
||||
if (!config.cloudflareSecret) { |
|
||||
config.cloudflareSecret = "" |
|
||||
} |
|
||||
if (!config.deepseekSecret) { |
|
||||
config.deepseekSecret = "" |
|
||||
} |
|
||||
if (!config.bigmodelSecret) { |
|
||||
config.bigmodelSecret = "" |
|
||||
} |
|
||||
if (!config.volcesSecret) { |
|
||||
config.volcesSecret = "" |
|
||||
} |
|
||||
if (!config.alibabaSecret) { |
|
||||
config.alibabaSecret = "" |
|
||||
} |
|
||||
if (!config.groqSecret) { |
|
||||
config.groqSecret = "" |
|
||||
} |
|
||||
if (!config.mistralSecret) { |
|
||||
config.mistralSecret = "" |
|
||||
} |
|
||||
if (!config.anthropicSecret) { |
|
||||
config.anthropicSecret = "" |
|
||||
} |
|
||||
if (!config.llamafamilySecret) { |
|
||||
config.llamafamilySecret = "" |
|
||||
} |
|
||||
if (!config.siliconflowSecret) { |
|
||||
config.siliconflowSecret = "" |
|
||||
} |
|
||||
return config |
|
||||
}; |
|
@ -1,111 +0,0 @@ |
|||||
<!DOCTYPE html> |
|
||||
<html> |
|
||||
<head> |
|
||||
<meta charset="utf-8" /> |
|
||||
<title>钉钉授权页面</title> |
|
||||
<meta |
|
||||
name="renderer" |
|
||||
content="webkit" |
|
||||
/> |
|
||||
<meta |
|
||||
http-equiv="X-UA-Compatible" |
|
||||
content="IE=edge,chrome=1" |
|
||||
/> |
|
||||
<meta |
|
||||
http-equiv="Cache-Control" |
|
||||
content="no-cache, no-store, must-revalidate" |
|
||||
/> |
|
||||
<meta |
|
||||
name="viewport" |
|
||||
content="width=device-width, initial-scale=1" |
|
||||
/> |
|
||||
</head> |
|
||||
<script src="https://g.alicdn.com/dingding/dingtalk-jsapi/3.0.12/dingtalk.open.js"></script> |
|
||||
<script src="./clientid.js"></script> |
|
||||
<script src="./config.js"></script> |
|
||||
<body> |
|
||||
<div id="ding"></div> |
|
||||
<script> |
|
||||
// 页面加载完成后执行登录 |
|
||||
window.onload = function () { |
|
||||
getCropId(); |
|
||||
}; |
|
||||
|
|
||||
async function getCropId() { |
|
||||
try { |
|
||||
const res = await fetch( |
|
||||
"http://server001.godoos.com/user/ding/conf" |
|
||||
); |
|
||||
const data = await res.json(); |
|
||||
if (data.success) { |
|
||||
await getCode(data.data.id); |
|
||||
} else { |
|
||||
ElMessage.error("获取钉钉配置失败"); |
|
||||
} |
|
||||
} catch (e) { |
|
||||
throw e; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 获取code登录 |
|
||||
async function getCode(corpId) { |
|
||||
dd.runtime.permission.requestAuthCode({ |
|
||||
corpId: corpId, |
|
||||
onSuccess: async function (result) { |
|
||||
await toLogin(result.code); |
|
||||
}, |
|
||||
onFail: function (err) { |
|
||||
document.getElementById("ding").innerHTML = |
|
||||
JSON.stringify(err); |
|
||||
}, |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
// 登录接口 |
|
||||
async function toLogin(code) { |
|
||||
const data = { |
|
||||
login_type: "dingtalk_workbench", |
|
||||
client_id: GetClientId(), |
|
||||
param: { |
|
||||
code, |
|
||||
}, |
|
||||
}; |
|
||||
document.getElementById("ding").innerHTML = |
|
||||
JSON.stringify(data); |
|
||||
const res = await fetch( |
|
||||
"http://server001.godoos.com/user/login", |
|
||||
{ |
|
||||
method: "POST", |
|
||||
body: JSON.stringify(data), |
|
||||
} |
|
||||
); |
|
||||
const jsondata = await res.json(); |
|
||||
if (jsondata.success) { |
|
||||
document.getElementById("ding").innerHTML = |
|
||||
JSON.stringify(jsondata); |
|
||||
// 从本地存储中尝试获取配置信息,若不存在则使用默认空对象 |
|
||||
const config = getSystemConfig(); |
|
||||
jsondata.data.url = config.userInfo.url; |
|
||||
config.userInfo = jsondata.data; |
|
||||
document.getElementById("ding").innerHTML = |
|
||||
JSON.stringify(config); |
|
||||
setSystemConfig(config); |
|
||||
window.location.href = "http://osadmin.godoos.com/"; |
|
||||
|
|
||||
// setStorage("Authorization", resData.data.token); |
|
||||
// setStorage("ClientID", resData.data.client_id); |
|
||||
// 缓存用户数据 |
|
||||
// const userData = { |
|
||||
// userDept: resData.data.dept, |
|
||||
// userInfo: resData.data.user, |
|
||||
// }; |
|
||||
// setStorage("userData", userData); |
|
||||
ElMessage.success("登录成功"); |
|
||||
// router.push("/knowledge/#/home"); |
|
||||
} else { |
|
||||
ElMessage.error("登录失败"); |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
</body> |
|
||||
</html> |
|
@ -0,0 +1,78 @@ |
|||||
|
import { GetClientId } from "@/util/clientid"; |
||||
|
import dd from "dingtalk-jsapi"; |
||||
|
import { getSystemConfig, setSystemConfig } from "./config"; |
||||
|
|
||||
|
const config = getSystemConfig(); |
||||
|
// 函数用于动态加载外部JS文件
|
||||
|
function loadScript(url: string): Promise<void> { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
const script = document.createElement('script') |
||||
|
script.src = url |
||||
|
script.onload = () => resolve() |
||||
|
script.onerror = () => reject(new Error(`Failed to load script ${url}`)) |
||||
|
document.head.appendChild(script) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const currentUrl = window.location.origin |
||||
|
|
||||
|
export async function getCropId(): Promise<boolean> { |
||||
|
try { |
||||
|
const res = await fetch(currentUrl + "/user/ding/conf"); |
||||
|
const data = await res.json(); |
||||
|
console.log(data) |
||||
|
if (data.success) { |
||||
|
console.log(data.data.id) |
||||
|
alert(data.data.host); |
||||
|
return await getCode(data.data.id); |
||||
|
} |
||||
|
return false; |
||||
|
} catch (e) { |
||||
|
console.error(e); |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 获取code登录
|
||||
|
async function getCode(corpId: string): Promise<boolean> { |
||||
|
// 加载钉钉登录脚本
|
||||
|
await loadScript("https://g.alicdn.com/dingding/dingtalk-jsapi/3.0.12/dingtalk.open.js") |
||||
|
|
||||
|
return new Promise((resolve) => { |
||||
|
dd.runtime.permission.requestAuthCode({ |
||||
|
corpId: corpId, |
||||
|
onSuccess: async function (result: { code: string }) { |
||||
|
resolve(await toLogin(result.code)); |
||||
|
}, |
||||
|
onFail: function (err: any) { |
||||
|
console.log(err) |
||||
|
resolve(false); |
||||
|
}, |
||||
|
} as any); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// 登录接口
|
||||
|
async function toLogin(this: any, code: string): Promise<boolean> { |
||||
|
const data = { |
||||
|
login_type: "dingtalk_workbench", |
||||
|
client_id: GetClientId(), |
||||
|
param: { |
||||
|
code, |
||||
|
}, |
||||
|
}; |
||||
|
const res = await fetch(currentUrl + "/user/login", { |
||||
|
method: "POST", |
||||
|
body: JSON.stringify(data), |
||||
|
}); |
||||
|
const jsondata = await res.json(); |
||||
|
if (jsondata.success) { |
||||
|
jsondata.data.url = currentUrl; |
||||
|
config.userInfo = jsondata.data; |
||||
|
config.userType = "member"; |
||||
|
setSystemConfig(config); |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
Loading…
Reference in new issue