From 3710f23dc36cc057e6134937466f3046442e52a8 Mon Sep 17 00:00:00 2001 From: Sun_sun <469361609@qq.com> Date: Fri, 19 Sep 2025 10:00:12 +0800 Subject: [PATCH] =?UTF-8?q?2025-09-18=20=E7=9C=81=E5=B8=82=E5=8C=BA?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E3=80=81sms=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 68 +++++ .gitignore | 1 + app.js | 10 +- package-lock.json | 470 +++++++++++++++++++++++++++-------- package.json | 4 +- public/index.html | 13 - public/stylesheets/style.css | 8 - routes/auth.js | 1 - routes/index.js | 6 - routes/sms.js | 340 +++++++++++++++++++++++++ routes/users.js | 9 - 11 files changed, 784 insertions(+), 146 deletions(-) create mode 100644 .env delete mode 100644 public/index.html delete mode 100644 public/stylesheets/style.css delete mode 100644 routes/index.js create mode 100644 routes/sms.js delete mode 100644 routes/users.js diff --git a/.env b/.env new file mode 100644 index 0000000..067bfb4 --- /dev/null +++ b/.env @@ -0,0 +1,68 @@ +# 数据库配置 +DB_HOST=114.55.111.44 +DB_USER=maov2 +DB_PASSWORD=5fYhw8z6T62b7heS +DB_NAME=maov2 + +# JWT密钥 +JWT_SECRET=your_jwt_secret_key + +# 阿里云短信服务配置 +# 请在阿里云控制台获取以下配置信息: +# 1. AccessKey ID 和 AccessKey Secret:在阿里云控制台 -> AccessKey管理中创建 +# 2. 短信签名:在阿里云短信服务控制台中申请并审核通过的签名 +# 3. 短信模板CODE:在阿里云短信服务控制台中申请并审核通过的模板CODE +ALIYUN_ACCESS_KEY_ID=LTAI5tBHymRUu1vvo5tgYpaa +ALIYUN_ACCESS_KEY_SECRET=lNsDZvpUVX2b3pfBQCBawOEyr3dNB9 +ALIYUN_SMS_SIGN_NAME=宁波炬融歆创科技 +ALIYUN_SMS_TEMPLATE_CODE=SMS_324470054 + +# 环境配置 +NODE_ENV=development +PORT=3000 + +# 前端地址配置 +FRONTEND_URL=https://www.zrbjr.com/frontend +# FRONTEND_URL=http://114.55.111.44:3001/frontend + +# MinIO 对象存储配置 +# MinIO服务器地址(不包含协议) +MINIO_ENDPOINT=114.55.111.44 +# MinIO服务器端口 +MINIO_PORT=9000 +# 是否使用SSL(true/false) +MINIO_USE_SSL=false +# MinIO访问密钥 +MINIO_ACCESS_KEY=minio +# MinIO秘密密钥 +MINIO_SECRET_KEY=CNy6fMCfyfeaEjbE +# MinIO公开访问地址(用于生成文件URL) +MINIO_PUBLIC_URL=https://minio.zrbjr.com + +# MinIO存储桶配置 +MINIO_BUCKET_UPLOADS=jurongquan +MINIO_BUCKET_AVATARS=jurongquan +MINIO_BUCKET_PRODUCTS=jurongquan +MINIO_BUCKET_DOCUMENTS=jurongquan + +#支付配置 +WECHAT_APP_ID=wx3a702dbe13fd2217 +WECHAT_MCH_ID=1726377336 +WECHAT_API_KEY=NINGBOJURONGkejiyouxiangongsi202 +WECHAT_API_V3_KEY=NINGBOJURONGkejiyouxiangongsi202 +WECHAT_CERT_PATH=./cert/apiclient_cert.pem +WECHAT_KEY_PATH=./cert/apiclient_key.pem +WECHAT_NOTIFY_URL=https://www.zrbjr.com/api/wechat-pay/notify + +# 支付宝配置 +# 请在支付宝开放平台获取以下配置信息: +# 1. 应用ID:在支付宝开放平台创建应用后获得 +# 2. 应用私钥和支付宝公钥现在从文件读取 +ALIPAY_APP_ID=2021005188682022 +ALIPAY_NOTIFY_URL=https://www.zrbjr.com/api/payment/alipay/notify +ALIPAY_RETURN_URL=https://www.zrbjr.com/payment +ALIPAY_QUIT_URL=https://www.zrbjr.com/payment/ +#ALIPAY_APP_ID=9021000151699946 +#ALIPAY_NOTIFY_URL=https://test.zrbjr.com/api/payment/alipay/notify +#ALIPAY_RETURN_URL=http://192.168.1.124:5173/frontend/payment +#ALIPAY_QUIT_URL=http://192.168.1.124:5173/frontend/payment diff --git a/.gitignore b/.gitignore index 2ccbe46..6bdbe62 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /node_modules/ +/.idea/ diff --git a/app.js b/app.js index 29182d7..4c84532 100644 --- a/app.js +++ b/app.js @@ -6,11 +6,12 @@ const {specs, swaggerUi} = require('./config/swagger'); // 引入 swagger 配 const cors = require('cors'); const bodyParser = require('body-parser'); -var indexRouter = require('./routes/index'); -var usersRouter = require('./routes/users'); +// region api导入 var commonRouter = require('./routes/common'); var captchaRouter = require('./routes/captcha'); var authRouter = require('./routes/auth'); +var smsRouter = require('./routes/sms'); +// endregion var app = express(); @@ -42,10 +43,11 @@ app.use(express.urlencoded({extended: false})); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); -app.use('/users', usersRouter); +// region api配置 app.use('/api/common', commonRouter) app.use('/api/captcha', captchaRouter) app.use('/api/auth', authRouter) - +app.use('/api/sms', smsRouter) +// endregion module.exports = app; diff --git a/package-lock.json b/package-lock.json index c346e02..fef7c63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,10 @@ "name": "middle-office-system", "version": "0.0.0", "dependencies": { + "@alicloud/dysmsapi20170525": "^4.1.1", + "@alicloud/openapi-client": "^0.4.15", "bcryptjs": "^2.4.3", - "body-parser": "^2.2.0", + "body-parser": "^1.20.2", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "debug": "~2.6.9", @@ -21,6 +23,185 @@ "swagger-ui-express": "^5.0.1" } }, + "node_modules/@alicloud/credentials": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@alicloud/credentials/-/credentials-2.4.4.tgz", + "integrity": "sha512-/eRAGSKcniLIFQ1UCpDhB/IrHUZisQ1sc65ws/c2avxUMpXwH1rWAohb76SVAUJhiF4mwvLzLJM1Mn1XL4Xe/Q==", + "dependencies": { + "@alicloud/tea-typescript": "^1.8.0", + "httpx": "^2.3.3", + "ini": "^1.3.5", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/darabonba-array": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-array/-/darabonba-array-0.1.2.tgz", + "integrity": "sha512-ZPuQ+bJyjrd8XVVm55kl+ypk7OQoi1ZH/DiToaAEQaGvgEjrTcvQkg71//vUX/6cvbLIF5piQDvhrLb+lUEIPQ==", + "dependencies": { + "@alicloud/tea-typescript": "^1.7.1" + } + }, + "node_modules/@alicloud/darabonba-encode-util": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-encode-util/-/darabonba-encode-util-0.0.2.tgz", + "integrity": "sha512-mlsNctkeqmR0RtgE1Rngyeadi5snLOAHBCWEtYf68d7tyKskosXDTNeZ6VCD/UfrUu4N51ItO8zlpfXiOgeg3A==", + "dependencies": { + "moment": "^2.29.1" + } + }, + "node_modules/@alicloud/darabonba-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-map/-/darabonba-map-0.0.1.tgz", + "integrity": "sha512-2ep+G3YDvuI+dRYVlmER1LVUQDhf9kEItmVB/bbEu1pgKzelcocCwAc79XZQjTcQGFgjDycf3vH87WLDGLFMlw==", + "dependencies": { + "@alicloud/tea-typescript": "^1.7.1" + } + }, + "node_modules/@alicloud/darabonba-signature-util": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-signature-util/-/darabonba-signature-util-0.0.4.tgz", + "integrity": "sha512-I1TtwtAnzLamgqnAaOkN0IGjwkiti//0a7/auyVThdqiC/3kyafSAn6znysWOmzub4mrzac2WiqblZKFcN5NWg==", + "dependencies": { + "@alicloud/darabonba-encode-util": "^0.0.1" + } + }, + "node_modules/@alicloud/darabonba-signature-util/node_modules/@alicloud/darabonba-encode-util": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-encode-util/-/darabonba-encode-util-0.0.1.tgz", + "integrity": "sha512-Sl5vCRVAYMqwmvXpJLM9hYoCHOMsQlGxaWSGhGWulpKk/NaUBArtoO1B0yHruJf1C5uHhEJIaylYcM48icFHgw==", + "dependencies": { + "@alicloud/tea-typescript": "^1.7.1", + "moment": "^2.29.1" + } + }, + "node_modules/@alicloud/darabonba-string": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@alicloud/darabonba-string/-/darabonba-string-1.0.3.tgz", + "integrity": "sha512-NyWwrU8cAIesWk3uHL1Q7pTDTqLkCI/0PmJXC4/4A0MFNAZ9Ouq0iFBsRqvfyUujSSM+WhYLuTfakQXiVLkTMA==", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1" + } + }, + "node_modules/@alicloud/dysmsapi20170525": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@alicloud/dysmsapi20170525/-/dysmsapi20170525-4.2.0.tgz", + "integrity": "sha512-XXwOWUKEVFcfbqmJXw616ekHFp3jmaUC0OadYZs77TdMr0D13W41MuiFevKRNL09W5N0e+0GKdDErwvPuVGCpw==", + "dependencies": { + "@alicloud/openapi-core": "^1.0.0", + "@darabonba/typescript": "^1.0.0" + } + }, + "node_modules/@alicloud/endpoint-util": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@alicloud/endpoint-util/-/endpoint-util-0.0.1.tgz", + "integrity": "sha512-+pH7/KEXup84cHzIL6UJAaPqETvln4yXlD9JzlrqioyCSaWxbug5FUobsiI6fuUOpw5WwoB3fWAtGbFnJ1K3Yg==", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/gateway-pop": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@alicloud/gateway-pop/-/gateway-pop-0.0.6.tgz", + "integrity": "sha512-KF4I+JvfYuLKc3fWeWYIZ7lOVJ9jRW0sQXdXidZn1DKZ978ncfGf7i0LBfONGk4OxvNb/HD3/0yYhkgZgPbKtA==", + "dependencies": { + "@alicloud/credentials": "^2", + "@alicloud/darabonba-array": "^0.1.0", + "@alicloud/darabonba-encode-util": "^0.0.2", + "@alicloud/darabonba-map": "^0.0.1", + "@alicloud/darabonba-signature-util": "^0.0.4", + "@alicloud/darabonba-string": "^1.0.2", + "@alicloud/endpoint-util": "^0.0.1", + "@alicloud/gateway-spi": "^0.0.8", + "@alicloud/openapi-util": "^0.3.2", + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.4.8" + } + }, + "node_modules/@alicloud/gateway-spi": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@alicloud/gateway-spi/-/gateway-spi-0.0.8.tgz", + "integrity": "sha512-KM7fu5asjxZPmrz9sJGHJeSU+cNQNOxW+SFmgmAIrITui5hXL2LB+KNRuzWmlwPjnuA2X3/keq9h6++S9jcV5g==", + "dependencies": { + "@alicloud/credentials": "^2", + "@alicloud/tea-typescript": "^1.7.1" + } + }, + "node_modules/@alicloud/openapi-client": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-client/-/openapi-client-0.4.15.tgz", + "integrity": "sha512-4VE0/k5ZdQbAhOSTqniVhuX1k5DUeUMZv74degn3wIWjLY6Bq+hxjaGsaHYlLZ2gA5wUrs8NcI5TE+lIQS3iiA==", + "dependencies": { + "@alicloud/credentials": "^2.4.2", + "@alicloud/gateway-spi": "^0.0.8", + "@alicloud/openapi-util": "^0.3.2", + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "1.4.9", + "@alicloud/tea-xml": "0.0.3" + } + }, + "node_modules/@alicloud/openapi-client/node_modules/@alicloud/tea-util": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/@alicloud/tea-util/-/tea-util-1.4.9.tgz", + "integrity": "sha512-S0wz76rGtoPKskQtRTGqeuqBHFj8BqUn0Vh+glXKun2/9UpaaaWmuJwcmtImk6bJZfLYEShDF/kxDmDJoNYiTw==", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/openapi-core": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-core/-/openapi-core-1.0.5.tgz", + "integrity": "sha512-ed4EKyqHjb9zwrXUs6IRthha/pRn3OUoOcUKuhYu4tllp0RpidA+JYswsweN6sh26H0WIs/LB6nzJEOvh1d3fg==", + "hasInstallScript": true, + "dependencies": { + "@alicloud/credentials": "latest", + "@alicloud/gateway-pop": "0.0.6", + "@alicloud/gateway-spi": "^0.0.8", + "@darabonba/typescript": "^1.0.2" + } + }, + "node_modules/@alicloud/openapi-util": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-util/-/openapi-util-0.3.2.tgz", + "integrity": "sha512-EC2JvxdcOgMlBAEG0+joOh2IB1um8CPz9EdYuRfTfd1uP8Yc9D8QRUWVGjP6scnj6fWSOaHFlit9H6PrJSyFow==", + "dependencies": { + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.3.0", + "kitx": "^2.1.0", + "sm3": "^1.0.3" + } + }, + "node_modules/@alicloud/tea-typescript": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@alicloud/tea-typescript/-/tea-typescript-1.8.0.tgz", + "integrity": "sha512-CWXWaquauJf0sW30mgJRVu9aaXyBth5uMBCUc+5vKTK1zlgf3hIqRUjJZbjlwHwQ5y9anwcu18r48nOZb7l2QQ==", + "dependencies": { + "@types/node": "^12.0.2", + "httpx": "^2.2.6" + } + }, + "node_modules/@alicloud/tea-util": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@alicloud/tea-util/-/tea-util-1.4.10.tgz", + "integrity": "sha512-VEsXWP2dlJLvsY2THj+sH++zwxQRz3Y5BQ8EkfnFems36RkngQKYOLsoto5nR6ej1Gf6I+0IOgBXrkRdpNCQ1g==", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "@darabonba/typescript": "^1.0.0", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/tea-xml": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@alicloud/tea-xml/-/tea-xml-0.0.3.tgz", + "integrity": "sha512-+/9GliugjrLglsXVrd1D80EqqKgGpyA0eQ6+1ZdUOYCaRguaSwz44trX3PaxPu/HhIPJg9PsGQQ3cSLXWZjbAA==", + "dependencies": { + "@alicloud/tea-typescript": "^1", + "@types/xml2js": "^0.4.5", + "xml2js": "^0.6.0" + } + }, "node_modules/@apidevtools/json-schema-ref-parser": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz", @@ -61,6 +242,19 @@ "openapi-types": ">=7" } }, + "node_modules/@darabonba/typescript": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@darabonba/typescript/-/typescript-1.0.3.tgz", + "integrity": "sha512-/y2y6wf5TsxD7pCPIm0OvTC+5qV0Tk7HQYxwpIuWRLXQLB0CRDvr6qk4bR6rTLO/JglJa8z2uCGZsaLYpQNqFQ==", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "httpx": "^2.3.2", + "lodash": "^4.17.21", + "moment": "^2.30.1", + "moment-timezone": "^0.5.45", + "xml2js": "^0.6.2" + } + }, "node_modules/@jsdevtools/ono": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", @@ -77,6 +271,19 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, + "node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + }, + "node_modules/@types/xml2js": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz", + "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -129,38 +336,26 @@ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" }, "node_modules/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">=18" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/body-parser/node_modules/depd": { @@ -171,6 +366,15 @@ "node": ">= 0.8" } }, + "node_modules/body-parser/node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/body-parser/node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -191,38 +395,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/body-parser/node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/body-parser/node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -235,11 +407,11 @@ } }, "node_modules/body-parser/node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dependencies": { - "side-channel": "^1.1.0" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -261,19 +433,6 @@ "node": ">= 0.8" } }, - "node_modules/body-parser/node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -773,12 +932,50 @@ "node": ">= 0.6" } }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "node_modules/httpx": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/httpx/-/httpx-2.3.3.tgz", + "integrity": "sha512-k1qv94u1b6e+XKCxVbLgYlOypVP9MPGpnN5G/vxFf6tDO4V3xpz3d6FUOY/s8NtPgaq5RBVVgSB+7IHpVxMYzw==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "@types/node": "^20", + "debug": "^4.1.1" + } + }, + "node_modules/httpx/node_modules/@types/node": { + "version": "20.19.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.17.tgz", + "integrity": "sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/httpx/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/httpx/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" @@ -799,6 +996,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -868,6 +1070,27 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/kitx": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/kitx/-/kitx-2.2.0.tgz", + "integrity": "sha512-tBMwe6AALTBQJb0woQDD40734NKzb0Kzi3k7wQj9ar3AbP9oqhoVrdXPh7rk2r00/glIgd0YbToIUJsnxWMiIg==", + "dependencies": { + "@types/node": "^22.5.4" + } + }, + "node_modules/kitx/node_modules/@types/node": { + "version": "22.18.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.6.tgz", + "integrity": "sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -1014,6 +1237,25 @@ "node": "*" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.48", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz", + "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/morgan": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", @@ -1189,17 +1431,17 @@ } }, "node_modules/raw-body": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz", - "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", - "iconv-lite": "0.7.0", + "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 0.8" } }, "node_modules/raw-body/node_modules/depd": { @@ -1225,21 +1467,6 @@ "node": ">= 0.8" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/raw-body/node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -1268,6 +1495,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" + }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -1394,6 +1626,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sm3": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sm3/-/sm3-1.0.3.tgz", + "integrity": "sha512-KyFkIfr8QBlFG3uc3NaljaXdYcsbRy1KrSfc4tsQV8jW68jAktGeOcifu530Vx/5LC+PULHT0Rv8LiI8Gw+c1g==" + }, "node_modules/sqlstring": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", @@ -1482,6 +1719,11 @@ "node": ">= 0.6" } }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1519,6 +1761,26 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, "node_modules/yaml": { "version": "2.0.0-1", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz", diff --git a/package.json b/package.json index e52ea20..5452848 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,10 @@ "start": "node ./bin/www" }, "dependencies": { + "@alicloud/dysmsapi20170525": "^4.1.1", + "@alicloud/openapi-client": "^0.4.15", "bcryptjs": "^2.4.3", - "body-parser": "^2.2.0", + "body-parser": "^1.20.2", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "debug": "~2.6.9", diff --git a/public/index.html b/public/index.html deleted file mode 100644 index ab1ad8a..0000000 --- a/public/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - Express - - - - -

