feat: 授权延长——同事一键申请,管理员批准时决定时长;时长支持 30 分钟与自定义

同事端
- 用过邀请链接的设备再次打开链接时显示自己的授权状态:有效时可申请延长,
  访问结束(到期或通道关闭)后 2 小时内也可以;超过 2 小时或被撤销则提示重新获取邀请
- 「申请延长」只有一个按钮,提交后复用审批状态页,批准后显示新的到期时间
- 用过链接的设备不再自动重新放通,统一走申请延长

网关
- 授权结束后保留 2 小时的记录(通道关闭后仍保留,随状态文件持久化);撤销的不能延长,
  删除通道 / 解散组时一并清除(unregister 带 deleted 标记)
- 新增 extend_lease:有效授权从原到期时间顺延,已结束的从现在起算,不受通道最长开启时长截断,
  并批准该设备的延长申请;指标里带上全部可延长设备与申请(包括已关闭的通道)
- 授权时长支持分钟数("30m"、"90m",5 分钟到 30 天)

Agent / App / 网页面板
- POST .../leases/extend:通道已关闭时先自动开启(组则全组开启),并让通道至少开到授权结束
- 授权管理新增「申请延长」「最近结束 · 2 小时内可延长」,已授权设备可直接「延长」;
  卡片、菜单栏和系统通知提示延长申请,菜单栏可直接选时长批准
- 邀请的可访问时长、通道最长开启时长增加 30 分钟与自定义;网页面板弹窗层级高于侧边抽屉
- 邀请分享文案提示「授权结束后 2 小时内可重新打开此链接申请延长」
This commit is contained in:
DeepFal committed 2026-10-14 10:11:06 +08:00
1 parent 9a675ba96e
commit dceb59c0ca
16 files changed
+1707 -75

No files matched your search

+3 -2
View File
@@ -575,8 +575,9 @@ func TestRevokeInviteRemovesItsLeases(t *testing.T) {
if hit(cfg.ListenPort) == "OK" {
t.Fatal("leases of revoked invite still active")
}
if status, _ := httpGet(t, addr, "/i/"+inv.Code, nil); status != 404 {
t.Fatal("revoked invite still usable")
// 用过它的设备看到「授权已撤销」,不能申请延长
if status, body := httpGet(t, addr, "/i/"+inv.Code, nil); status != 403 || !strings.Contains(body, "授权已撤销") {
t.Fatalf("revoked invite still usable: %d", status)
}
}