├── image-1.png ├── image-2.png ├── image.png ├── requirements.txt ├── .gitignore ├── start.sh ├── static ├── js │ └── main.js └── css │ └── style.css ├── README.md ├── templates ├── login.html ├── change_password.html ├── settings.html └── index.html ├── scheduler.py ├── notifier.py ├── fix_config.py ├── user_lister.py ├── checker.py ├── user_creator.py ├── app.py ├── user_activation.py └── config_manager.py /image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaokun567/office365/HEAD/image-1.png -------------------------------------------------------------------------------- /image-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaokun567/office365/HEAD/image-2.png -------------------------------------------------------------------------------- /image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaokun567/office365/HEAD/image.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==3.0.0 2 | APScheduler==3.10.4 3 | requests==2.31.0 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Python 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | *.so 6 | .Python 7 | env/ 8 | venv/ 9 | ENV/ 10 | build/ 11 | develop-eggs/ 12 | dist/ 13 | downloads/ 14 | eggs/ 15 | .eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | wheels/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # 配置文件(包含敏感信息) 27 | config.json 28 | config.json.bak 29 | config.json.tmp 30 | config.json.backup.* 31 | 32 | # 日志文件 33 | *.log 34 | 35 | # IDE 36 | .vscode/ 37 | .idea/ 38 | *.swp 39 | *.swo 40 | *~ 41 | 42 | # macOS 43 | .DS_Store 44 | 45 | # 测试 46 | .pytest_cache/ 47 | .coverage 48 | htmlcov/ 49 | 50 | # 临时文件 51 | *.tmp 52 | *.temp 53 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 获取脚本所在目录 4 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | 6 | # 切换到脚本目录 7 | cd "$SCRIPT_DIR" 8 | 9 | echo "======================================" 10 | echo "Office 365 订阅监控系统" 11 | echo "======================================" 12 | echo "" 13 | echo "工作目录: $SCRIPT_DIR" 14 | echo "" 15 | echo "正在启动..." 16 | echo "" 17 | 18 | # 检查 Python 是否安装 19 | if ! command -v python3 &> /dev/null; then 20 | echo "❌ 错误: 未找到 Python3" 21 | echo "请先安装 Python 3.7 或更高版本" 22 | exit 1 23 | fi 24 | 25 | # 检查依赖是否安装 26 | if ! python3 -c "import flask" &> /dev/null; then 27 | echo "📦 正在安装依赖..." 28 | pip3 install -r requirements.txt 29 | fi 30 | 31 | echo "✅ 依赖检查完成" 32 | echo "" 33 | echo "🚀 启动服务..." 34 | echo "" 35 | echo "访问地址: http://localhost:5000" 36 | echo "默认密码: xiaokun567" 37 | echo "" 38 | echo "按 Ctrl+C 停止服务" 39 | echo "" 40 | 41 | # 启动应用 42 | python3 app.py 43 | -------------------------------------------------------------------------------- /static/js/main.js: -------------------------------------------------------------------------------- 1 | // API 调用工具函数 2 | const API = { 3 | async getSubscriptions() { 4 | const response = await fetch('/api/subscriptions'); 5 | return await response.json(); 6 | }, 7 | 8 | async createSubscription(data) { 9 | const response = await fetch('/api/subscriptions', { 10 | method: 'POST', 11 | headers: { 12 | 'Content-Type': 'application/json' 13 | }, 14 | body: JSON.stringify(data) 15 | }); 16 | return await response.json(); 17 | }, 18 | 19 | async updateSubscription(id, data) { 20 | const response = await fetch(`/api/subscriptions/${id}`, { 21 | method: 'PUT', 22 | headers: { 23 | 'Content-Type': 'application/json' 24 | }, 25 | body: JSON.stringify(data) 26 | }); 27 | return await response.json(); 28 | }, 29 | 30 | async deleteSubscription(id) { 31 | const response = await fetch(`/api/subscriptions/${id}`, { 32 | method: 'DELETE' 33 | }); 34 | return await response.json(); 35 | }, 36 | 37 | async checkSubscription(id) { 38 | const response = await fetch(`/api/subscriptions/${id}/check`, { 39 | method: 'POST' 40 | }); 41 | return await response.json(); 42 | } 43 | }; 44 | 45 | // 工具函数 46 | const Utils = { 47 | formatDate(dateString) { 48 | if (!dateString) return '未知'; 49 | return new Date(dateString).toLocaleDateString('zh-CN'); 50 | }, 51 | 52 | formatDateTime(dateString) { 53 | if (!dateString) return '从未检测'; 54 | return new Date(dateString).toLocaleString('zh-CN'); 55 | }, 56 | 57 | showLoading(element) { 58 | element.disabled = true; 59 | element.dataset.originalText = element.textContent; 60 | element.textContent = '处理中...'; 61 | }, 62 | 63 | hideLoading(element) { 64 | element.disabled = false; 65 | element.textContent = element.dataset.originalText || '确定'; 66 | }, 67 | 68 | showAlert(message, type = 'info') { 69 | alert(message); 70 | } 71 | }; 72 | 73 | // 导出供 HTML 使用 74 | window.API = API; 75 | window.Utils = Utils; 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Office 365 订阅监控系统 2 | 3 | 一个轻量级的 Office 365 订阅状态监控系统,支持自动检测、手动检测和异常通知。 4 | 5 | ## 使用方法 6 | 7 | ### 查看许可 8 | 9 | 1、获取抓包数据-输入后到仪表盘检测进行更新许可数量。 10 | 11 | ### 添加用户 12 | 13 | 2、获取抓包数据-输入后到仪表盘选择许可添加用户。(需要设置填写 curl 值才能添加用户) 14 | 15 | ## 主要功能 16 | 17 | - 📊 订阅状态监控 18 | - 🔔 自定义 Webhook 通知 19 | - 👤 用户管理 20 | - 📱 设备激活查询 21 | - ⏰ 定时检测(每24小时) 22 | 23 | ## 通知触发条件 24 | 25 | 系统会在以下情况自动发送通知: 26 | 27 | 1. **订阅即将到期** - 剩余天数 ≤ 30天 28 | 2. **订阅已失效** - 订阅状态为失效 29 | 3. **Cookie 失效** - 认证失败,需要更新 Cookie 30 | 4. **登录密码错误** - 有人尝试使用错误密码登录 31 | 32 | ## 安装步骤 33 | 34 | 1. 安装依赖: 35 | ```bash 36 | pip install -r requirements.txt 37 | ``` 38 | 39 | 2. 运行程序: 40 | ```bash 41 | python app.py 42 | ``` 43 | 44 | 3. 访问系统: 45 | ``` 46 | http://localhost:5000 47 | ``` 48 | 49 | ## 默认登录信息 50 | 51 | - **默认密码**: `xiaokun567` 52 | - **首次登录后会强制要求修改密码** 53 | 54 | ## Webhook 配置 55 | 56 | 在设置页面配置 Webhook 通知: 57 | 58 | ### 配置示例 59 | 60 | **Webhook 地址:** 61 | ``` 62 | https://your-webhook-url.com/api/notify 63 | ``` 64 | 65 | **请求体 JSON 模板:** 66 | ```json 67 | { 68 | "title": "{title}", 69 | "text": "{通知消息}" 70 | } 71 | ``` 72 | 73 | ### 支持的变量 74 | 75 | - `{title}` - 标题(固定为"订阅监控通知") 76 | - `{content}` 或 `{通知消息}` - 通知内容 77 | 78 | ### 示例配置 79 | 80 | #### 1. 简单格式 81 | ```json 82 | { 83 | "title": "{title}", 84 | "text": "{content}" 85 | } 86 | ``` 87 | 88 | ## 订阅管理 89 | 90 | 获取 Curl 命令 91 | ### 许可证 92 | 1. 打开浏览器,访问 Microsoft 365 管理中心-许可证-许可点进去(多许可证就抓包这个搜索subscriptions)-管理订阅详细信息(单许可抓包这个搜索getSubscription) 93 | 2. 打开开发者工具(F12) 94 | 3. 切换到 Network(网络)标签 95 | 4. 刷新订阅页面,找到 `getSubscription - 单订阅模式` 请求或者subscriptions 请求 - 多许可证支持 96 | 5. 右键点击请求,选择 "Copy" -> "复制 curl (bash)格式" 97 | 6. 将复制的命令粘贴到添加订阅表单中 98 | ### 用户(可实现 web 界面快捷添加用户) 99 | 100 | 1.用户的 curl 抓包,到 Microsoft 365 管理中心 添加用户,配置用户名,勾选手动设置密码,勾选许可证。 101 | 2. 打开开发者工具(F12) 102 | 3. 切换到 Network(网络)标签 103 | 4. 刷新订阅页面,找到 ` user` 请求 104 | 5. 右键点击请求,选择 "Copy" -> "复制 curl (bash)格式" 105 | 6. 将复制的命令粘贴到添加订阅表单中 106 | 107 | ## 系统展示 108 |  109 | 110 |  111 | 112 |  113 | 114 | 其他就不展示了。 115 | ## 注意事项 116 | 117 | - Cookie 会过期,需要定期更新 118 | - 建议配置 Webhook 以便及时收到通知 119 | - 首次登录后请立即修改默认密码 120 | - 定时任务每24小时自动检测一次 121 | 122 | ## 技术栈 123 | 124 | - Flask - Web 框架 125 | - APScheduler - 定时任务 126 | - Requests - HTTP 请求 127 | - Bootstrap 5 - 前端UI 128 | 129 | ## 许可证 130 | 131 | MIT License 132 | -------------------------------------------------------------------------------- /templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |请输入密码访问系统
77 |检测到您正在使用默认密码,请立即修改
77 |实时监控您的 Office 365 订阅
35 |