Skip to content

Commit 9f80c69

Browse files
committed
feat: 添加web登录 closes #11
1 parent e6b7b67 commit 9f80c69

File tree

7 files changed

+95
-7
lines changed

7 files changed

+95
-7
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ lerna-debug.log*
2525
node_modules/
2626
config/config/pm2.yaml
2727
index.js
28+
plugins/
2829
pnpm-workspace.yaml
2930
@karinjs/
3031
/dist

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ pnpm add @karinjs/plugin-basic -w
2020

2121
```
2222
# 插件列表
23-
```
23+
```
24+
25+
```
26+
#web登录
27+
```

config/config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"status": true,
33
"forward": true,
44
"restartMode": true,
5-
"restart": true
5+
"restart": true,
6+
"domain": ""
67
}

package.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@
3030
"karin": "karin"
3131
},
3232
"devDependencies": {
33-
"@types/node": "^20.17.30",
34-
"eslint": "^9.24.0",
33+
"@types/node": "^24.0.1",
34+
"eslint": "^9.29.0",
3535
"neostandard": "^0.12.1",
36-
"node-karin": "^1.8.12",
37-
"tsup": "^8.4.0",
38-
"tsx": "^4.19.3",
36+
"node-karin": "^1.10.7",
37+
"tsup": "^8.5.0",
38+
"tsx": "^4.20.3",
3939
"typescript": "^5.8.3"
4040
},
4141
"publishConfig": {
@@ -58,5 +58,8 @@
5858
],
5959
"ts-web": "src/web.config.ts",
6060
"web": "dist/web.config.js"
61+
},
62+
"dependencies": {
63+
"internal-ip": "^8.0.0"
6164
}
6265
}

src/apps/login.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { config } from '@/utils/config'
2+
import karin, { common, contactFriend, logger, segment } from 'node-karin'
3+
import axios from 'node-karin/axios'
4+
import os from 'node:os'
5+
6+
const url = { IPv4: ['https://4.ipw.cn'], IPv6: ['https://6.ipw.cn'] }
7+
8+
export const login = karin.command(/#?(|web)$/i, async (e) => {
9+
const net = os.networkInterfaces()
10+
const cfg = config()
11+
const IP: { lan: { ipv4: null | string, ipv6: null | string }, net: { ipv4: null | string, ipv6: null | string } } =
12+
{ lan: { ipv4: null, ipv6: null }, net: { ipv4: null, ipv6: null } }
13+
for (const i in net) {
14+
for (const iface of net[i]!) {
15+
if (iface.internal) continue
16+
if (iface.family === 'IPv4') {
17+
const ip = iface.address
18+
if (
19+
ip.startsWith('192.168.') ||
20+
ip.startsWith('10.') ||
21+
(ip.startsWith('172.') && parseInt(ip.split('.')[1]) >= 16 && parseInt(ip.split('.')[1]) <= 31)
22+
) {
23+
IP.lan.ipv4 = ip
24+
}
25+
} else if (iface.family === 'IPv6') {
26+
const ip = iface.address
27+
if (ip.startsWith('fd') || ip.startsWith('fe80:') || ip.startsWith('fc')) {
28+
IP.lan.ipv6 = ip
29+
}
30+
}
31+
}
32+
}
33+
IP.net.ipv4 = await getnetIP('IPv4')
34+
IP.net.ipv6 = await getnetIP('IPv6')
35+
const port = process.env.HTTP_PORT
36+
const token = process.env.HTTP_AUTH_KEY
37+
const msg = [segment.text('面板登录地址:')]
38+
if (cfg.domain) msg.push(segment.text(`- 自定义域名: ${cfg.domain}/web/login?token=${token}`))
39+
msg.push(segment.text(`- 内网地址: ${IP.lan.ipv4 ? `http://${IP.lan.ipv4}:${port}/web/login?token=${token}` : `http://${IP.lan.ipv4}:${port}/web/login?token=${token}`}`))
40+
if (IP.net.ipv4) msg.push(segment.text(`- 外网IPv4地址: http://${IP.net.ipv4}:${port}/web/login?token=${token}`))
41+
if (IP.net.ipv6) msg.push(segment.text(`- 外网IPv6地址: http://${IP.net.ipv6}:${port}/web/login?token=${token}`))
42+
try {
43+
const content = common.makeForward(msg, e.selfId, e.bot.account.name)
44+
await e.bot.sendForwardMsg(contactFriend(e.userId), content)
45+
if (e.isGroup) await e.reply('登录地址已经私信给主人了哦~')
46+
} catch (err) {
47+
msg.forEach(item => {
48+
item.text = item.text + '\n'
49+
})
50+
await e.bot.sendMsg(contactFriend(e.userId), msg)
51+
if (e.isGroup) await e.reply('登录地址已经私信给主人了哦~')
52+
return true
53+
}
54+
return true
55+
}, { name: '面板登录', perm: 'admin' })
56+
57+
async function getnetIP (type: 'IPv4' | 'IPv6') {
58+
for (const i of url[type] || []) {
59+
try {
60+
const res = await axios.get(i)
61+
if (res.data) {
62+
return res.data
63+
}
64+
} catch (e) {
65+
logger.error(`访问${i}获取外网${type}地址失败: ${e}`)
66+
continue
67+
}
68+
}
69+
return null
70+
}

src/types/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ export interface Config {
88
restartMode: boolean
99
/** 更新完成是否自动重启 */
1010
restart: boolean
11+
/** 自定义登录域名 */
12+
domain: string
1113
}

src/web.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ export default {
4343
label: '自动重启',
4444
description: '更新完成是否自动重启',
4545
defaultSelected: cfg.restart
46+
}),
47+
components.input.string('domain', {
48+
color: 'success',
49+
label: '自定义域名',
50+
description: 'Web登录发送的自定义域名',
51+
defaultValue: cfg.domain,
52+
isRequired: false
4653
})
4754
]
4855

0 commit comments

Comments
 (0)