diff --git a/frontend/src/locales/en.ts b/frontend/src/locales/en.ts index 37b8880..cf923aa 100644 --- a/frontend/src/locales/en.ts +++ b/frontend/src/locales/en.ts @@ -59,6 +59,9 @@ export default { enterOldAndNewPassword: 'Please enter current and new password', passwordsDoNotMatch: 'The two passwords do not match', passwordChangeFailed: 'Failed to change password', + myVpnConnections: 'My VPN Connections', + noConnections: 'No active connections', + abnormalConnectionHint: 'If you notice any abnormal connections, please change your password to disconnect all devices.', }, about: { title: 'About LmVPN', diff --git a/frontend/src/locales/zh.ts b/frontend/src/locales/zh.ts index 7ac506c..eab44ed 100644 --- a/frontend/src/locales/zh.ts +++ b/frontend/src/locales/zh.ts @@ -59,6 +59,9 @@ export default { enterOldAndNewPassword: '请填写原密码和新密码', passwordsDoNotMatch: '两次输入的新密码不一致', passwordChangeFailed: '密码修改失败', + myVpnConnections: '我的 VPN 连接', + noConnections: '暂无在线连接', + abnormalConnectionHint: '如发现异常连接,请修改密码以断开所有设备', }, about: { title: '关于 LmVPN', diff --git a/frontend/src/views/ProfileView.vue b/frontend/src/views/ProfileView.vue index 3269821..1192413 100644 --- a/frontend/src/views/ProfileView.vue +++ b/frontend/src/views/ProfileView.vue @@ -8,8 +8,29 @@ const authStore = useAuthStore() const router = useRouter() const { t } = useI18n() +interface VpnConnection { + ip: string + ip6?: string + connected_at: string +} +const vpnConnections = ref([]) +const maxConns = ref(30) + +async function fetchVpnConnections() { + try { + const res = await fetch('/api/me/vpn/connections', { + headers: { Authorization: `Bearer ${authStore.token}` }, + }) + if (!res.ok) return + const data = await res.json() + vpnConnections.value = data.connections || [] + maxConns.value = data.max_conns_per_user || 30 + } catch {} +} + onMounted(async () => { await authStore.fetchUser() + fetchVpnConnections() }) const showPasswordModal = ref(false) @@ -73,6 +94,35 @@ async function handleChangePassword() { +
+
+

{{ t('profile.myVpnConnections') }}

+ + {{ vpnConnections.length }} / {{ maxConns }} + +
+ + + + + + + + + + + + + + + + + + +
{{ t('vpn.ipv4') }}{{ t('vpn.ipv6') }}{{ t('vpn.connectTime') }}
{{ t('profile.noConnections') }}
{{ c.ip }}{{ c.ip6 || '-' }}{{ c.connected_at }}
+

{{ t('profile.abnormalConnectionHint') }}

+
+