Express

-

Welcome to Express

- - - diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css deleted file mode 100644 index 9453385..0000000 --- a/public/stylesheets/style.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - padding: 50px; - font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; -} - -a { - color: #00B7FF; -} diff --git a/routes/auth.js b/routes/auth.js index b469a18..d65b95d 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -143,7 +143,6 @@ router.post('/register', async (req, res) => { router.post('/login', async (req, res) => { - console.log(123456) try { const db = getDB(); const {username, password, captchaId, captchaText} = req.body; diff --git a/routes/index.js b/routes/index.js deleted file mode 100644 index 9264798..0000000 --- a/routes/index.js +++ /dev/null @@ -1,6 +0,0 @@ -var express = require('express'); -var router = express.Router(); - - - -module.exports = router; diff --git a/routes/sms.js b/routes/sms.js new file mode 100644 index 0000000..787bd56 --- /dev/null +++ b/routes/sms.js @@ -0,0 +1,340 @@ +const express = require('express') +const router = express.Router() +const { getDB } = require('../database') +const Dysmsapi20170525 = require('@alicloud/dysmsapi20170525') +const OpenApi = require('@alicloud/openapi-client') +const { Config } = require('@alicloud/openapi-client') + +/** + * @swagger + * tags: + * name: SMS + * description: 短信验证码相关接口 + */ + +/** + * @swagger + * components: + * schemas: + * SMSVerification: + * type: object + * properties: + * phone: + * type: string + * description: 手机号码 + * code: + * type: string + * description: 验证码 + */ + +// 阿里云短信配置 +const config = new Config({ + // 您的AccessKey ID + accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID || 'your_access_key_id', + // 您的AccessKey Secret + accessKeySecret: process.env.ALIYUN_ACCESS_KEY_SECRET || 'your_access_key_secret', + // 访问的域名 + endpoint: 'dysmsapi.aliyuncs.com' +}) + +// 创建短信客户端 +const client = new Dysmsapi20170525.default(config) + +// 短信模板配置 +const SMS_CONFIG = { + signName: process.env.ALIYUN_SMS_SIGN_NAME || '您的签名', // 短信签名 + templateCode: process.env.ALIYUN_SMS_TEMPLATE_CODE || 'SMS_XXXXXX', // 短信模板CODE + // 开发环境标识 + isDevelopment: process.env.NODE_ENV !== 'production' +} + +// 存储验证码的内存对象(生产环境建议使用Redis) +const smsCodeStore = new Map() + +// 验证码有效期(5分钟) +const CODE_EXPIRE_TIME = 5 * 60 * 1000 +// 最大尝试次数 +const MAX_ATTEMPTS = 3 +// 发送频率限制(60秒) +const SEND_INTERVAL = 60 * 1000 + +/** + * 生成6位数字验证码 + * @returns {string} 验证码 + */ +function generateSMSCode() { + return Math.floor(100000 + Math.random() * 900000).toString(); +} + +/** + * @swagger + * /api/sms/send: + * post: + * summary: 发送短信验证码 + * tags: [SMS] + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - phone + * properties: + * phone: + * type: string + * description: 手机号码 + * responses: + * 200: + * description: 验证码发送成功 + * content: + * application/json: + * schema: + * type: object + * properties: + * success: + * type: boolean + * example: true + * message: + * type: string + * example: 验证码发送成功 + * 400: + * description: 参数错误或发送频率限制 + * 500: + * description: 服务器错误 + */ +router.post('/send', async (req, res) => { + try { + const { phone } = req.body + console.log(phone) + // 验证手机号格式 + const phoneRegex = /^1[3-9]\d{9}$/ + if (!phoneRegex.test(phone)) { + return res.json({ + success: false, + message: '手机号格式不正确' + }) + } + + // 检查发送频率限制 + const lastSendTime = smsCodeStore.get(`last_send_${phone}`) + if (lastSendTime && Date.now() - lastSendTime < SEND_INTERVAL) { + const remainingTime = Math.ceil((SEND_INTERVAL - (Date.now() - lastSendTime)) / 1000) + return res.json({ + success: false, + message: `请等待${remainingTime}秒后再发送` + }) + } + + // 生成6位数字验证码 + const code = Math.random().toString().slice(-6) + + // 存储验证码信息 + smsCodeStore.set(phone, { + code, + timestamp: Date.now(), + attempts: 0 + }) + + // 记录发送时间 + smsCodeStore.set(`last_send_${phone}`, Date.now()) + // 生产环境发送真实短信 + try { + console.log(code); + res.json({ + success: true, + message: '验证码发送成功' + }) + return + const sendSmsRequest = new Dysmsapi20170525.SendSmsRequest({ + phoneNumbers: phone, + signName: SMS_CONFIG.signName, + templateCode: SMS_CONFIG.templateCode, + templateParam: JSON.stringify({ code }) + }) + + const response = await client.sendSms(sendSmsRequest) + console.log(response.body); + + if (response.body.code === 'OK') { + res.json({ + success: true, + message: '验证码发送成功' + }) + } else { + console.error('阿里云短信发送失败:', response.body) + res.json({ + success: false, + message: '发送失败,请稍后重试' + }) + } + } catch (smsError) { + console.error('阿里云短信API调用失败:', smsError) + res.json({ + success: false, + message: '发送失败,请稍后重试' + }) + } + + } catch (error) { + console.error('发送短信验证码失败:', error) + res.status(500).json({ + success: false, + message: '发送失败,请稍后重试' + }) + } +}); + +/** + * @swagger + * /api/sms/verify: + * post: + * summary: 验证短信验证码 + * tags: [SMS] + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - phone + * - code + * properties: + * phone: + * type: string + * description: 手机号码 + * code: + * type: string + * description: 验证码 + * responses: + * 200: + * description: 验证码验证成功 + * content: + * application/json: + * schema: + * type: object + * properties: + * success: + * type: boolean + * example: true + * message: + * type: string + * example: 手机号验证成功 + * data: + * type: object + * properties: + * phone: + * type: string + * verified: + * type: boolean + * 400: + * description: 参数错误或验证码错误 + * 500: + * description: 服务器错误 + */ +router.post('/verify', async (req, res) => { + try { + const { phone, code } = req.body; + + if (!phone || !code) { + return res.status(400).json({ success: false, message: '手机号和验证码不能为空' }); + } + + const storedData = smsCodeStore.get(phone); + + if (!storedData) { + return res.status(400).json({ success: false, message: '验证码不存在或已过期' }); + } + + // 检查验证码是否过期(5分钟) + if (Date.now() - storedData.timestamp > 300000) { + smsCodeStore.delete(phone); + return res.status(400).json({ success: false, message: '验证码已过期' }); + } + + // 检查尝试次数(最多3次) + if (storedData.attempts >= 3) { + smsCodeStore.delete(phone); + return res.status(400).json({ success: false, message: '验证码错误次数过多,请重新获取' }); + } + + // 验证验证码 + if (storedData.code !== code) { + storedData.attempts++; + smsCodeStore.set(phone, storedData); + return res.status(400).json({ + success: false, + message: `验证码错误,还可尝试${3 - storedData.attempts}次` + }); + } + + // 验证成功,删除验证码 + smsCodeStore.delete(phone); + smsCodeStore.delete(`time_${phone}`); + + res.json({ + success: true, + message: '手机号验证成功', + data: { + phone: phone, + verified: true + } + }); + + } catch (error) { + console.error('验证短信验证码错误:', error); + res.status(500).json({ success: false, message: '验证失败' }); + } +}); + +/** + * 导出验证手机号的函数供其他模块使用 + * @param {string} phone 手机号 + * @param {string} code 验证码 + * @returns {boolean} 验证结果 + */ +function verifySMSCode(phone, code) { + const storedData = smsCodeStore.get(phone); + + if (!storedData) { + return false; + } + + // 检查是否过期 + if (Date.now() - storedData.timestamp > 300000) { + smsCodeStore.delete(phone); + return false; + } + + // 检查尝试次数 + if (storedData.attempts >= 3) { + smsCodeStore.delete(phone); + return false; + } + + // 验证验证码 + if (storedData.code === code) { + smsCodeStore.delete(phone); + smsCodeStore.delete(`time_${phone}`); + return true; + } + + return false; +} + +// 清理过期验证码的定时任务 +setInterval(() => { + const now = Date.now(); + for (const [key, value] of smsCodeStore.entries()) { + if (key.startsWith('time_')) continue; + + if (value.timestamp && now - value.timestamp > 300000) { + smsCodeStore.delete(key); + smsCodeStore.delete(`time_${key}`); + } + } +}, 60000); // 每分钟清理一次 + +module.exports = router; +module.exports.verifySMSCode = verifySMSCode; \ No newline at end of file diff --git a/routes/users.js b/routes/users.js deleted file mode 100644 index b5a7010..0000000 --- a/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/',function(req, res, next) { - res.send('respond with a resource'); -}); - -module.exports = router;