├── .gitignore
├── config.js
├── router
├── api.js
├── user.js
├── cloudsync.js
└── system.js
├── package.json
├── page
└── index.html
├── index.js
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | domain: 'www.test.site', // 群晖的域名或者ip
3 | port: 5000, // 端口号
4 | https: false,// 是否为https
5 | apiPort: 80, // api启动端口
6 | responseTimeout: 10 // 请求多少秒后超时
7 | }
--------------------------------------------------------------------------------
/router/api.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const router = express.Router();
3 | const axios = require("axios");
4 |
5 | router.get("/all", (req, res) => { // 获取所有api接口
6 | axios.get(`${req.domain}/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=all`)
7 | .then(response => {
8 | const { data: data } = response.data;
9 | res.send(data)
10 | }).catch(err => res.send(err)
11 | )
12 | })
13 | module.exports = router;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "syno_api",
3 | "version": "1.0.0",
4 | "description": "将本项目搭建在任何有网络的地方上,可以通过RESTful API调用群晖nas接口,可用于开发前端项目,也可用于定制自己专属的管理系统,本项目持续更新中",
5 | "main": "index.js",
6 | "scripts": {
7 | "dsm": "npx forever start ./index.js",
8 | "stop": "npx forever stop ./index.js"
9 | },
10 | "keywords": [
11 | "群晖",
12 | "synology"
13 | ],
14 | "author": "wushanglin",
15 | "license": "ISC",
16 | "dependencies": {
17 | "axios": "^1.2.1",
18 | "cors": "^2.8.5",
19 | "express": "^4.18.2",
20 | "express-session": "^1.17.3",
21 | "forever": "^4.0.3",
22 | "nodemon": "^2.0.20"
23 | }
24 | }
--------------------------------------------------------------------------------
/page/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Document
9 |
10 |
11 |
12 | test
13 |
14 |
25 |
26 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 | const express = require('express');
3 | const cors = require('cors');
4 | const app = express();
5 | const session = require("express-session");
6 | const config = require("./config.js");
7 | app.use('/', express.static('./page'));
8 | app.use(cors());
9 | app.use(session({
10 | secret: "DSM-api",
11 | resave: false,
12 | saveUninitialized: true
13 | }))
14 | // 处理config.js
15 | app.use(function (req, res, next) {
16 | if (config.https) {
17 | req.domain = `https://${config.domain}:${config.port}`
18 | } else {
19 | req.domain = `http://${config.domain}:${config.port}`
20 | }
21 | req.api = req.domain + '/webapi';
22 | next();
23 | })
24 |
25 | // 获取api接口
26 | const api_router = require('./router/api.js');
27 | app.use('/api', api_router);
28 | // 用户
29 | const user_router = require("./router/user.js");
30 | app.use('/user', user_router);
31 | // 系统
32 | const info_router = require("./router/system.js");
33 | app.use('/system', info_router);
34 | // cloudsync
35 | const cloudsync_router = require("./router/cloudsync.js");
36 | app.use('/cloudsync', cloudsync_router);
37 | // 接受错误,防止项目崩溃
38 | app.use((err, req, res, next) => {
39 | res.send(err.message);
40 | })
41 |
42 | app.listen(config.apiPort)
--------------------------------------------------------------------------------
/router/user.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const axios = require("axios");
4 | const config = require("../config.js");
5 | // console.log(method.iferror);
6 | router.get('/login', (req, res) => {
7 | if (!req.query.username || !req.query.password) { // 登录群晖
8 | throw new Error('请传入用户名和密码')
9 | }
10 |
11 | axios.get(`${req.api}/entry.cgi?api=SYNO.API.Auth&version=7&method=login&account=${req.query.username}&passwd=${req.query.password}&session=FileStation&format=sid`, { timeout: (config.responseTimeout * 1000) })
12 | .then(response => { // 判断返回的值是否正确
13 | return new Promise((resolve, reject) => {
14 | if (response.data.data) {
15 | resolve(response.data);
16 | } else if (response.data.error.code == 400) {
17 | reject(new Error("密码或账号错误"))
18 | } else if (response.data.error.code == 407) {
19 | reject(new Error("IP 地址已被封锁,因为它已达到特定时间允许的登录尝试失败最大数。请修改最大访问次数"))
20 | }
21 | });
22 | })
23 | .then(response => { // 正确的处理
24 | // console.log(response);
25 | req.session.auth = response.data.sid;
26 | res.send(response)
27 |
28 | }).catch(e => { // 错误的处理
29 | res.send(e.message)
30 | })
31 |
32 |
33 | })
34 |
35 | router.get('/logout', (req, res) => {// 登出群晖 BUG
36 | axios.get(`${req.api}/auth.cgi?api=SYNO.API.Auth&version=7&method=logout&session=FileStation&${req.query.cookie}`, { timeout: (config.responseTimeout * 1000) })
37 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
38 | return new Promise((resolve, reject) => {
39 | const string = JSON.stringify(response.data).slice(0, 85);
40 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
41 | reject(new Error('登录过期,请重新登录'))
42 | } else {
43 | resolve(response.data)
44 | }
45 | });
46 | })
47 | .then(response => {
48 | res.send(response)
49 | })
50 | .catch(e => {
51 | res.send(e.message)
52 | })
53 | })
54 | module.exports = router;
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 将本项目可以搭建在任何有网络的地方上,使用RESTful API调用群晖nas接口,可用于开发前端项目,也可用于定制自己专属的管理系统,本项目持续更新中"
2 |
3 | # 注意事项
4 |
5 | - **填写好config.js文件**
6 |
7 | - **node.js版本大于或等于14**
8 |
9 |
10 |
11 | **根据测试,群晖7.1.1系统可以正常使用,理论上其他版本也能使用,如有问题请创建issue**
12 |
13 | # 使用教程
14 |
15 | ### 群晖 :确保已安装npm和node.js,在群晖管理页面创建好文件夹,将项目里所有文件上传,通过ssh进入到该文件夹,运行下方命令
16 |
17 | ### windows:安装node.js后,通过powershell打开该项目,运行命令
18 |
19 | ### linux:都用linux了,不用我多说了吧(手动狗头),安装好node环境和npm,运行命令即可
20 |
21 | ```powershell
22 | $ npm install
23 | $ npm run dsm // 运行项目
24 | $ npm run stop // 停止项目
25 | ```
26 |
27 | # 关于返回结果的问题
28 |
29 | | 状态码 | 解答 |
30 | | ------ | ------------------------------------ |
31 | | 102 | 返回个状态码一般是未安装该应用导致的 |
32 |
33 |
34 |
35 | # 在运行其他api之前先进行登录,本项目采用中间件封装形式,通过调用以下api即可操作群晖系统
36 |
37 | 示例 **http://romain:port/user/login?username=dsm&password=123456**
38 |
39 | romain为域名
40 |
41 | port为端口
42 |
43 | ## /api 简介
44 |
45 | all 获取所有群晖api接口
46 |
47 | ## /user 简介
48 |
49 | /login 登录
50 |
51 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
52 | | -------- | -------- | -------- | -------------- |
53 | | username | true | string | 群晖登录用户名 |
54 | | password | true | string | 群晖登录密码 |
55 |
56 | /logout 退出
57 |
58 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
59 | | -------- | -------- | -------- | ---- |
60 |
61 | ## /system 简介
62 |
63 | /info 获取系统基本信息
64 |
65 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
66 | | -------- | -------- | -------- | ---- |
67 |
68 | /status 获取系统状态
69 |
70 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
71 | | -------- | -------- | -------- | ---- |
72 |
73 | /network 获取网络信息
74 |
75 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
76 | | -------- | -------- | -------- | ---- |
77 |
78 | /service 获取已启用的服务
79 |
80 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
81 | | -------- | -------- | -------- | ---- |
82 |
83 | /terminal 终端设置
84 |
85 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
86 | | ------------ | -------- | -------- | ------------------------------ |
87 | | enablessh | false | boolean | 开启或关闭ssh,不填则不更改 |
88 | | enabletelnet | false | boolean | 开启或关闭telnet,不填则不更改 |
89 | | sshport | false | boolean | ssh端口,不填则不更改 |
90 |
91 | /shutdown 关机
92 |
93 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
94 | | -------- | -------- | -------- | --------------------------- |
95 | | force | false | boolean | true则为强制关机,默认false |
96 |
97 | /reboot 重启
98 |
99 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
100 | | -------- | -------- | -------- | --------------------------- |
101 | | force | false | boolean | true则为强制重启,默认false |
102 |
103 | ## /cloudsync 简介
104 |
105 | /list 获取cloudsync所有已授权的云盘
106 |
107 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
108 | | -------- | -------- | -------- | ---- |
109 |
110 | /settingmsg 获取云盘设置信息
111 |
112 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
113 | | -------- | -------- | -------- | -------------------------- |
114 | | id | true | number | 网盘的对应id,在list里获取 |
115 |
116 | /status 获取云盘状态信息
117 |
118 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
119 | | -------- | -------- | -------- | -------------------------- |
120 | | id | true | number | 网盘的对应id,在list里获取 |
121 |
122 | /property 获取云盘属性信息
123 |
124 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
125 | | -------- | -------- | -------- | -------------------------- |
126 | | id | true | number | 网盘的对应id,在list里获取 |
127 |
128 | /log 同步记录
129 |
130 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
131 | | -------- | -------- | -------- | ------------------------------- |
132 | | id | true | number | 网盘的对应id,在list里获取 |
133 | | limit | false | number | 一次性获取多少数据,默认为200条 |
134 |
135 | /change 更改云盘同步设置
136 |
137 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
138 | | ---------------- | -------- | -------- | -------------------------- |
139 | | id | true | number | 网盘的对应id,在list里获取 |
140 | | name | true | string | cloudsync里显示的名称 |
141 | | Pollingtime | true | number | 轮询时间 |
142 | | maxdownloadspeed | true | number | 最大下载速度,0为不限速 |
143 | | maxuploadspeed | true | number | 最大上传速度,0为不限速 |
144 |
145 | /pause 暂停同步所有云盘
146 |
147 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
148 | | -------- | -------- | -------- | ---- |
149 |
150 | /start 开始同步
151 |
152 | | 参数名称 | 是否必填 | 接口类型 | 说明 |
153 | | -------- | -------- | -------- | ---- |
154 |
--------------------------------------------------------------------------------
/router/cloudsync.js:
--------------------------------------------------------------------------------
1 | const { default: axios } = require('axios');
2 | const express = require('express')
3 | const router = express.Router();
4 | const config = require("../config.js");
5 | router.get("/list", (req, res) => { // 获取cloudsync列表
6 | axios.get(`${req.api}/entry.cgi?is_tray=false&group_by="group_by_user"&api=SYNO.CloudSync&method=list_conn&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
7 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
8 | return new Promise((resolve, reject) => {
9 | const string = JSON.stringify(response.data).slice(0, 85);
10 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
11 | reject(new Error('登录过期,请重新登录'))
12 | } else {
13 | resolve(response.data)
14 | }
15 | });
16 | })
17 | .then(response => {
18 | res.send(response);
19 | })
20 | .catch(e => {
21 | res.send(e.message)
22 | })
23 | })
24 |
25 | router.get("/settingmsg", (req, res) => { // 获取items设置信息
26 | if (!(req.query.id >= 0) || req.query.id == undefined) {
27 | throw new Error("请添加list的请求id")
28 | }
29 | axios.get(`${req.api}/entry.cgi?connection_id=${req.query.id}&api=SYNO.CloudSync&method=get_connection_setting&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
30 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
31 | return new Promise((resolve, reject) => {
32 | const string = JSON.stringify(response.data).slice(0, 85);
33 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
34 | reject(new Error('登录过期,请重新登录'))
35 | } else {
36 | resolve(response.data)
37 | }
38 | });
39 | })
40 | .then(response => {
41 | res.send(response);
42 | }).catch(e => {
43 | res.send(e.message)
44 | })
45 | })
46 |
47 | router.get("/status", (req, res) => { // 获取items状态信息
48 | if (!(req.query.id >= 0) || req.query.id == undefined) {
49 | throw new Error("请添加list的请求id")
50 | }
51 | axios.get(`${req.api}/entry.cgi?connection_id=3&api=SYNO.CloudSync&method=list_sess&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
52 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
53 | return new Promise((resolve, reject) => {
54 | const string = JSON.stringify(response.data).slice(0, 85);
55 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
56 | reject(new Error('登录过期,请重新登录'))
57 | } else {
58 | resolve(response.data)
59 | }
60 | });
61 | })
62 | .then(response => {
63 | res.send(response);
64 | })
65 | .catch(e => {
66 | res.send(e.message)
67 | })
68 | })
69 |
70 | router.get("/property", (req, res) => { // 获取items属性信息
71 | if (!(req.query.id >= 0) || req.query.id == undefined) {
72 | throw new Error("请添加list的请求id")
73 | }
74 | axios.get(`${req.api}/entry.cgi?connection_id=${req.query.id}&api=SYNO.CloudSync&method=get_property&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
75 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
76 | return new Promise((resolve, reject) => {
77 | const string = JSON.stringify(response.data).slice(0, 85);
78 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
79 | reject(new Error('登录过期,请重新登录'))
80 | } else {
81 | resolve(response.data)
82 | }
83 | });
84 | })
85 | .then(response => {
86 | res.send(response);
87 | })
88 | .catch(e => {
89 | res.send(e.message)
90 | })
91 | })
92 |
93 | router.get("/log", (req, res) => { // 获取items同步记录
94 | if (!(req.query.id >= 0) || req.query.id == undefined) {
95 | throw new Error("请添加list的请求id")
96 | }
97 | req.query.limit = req.query.limit || 200;
98 | console.log(req.query.limit);
99 | axios.get(`${req.api}/entry.cgi?offset=0&limit=${req.query.limit}&connection_id=${req.query.id}&api=SYNO.CloudSync&method=get_log&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
100 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
101 | return new Promise((resolve, reject) => {
102 | const string = JSON.stringify(response.data).slice(0, 85);
103 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
104 | reject(new Error('登录过期,请重新登录'))
105 | } else {
106 | resolve(response.data)
107 | }
108 | });
109 | })
110 | .then(response => {
111 | res.send(response);
112 | })
113 | .catch(e => {
114 | res.send(e.message)
115 | })
116 | })
117 |
118 | router.get("/change", (req, res) => { // 更改items设置
119 | // 最大上传和下载为0 代表不限速
120 | if (!(req.query.id >= 0) || (req.query.id == undefined)) {
121 | throw new Error("请添加list的请求id")
122 | } else if (!req.query.name || req.query.Pollingtime == undefined || req.query.maxdownloadspeed == undefined || req.query.maxuploadspeed == undefined) {
123 | throw new Error("必须填写所有参数")
124 | }
125 | axios.get(`${req.api}/entry.cgi?connection_id=${req.query.id}&task_name="${req.query.name}"&pull_event_period=${Number(req.query.Pollingtime)}&max_upload_speed=${req.query.maxuploadspeed}&max_download_speed=${req.query.maxdownloadspeed}&storage_class=""&isSSE=false&part_size=128&api=SYNO.CloudSync&method=set_connection_setting&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
126 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
127 | return new Promise((resolve, reject) => {
128 | const string = JSON.stringify(response.data).slice(0, 85);
129 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
130 | reject(new Error('登录过期,请重新登录'))
131 | } else {
132 | resolve(response.data)
133 | }
134 | });
135 | })
136 | .then(response => {
137 | res.send(response);
138 | })
139 | .catch(e => {
140 | res.send(e.message)
141 | })
142 | })
143 |
144 | router.get("/pause", (req, res) => { // 暂停所有items同步
145 | axios.get(`${req.api}/entry.cgi?api=SYNO.CloudSync&method=pause&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
146 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
147 | return new Promise((resolve, reject) => {
148 | const string = JSON.stringify(response.data).slice(0, 85);
149 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
150 | reject(new Error('登录过期,请重新登录'))
151 | } else {
152 | resolve(response.data)
153 | }
154 | });
155 | })
156 | .then(response => {
157 | res.send(response);
158 | })
159 | .catch(e => {
160 | res.send(e.message)
161 | })
162 | })
163 |
164 | router.get("/start", (req, res) => { // 开始所有items同步
165 | axios.get(`${req.api}/entry.cgi?api=SYNO.CloudSync&method=resume&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
166 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
167 | return new Promise((resolve, reject) => {
168 | const string = JSON.stringify(response.data).slice(0, 85);
169 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
170 | reject(new Error('登录过期,请重新登录'))
171 | } else {
172 | resolve(response.data)
173 | }
174 | });
175 | })
176 | .then(response => {
177 | res.send(response);
178 | })
179 | .catch(e => {
180 | res.send(e.message)
181 | })
182 | })
183 |
184 | module.exports = router;
--------------------------------------------------------------------------------
/router/system.js:
--------------------------------------------------------------------------------
1 | const axios = require('axios');
2 | const express = require('express')
3 | const router = express.Router();
4 | const config = require("../config")
5 | router.get("/info", (req, res) => { // 获取系统基本信息
6 | axios.get(`${req.api}/entry.cgi?stop_when_error=false&mode="sequential"&compound=[{"api":"SYNO.Core.System","method":"info","version":3},{"api":"SYNO.Core.QuickConnect","method":"get","version":2},{"api":"SYNO.Core.Hardware.FanSpeed","method":"get","version":1}]&api=SYNO.Entry.Request&method=request&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
7 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
8 | return new Promise((resolve, reject) => {
9 | const string = JSON.stringify(response.data).slice(0, 85);
10 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
11 | reject(new Error('登录过期,请重新登录'))
12 | } else {
13 | resolve(response.data)
14 | }
15 | });
16 | })
17 | .then(response => {
18 | res.send(response);
19 | })
20 | .catch((e) => {
21 | res.send(e.message)
22 | })
23 | })
24 |
25 | router.get("/status", (req, res) => { // 获取系统状态
26 | axios.get(`${req.api}/entry.cgi?api=SYNO.Core.System.Utilization&method=get&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
27 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
28 | return new Promise((resolve, reject) => {
29 | const string = JSON.stringify(response.data).slice(0, 85);
30 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
31 | reject(new Error('登录过期,请重新登录'))
32 | } else {
33 | resolve(response.data)
34 | }
35 | });
36 | })
37 | .then(response => {
38 | res.send(response);
39 | })
40 | .catch(e => {
41 | res.send(e.message)
42 | })
43 | })
44 |
45 |
46 | router.get("/network", (req, res) => { // 获取网络基本信息
47 |
48 | axios.get(`${req.api}/entry.cgi?stop_when_error=false&mode="sequential"&compound=[{"api":"SYNO.Core.System","method":"info","version":1,"type":"network"},{"api":"SYNO.Core.DDNS.Record","method":"list","version":1}]&api=SYNO.Entry.Request&method=request&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
49 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
50 | return new Promise((resolve, reject) => {
51 | const string = JSON.stringify(response.data).slice(0, 85);
52 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
53 | reject(new Error('登录过期,请重新登录'))
54 | } else {
55 | resolve(response.data)
56 | }
57 | });
58 | })
59 | .then(response => {
60 | res.send(response);
61 | })
62 | .catch(e => {
63 | res.send(e.message)
64 | })
65 | })
66 |
67 | router.get("/service", (req, res) => { // 获取获取已启用的服务
68 | axios.get(`${req.api}/entry.cgi?stop_when_error=false&mode="parallel"&compound=[{"api":"SYNO.Core.Service","method":"get","version":3,"additional":["active_status"]},{"api":"SYNO.Core.Package","method":"list","version":1,"additional":["status"]}]&api=SYNO.Entry.Request&method=request&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
69 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
70 | return new Promise((resolve, reject) => {
71 | const string = JSON.stringify(response.data).slice(0, 85);
72 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
73 | reject(new Error('登录过期,请重新登录'))
74 | } else {
75 | resolve(response.data)
76 | }
77 | });
78 | })
79 | .then(response => {
80 | res.send(response);
81 | })
82 | .catch(e => {
83 | res.send(e.message)
84 | })
85 | })
86 |
87 | router.get("/terminal", (req, res) => { // 终端设置
88 | if (req.query.enablessh == undefined && req.query.enabletelnet == undefined && req.query.sshport == undefined) {
89 | throw new Error("请输入至少一个参数");
90 | }
91 | // 先获取原来的数据
92 | axios.get(`${req.api}/entry.cgi?stop_when_error=false&mode="sequential"&compound=[{"api":"SYNO.Core.Terminal","method":"get","version":3},{"api":"SYNO.Core.SNMP","method":"get","version":1}]&api=SYNO.Entry.Request&method=request&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
93 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
94 | return new Promise((resolve, reject) => {
95 | const string = JSON.stringify(response.data).slice(0, 85);
96 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
97 | reject(new Error('登录过期,请重新登录'))
98 | } else {
99 | resolve(response.data)
100 | }
101 | });
102 | })
103 | .then(response => {
104 | let enable_telnet = response.data.result[0].data.enable_telnet;
105 | let enable_ssh = response.data.result[0].data.enable_ssh;
106 | let ssh_port = response.data.result[0].data.ssh_port;
107 |
108 | // 处理配置数据
109 | enable_ssh = Boolean(enable_ssh);
110 | enable_telnet = Boolean(enable_telnet);
111 | ssh_port = Number(ssh_port);
112 |
113 | req.query.enablessh = req.query.enablessh == undefined ? enable_ssh : req.query.enablessh;
114 | req.query.enabletelnet = req.query.enabletelnet == undefined ? enable_telnet : req.query.enabletelnet;
115 | req.query.sshport = req.query.sshport == undefined ? ssh_port : req.query.sshport;
116 |
117 | // 发起请求
118 | let compound = `[{ "api": "SYNO.Core.Terminal", "method": "set", "version": "3", "enable_telnet": ${req.query.enabletelnet}, "enable_ssh": ${req.query.enablessh}, "ssh_port": ${req.query.sshport} }, { "api": "SYNO.Core.SNMP", "method": "set", "version": "1", "enable_snmp": false }, { "api": "SYNO.Core.Terminal", "method": "get", "version": 3 }, { "api": "SYNO.Core.SNMP", "method": "get", "version": 1 }]`;
119 | axios.get(`${req.api}/entry.cgi?stop_when_error=false&mode="sequential"&compound=${compound}&api=SYNO.Entry.Request&method=request&version=1&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
120 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
121 | return new Promise((resolve, reject) => {
122 | const string = JSON.stringify(response.data).slice(0, 85);
123 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
124 | reject(new Error('登录过期,请重新登录'))
125 | } else {
126 | resolve(response.data)
127 | }
128 | });
129 | })
130 | .then(response => {
131 | res.send(response);
132 | })
133 | })
134 | .catch(e => {
135 | res.send(e.message)
136 | })
137 | })
138 | router.get("/shutdown", (req, res) => { // 关机
139 | (req.query.force == undefined) && (req.query.force = false);
140 | req.query.force = Boolean(req.query.force);
141 | axios.get(`${req.api}/entry.cgi?force=${req.query.force}&local=true&firmware_upgrade=false&cache_check_shutdown=true&api=SYNO.Core.System&method=shutdown&version=2&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
142 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
143 | return new Promise((resolve, reject) => {
144 | const string = JSON.stringify(response.data).slice(0, 85);
145 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
146 | reject(new Error('登录过期,请重新登录'))
147 | } else {
148 | resolve(response.data)
149 | }
150 | });
151 | })
152 | .then(response => {
153 | res.send(response);
154 | })
155 | .catch(e => {
156 | res.send(e.message)
157 | })
158 | })
159 | router.get("/reboot", (req, res) => { // 重启
160 | (req.query.force == undefined) && (req.query.force = false);
161 | req.query.force = Boolean(req.query.force);
162 | axios.get(`${req.api}/entry.cgi?force=${req.query.force}&local=true&firmware_upgrade=false&cache_check_shutdown=false&api=SYNO.Core.System&method=reboot&version=2&_sid=${req.session.auth}`, { timeout: (config.responseTimeout * 1000) })
163 | .then((response) => { // 判断有没有报错,如果报错证明cookie过期
164 | return new Promise((resolve, reject) => {
165 | const string = JSON.stringify(response.data).slice(0, 85);
166 | if (string.includes('"error":{"code":119}') || string.includes('"has_fail":true')) {
167 | reject(new Error('登录过期,请重新登录'))
168 | } else {
169 | resolve(response.data)
170 | }
171 | });
172 | })
173 | .then(response => {
174 | res.send(response);
175 | })
176 | .catch(e => {
177 | res.send(e.message)
178 | })
179 | })
180 | module.exports = router;
--------------------------------------------------------------------------------