Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 72b3babfd8 | |||
| c63e14ddf3 | |||
| 46ded91c41 | |||
| 1aaa536cc6 | |||
| f35a097014 | |||
| 4298486382 | |||
| d4f9cf35a5 | |||
| 9178e892d6 | |||
| f724ba0f07 | |||
| 768352b804 | |||
| e141583f91 | |||
| 8ffa64a71d | |||
| 0ab5234b5b | |||
| b0444e1517 | |||
| 11c2da6d7a | |||
| 01d7b67665 | |||
| 5510bc3f01 | |||
| 93c8c0f871 | |||
| e34bcb2aa8 | |||
| 646a0293a5 | |||
| 5a83f433b6 | |||
| cd7bcd9d11 | |||
| b389f078a5 | |||
| 547d5dba1c | |||
| e597974581 |
@@ -0,0 +1,10 @@
|
|||||||
|
.git*
|
||||||
|
|
||||||
|
tools*
|
||||||
|
mysql*
|
||||||
|
letsencrypt*
|
||||||
|
test*
|
||||||
|
|
||||||
|
.env*
|
||||||
|
.github*
|
||||||
|
LICENSE*
|
||||||
@@ -5,7 +5,7 @@ WEB_PORT=3200
|
|||||||
DB_HOSTNAME=database
|
DB_HOSTNAME=database
|
||||||
DB_DATABASE=auth
|
DB_DATABASE=auth
|
||||||
DB_USERNAME=auth
|
DB_USERNAME=auth
|
||||||
DB_PASSWORD=venusaur
|
DB_PASSWORD=charizard
|
||||||
|
|
||||||
MAIL_SMTP=smtp.example.com
|
MAIL_SMTP=smtp.example.com
|
||||||
MAIL_USERNAME=foobar@example.com
|
MAIL_USERNAME=foobar@example.com
|
||||||
|
|||||||
+1
-1
@@ -2,8 +2,8 @@
|
|||||||
FROM node:15
|
FROM node:15
|
||||||
WORKDIR "/app"
|
WORKDIR "/app"
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm install --production
|
|
||||||
COPY . /app
|
COPY . /app
|
||||||
|
RUN npm install --production
|
||||||
EXPOSE 3200
|
EXPOSE 3200
|
||||||
USER node
|
USER node
|
||||||
ENTRYPOINT ["bash", "-c"]
|
ENTRYPOINT ["bash", "-c"]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ An API centric auth server. Uses Sequelize and mariaDB by default.
|
|||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
|
|
||||||
There are multiple ways to run this app - it can run on it's own via `npm start` (for production) or `npm run dev` (for development). it can also run inside docker using `docker-compose up --build` - run `node configure-script.js` to generate docker-compose.yml.
|
There are multiple ways to run this app - it can run on it's own via `npm start` (for production) or `npm run dev` (for development). it can also run inside docker using `docker-compose up --build` - run `node configure-script.js` to generate docker-compose.yml and startup.sql.
|
||||||
|
|
||||||
# API
|
# API
|
||||||
|
|
||||||
@@ -19,9 +19,11 @@ Content-Type: application/json
|
|||||||
"password": "helloworld"
|
"password": "helloworld"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//DOCS: Used for validating the email address above
|
//DOCS: Used for validating the email address above
|
||||||
GET /auth/validation?username=example&token=12345678
|
GET /auth/validation?username=example&token=12345678
|
||||||
|
|
||||||
|
|
||||||
//DOCS: Login after validation
|
//DOCS: Login after validation
|
||||||
POST /auth/login
|
POST /auth/login
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
@@ -37,7 +39,8 @@ Content-Type: application/json
|
|||||||
"refreshToken": "fghij"
|
"refreshToken": "fghij"
|
||||||
}
|
}
|
||||||
|
|
||||||
//Replace an expired authToken pair with these values
|
|
||||||
|
//DOCS: Replace an expired authToken pair with these values
|
||||||
POST /auth/token
|
POST /auth/token
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
@@ -45,6 +48,7 @@ Content-Type: application/json
|
|||||||
"token": "refreshToken"
|
"token": "refreshToken"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//DOCS: After this is called, the refresh route will no longer work
|
//DOCS: After this is called, the refresh route will no longer work
|
||||||
DELETE /auth/logout
|
DELETE /auth/logout
|
||||||
Authorization: Bearer accessToken
|
Authorization: Bearer accessToken
|
||||||
@@ -53,6 +57,7 @@ Authorization: Bearer accessToken
|
|||||||
"token": "refreshToken"
|
"token": "refreshToken"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//DOCS: Retreives the private account data, results vary
|
//DOCS: Retreives the private account data, results vary
|
||||||
GET /auth/account
|
GET /auth/account
|
||||||
Authorization: Bearer accessToken
|
Authorization: Bearer accessToken
|
||||||
@@ -63,11 +68,13 @@ Authorization: Bearer accessToken
|
|||||||
"refreshToken": "fghij"
|
"refreshToken": "fghij"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//DOCS: Update account data, input varies, but is always JSON
|
//DOCS: Update account data, input varies, but is always JSON
|
||||||
PATCH /auth/account
|
PATCH /auth/account
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
Authorization: Bearer accessToken
|
Authorization: Bearer accessToken
|
||||||
|
|
||||||
|
|
||||||
//DOCS: Sets the timer, account will be deleted after 2 days
|
//DOCS: Sets the timer, account will be deleted after 2 days
|
||||||
DELETE /auth/account
|
DELETE /auth/account
|
||||||
Authorization: Bearer accessToken
|
Authorization: Bearer accessToken
|
||||||
@@ -76,14 +83,4 @@ Content-Type: application/json
|
|||||||
{
|
{
|
||||||
"password": "helloworld"
|
"password": "helloworld"
|
||||||
}
|
}
|
||||||
|
|
||||||
//DOCS: Sets the privilege of the specified user; usable only by admins
|
|
||||||
PATCH /auth/admin/privilege
|
|
||||||
Authorization: Bearer accessToken
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"username": "example",
|
|
||||||
"privilege: "administrator"
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
Generated
+155
-174
@@ -11,16 +11,16 @@
|
|||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.6.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"mariadb": "^2.5.2",
|
"mariadb": "^2.5.4",
|
||||||
"node-cron": "^2.0.3",
|
"node-cron": "^2.0.3",
|
||||||
"nodemailer": "^6.5.0",
|
"nodemailer": "^6.6.3",
|
||||||
"sequelize": "^6.5.0"
|
"sequelize": "^6.6.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodemon": "^2.0.7"
|
"nodemon": "^2.0.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sindresorhus/is": {
|
"node_modules/@sindresorhus/is": {
|
||||||
@@ -45,14 +45,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/geojson": {
|
"node_modules/@types/geojson": {
|
||||||
"version": "7946.0.7",
|
"version": "7946.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
|
||||||
"integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ=="
|
"integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "14.14.35",
|
"version": "14.17.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz",
|
||||||
"integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag=="
|
"integrity": "sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA=="
|
||||||
},
|
},
|
||||||
"node_modules/abbrev": {
|
"node_modules/abbrev": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@@ -161,9 +161,9 @@
|
|||||||
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
|
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
|
||||||
},
|
},
|
||||||
"node_modules/anymatch": {
|
"node_modules/anymatch": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||||
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
|
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"normalize-path": "^3.0.0",
|
"normalize-path": "^3.0.0",
|
||||||
@@ -179,9 +179,9 @@
|
|||||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||||
},
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/bcryptjs": {
|
"node_modules/bcryptjs": {
|
||||||
@@ -361,25 +361,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "3.5.1",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
||||||
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
|
"integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"anymatch": "~3.1.1",
|
"anymatch": "~3.1.2",
|
||||||
"braces": "~3.0.2",
|
"braces": "~3.0.2",
|
||||||
"fsevents": "~2.3.1",
|
"glob-parent": "~5.1.2",
|
||||||
"glob-parent": "~5.1.0",
|
|
||||||
"is-binary-path": "~2.1.0",
|
"is-binary-path": "~2.1.0",
|
||||||
"is-glob": "~4.0.1",
|
"is-glob": "~4.0.1",
|
||||||
"normalize-path": "~3.0.0",
|
"normalize-path": "~3.0.0",
|
||||||
"readdirp": "~3.5.0"
|
"readdirp": "~3.6.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 8.10.0"
|
"node": ">= 8.10.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"fsevents": "~2.3.1"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ci-info": {
|
"node_modules/ci-info": {
|
||||||
@@ -572,11 +571,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
"version": "8.2.0",
|
"version": "8.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
|
||||||
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
|
"integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dottie": {
|
"node_modules/dottie": {
|
||||||
@@ -718,9 +717,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/forwarded": {
|
"node_modules/forwarded": {
|
||||||
"version": "0.1.2",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
|
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@@ -733,20 +732,6 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fsevents": {
|
|
||||||
"version": "2.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
|
||||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
|
||||||
"dev": true,
|
|
||||||
"hasInstallScript": true,
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/get-stream": {
|
"node_modules/get-stream": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||||
@@ -889,9 +874,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/inflection": {
|
"node_modules/inflection": {
|
||||||
"version": "1.12.0",
|
"version": "1.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz",
|
||||||
"integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=",
|
"integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA==",
|
||||||
"engines": [
|
"engines": [
|
||||||
"node >= 0.4.0"
|
"node >= 0.4.0"
|
||||||
]
|
]
|
||||||
@@ -1195,14 +1180,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mariadb": {
|
"node_modules/mariadb": {
|
||||||
"version": "2.5.3",
|
"version": "2.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/mariadb/-/mariadb-2.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/mariadb/-/mariadb-2.5.4.tgz",
|
||||||
"integrity": "sha512-9ZbQ1zLqasLCQy6KDcPHtX7EUIMBlQ8p64gNR61+yfpCIWjPDji3aR56LvwbOz1QnQbVgYBOJ4J/pHoFN5MR+w==",
|
"integrity": "sha512-4vQgMRyBIN9EwSQG0vzjR9D8bscPH0dGPJt67qVlOkHSiSm0xUatg1Pft4o1LzORgeOW4PheiY/HBE9bYYmNCA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/geojson": "^7946.0.7",
|
"@types/geojson": "^7946.0.7",
|
||||||
"@types/node": "^14.14.28",
|
"@types/node": "^14.14.28",
|
||||||
"denque": "^1.4.1",
|
"denque": "^1.5.0",
|
||||||
"iconv-lite": "^0.6.2",
|
"iconv-lite": "^0.6.3",
|
||||||
"long": "^4.0.0",
|
"long": "^4.0.0",
|
||||||
"moment-timezone": "^0.5.33",
|
"moment-timezone": "^0.5.33",
|
||||||
"please-upgrade-node": "^3.2.0"
|
"please-upgrade-node": "^3.2.0"
|
||||||
@@ -1212,9 +1197,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mariadb/node_modules/iconv-lite": {
|
"node_modules/mariadb/node_modules/iconv-lite": {
|
||||||
"version": "0.6.2",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
|
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
},
|
},
|
||||||
@@ -1255,19 +1240,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mime-db": {
|
"node_modules/mime-db": {
|
||||||
"version": "1.46.0",
|
"version": "1.48.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
|
||||||
"integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==",
|
"integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mime-types": {
|
"node_modules/mime-types": {
|
||||||
"version": "2.1.29",
|
"version": "2.1.31",
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz",
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
|
||||||
"integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==",
|
"integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mime-db": "1.46.0"
|
"mime-db": "1.48.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
@@ -1346,17 +1331,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/nodemailer": {
|
"node_modules/nodemailer": {
|
||||||
"version": "6.5.0",
|
"version": "6.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.3.tgz",
|
||||||
"integrity": "sha512-Tm4RPrrIZbnqDKAvX+/4M+zovEReiKlEXWDzG4iwtpL9X34MJY+D5LnQPH/+eghe8DLlAVshHAJZAZWBGhkguw==",
|
"integrity": "sha512-faZFufgTMrphYoDjvyVpbpJcYzwyFnbAMmQtj1lVBYAUSm3SOy2fIdd9+Mr4UxPosBa0JRw9bJoIwQn+nswiew==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/nodemon": {
|
"node_modules/nodemon": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.12.tgz",
|
||||||
"integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==",
|
"integrity": "sha512-egCTmNZdObdBxUBw6ZNwvZ/xzk24CKRs5K6d+5zbmrMr7rOpPmfPeF6OxM3DDpaRx331CQRFEktn+wrFFfBSOA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1407,6 +1392,9 @@
|
|||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"nopt": "bin/nopt.js"
|
"nopt": "bin/nopt.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/normalize-path": {
|
"node_modules/normalize-path": {
|
||||||
@@ -1419,9 +1407,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/normalize-url": {
|
"node_modules/normalize-url": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
|
||||||
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
|
"integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@@ -1510,9 +1498,9 @@
|
|||||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "2.2.2",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
|
||||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
|
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.6"
|
"node": ">=8.6"
|
||||||
@@ -1539,11 +1527,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/proxy-addr": {
|
"node_modules/proxy-addr": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"forwarded": "~0.1.2",
|
"forwarded": "0.2.0",
|
||||||
"ipaddr.js": "1.9.1"
|
"ipaddr.js": "1.9.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1624,9 +1612,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/readdirp": {
|
"node_modules/readdirp": {
|
||||||
"version": "3.5.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
|
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"picomatch": "^2.2.1"
|
"picomatch": "^2.2.1"
|
||||||
@@ -1749,13 +1737,13 @@
|
|||||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||||
},
|
},
|
||||||
"node_modules/sequelize": {
|
"node_modules/sequelize": {
|
||||||
"version": "6.6.2",
|
"version": "6.6.5",
|
||||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.6.5.tgz",
|
||||||
"integrity": "sha512-H/zrzmTK+tis9PJaSigkuXI57nKBvNCtPQol0yxCvau1iWLzSOuq8t3tMOVeQ+Ep8QH2HoD9/+FCCIAqzUr/BQ==",
|
"integrity": "sha512-QyRrJrDRiwuiILqTMHUA1yWOPIL12KlfmgZ3hnzQwbMvp2vJ6fzu9bYJQB+qPMosck4mBUggY4Cjoc6Et8FBIQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"dottie": "^2.0.0",
|
"dottie": "^2.0.0",
|
||||||
"inflection": "1.12.0",
|
"inflection": "1.13.1",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"moment": "^2.26.0",
|
"moment": "^2.26.0",
|
||||||
"moment-timezone": "^0.5.31",
|
"moment-timezone": "^0.5.31",
|
||||||
@@ -1764,7 +1752,7 @@
|
|||||||
"sequelize-pool": "^6.0.0",
|
"sequelize-pool": "^6.0.0",
|
||||||
"toposort-class": "^1.0.1",
|
"toposort-class": "^1.0.1",
|
||||||
"uuid": "^8.1.0",
|
"uuid": "^8.1.0",
|
||||||
"validator": "^10.11.0",
|
"validator": "^13.6.0",
|
||||||
"wkx": "^0.5.0"
|
"wkx": "^0.5.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1800,9 +1788,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sequelize/node_modules/debug": {
|
"node_modules/sequelize/node_modules/debug": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "2.1.2"
|
"ms": "2.1.2"
|
||||||
},
|
},
|
||||||
@@ -2092,9 +2080,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/validator": {
|
"node_modules/validator": {
|
||||||
"version": "10.11.0",
|
"version": "13.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz",
|
||||||
"integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==",
|
"integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
@@ -2177,14 +2165,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/geojson": {
|
"@types/geojson": {
|
||||||
"version": "7946.0.7",
|
"version": "7946.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
|
||||||
"integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ=="
|
"integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA=="
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "14.14.35",
|
"version": "14.17.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz",
|
||||||
"integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag=="
|
"integrity": "sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA=="
|
||||||
},
|
},
|
||||||
"abbrev": {
|
"abbrev": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@@ -2271,9 +2259,9 @@
|
|||||||
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
|
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
|
||||||
},
|
},
|
||||||
"anymatch": {
|
"anymatch": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||||
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
|
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"normalize-path": "^3.0.0",
|
"normalize-path": "^3.0.0",
|
||||||
@@ -2286,9 +2274,9 @@
|
|||||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||||
},
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"bcryptjs": {
|
"bcryptjs": {
|
||||||
@@ -2430,19 +2418,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
"version": "3.5.1",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
||||||
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
|
"integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"anymatch": "~3.1.1",
|
"anymatch": "~3.1.2",
|
||||||
"braces": "~3.0.2",
|
"braces": "~3.0.2",
|
||||||
"fsevents": "~2.3.1",
|
"fsevents": "~2.3.2",
|
||||||
"glob-parent": "~5.1.0",
|
"glob-parent": "~5.1.2",
|
||||||
"is-binary-path": "~2.1.0",
|
"is-binary-path": "~2.1.0",
|
||||||
"is-glob": "~4.0.1",
|
"is-glob": "~4.0.1",
|
||||||
"normalize-path": "~3.0.0",
|
"normalize-path": "~3.0.0",
|
||||||
"readdirp": "~3.5.0"
|
"readdirp": "~3.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ci-info": {
|
"ci-info": {
|
||||||
@@ -2593,9 +2581,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dotenv": {
|
"dotenv": {
|
||||||
"version": "8.2.0",
|
"version": "8.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
|
||||||
"integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
|
"integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g=="
|
||||||
},
|
},
|
||||||
"dottie": {
|
"dottie": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
@@ -2718,22 +2706,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"forwarded": {
|
"forwarded": {
|
||||||
"version": "0.1.2",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
|
||||||
},
|
},
|
||||||
"fresh": {
|
"fresh": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||||
},
|
},
|
||||||
"fsevents": {
|
|
||||||
"version": "2.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
|
||||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"get-stream": {
|
"get-stream": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||||
@@ -2843,9 +2824,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"inflection": {
|
"inflection": {
|
||||||
"version": "1.12.0",
|
"version": "1.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.1.tgz",
|
||||||
"integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY="
|
"integrity": "sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA=="
|
||||||
},
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
@@ -3092,23 +3073,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mariadb": {
|
"mariadb": {
|
||||||
"version": "2.5.3",
|
"version": "2.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/mariadb/-/mariadb-2.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/mariadb/-/mariadb-2.5.4.tgz",
|
||||||
"integrity": "sha512-9ZbQ1zLqasLCQy6KDcPHtX7EUIMBlQ8p64gNR61+yfpCIWjPDji3aR56LvwbOz1QnQbVgYBOJ4J/pHoFN5MR+w==",
|
"integrity": "sha512-4vQgMRyBIN9EwSQG0vzjR9D8bscPH0dGPJt67qVlOkHSiSm0xUatg1Pft4o1LzORgeOW4PheiY/HBE9bYYmNCA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/geojson": "^7946.0.7",
|
"@types/geojson": "^7946.0.7",
|
||||||
"@types/node": "^14.14.28",
|
"@types/node": "^14.14.28",
|
||||||
"denque": "^1.4.1",
|
"denque": "^1.5.0",
|
||||||
"iconv-lite": "^0.6.2",
|
"iconv-lite": "^0.6.3",
|
||||||
"long": "^4.0.0",
|
"long": "^4.0.0",
|
||||||
"moment-timezone": "^0.5.33",
|
"moment-timezone": "^0.5.33",
|
||||||
"please-upgrade-node": "^3.2.0"
|
"please-upgrade-node": "^3.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.6.2",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
|
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
}
|
}
|
||||||
@@ -3136,16 +3117,16 @@
|
|||||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||||
},
|
},
|
||||||
"mime-db": {
|
"mime-db": {
|
||||||
"version": "1.46.0",
|
"version": "1.48.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
|
||||||
"integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ=="
|
"integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ=="
|
||||||
},
|
},
|
||||||
"mime-types": {
|
"mime-types": {
|
||||||
"version": "2.1.29",
|
"version": "2.1.31",
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz",
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
|
||||||
"integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==",
|
"integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"mime-db": "1.46.0"
|
"mime-db": "1.48.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mimic-response": {
|
"mimic-response": {
|
||||||
@@ -3202,14 +3183,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nodemailer": {
|
"nodemailer": {
|
||||||
"version": "6.5.0",
|
"version": "6.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.3.tgz",
|
||||||
"integrity": "sha512-Tm4RPrrIZbnqDKAvX+/4M+zovEReiKlEXWDzG4iwtpL9X34MJY+D5LnQPH/+eghe8DLlAVshHAJZAZWBGhkguw=="
|
"integrity": "sha512-faZFufgTMrphYoDjvyVpbpJcYzwyFnbAMmQtj1lVBYAUSm3SOy2fIdd9+Mr4UxPosBa0JRw9bJoIwQn+nswiew=="
|
||||||
},
|
},
|
||||||
"nodemon": {
|
"nodemon": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.12.tgz",
|
||||||
"integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==",
|
"integrity": "sha512-egCTmNZdObdBxUBw6ZNwvZ/xzk24CKRs5K6d+5zbmrMr7rOpPmfPeF6OxM3DDpaRx331CQRFEktn+wrFFfBSOA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chokidar": "^3.2.2",
|
"chokidar": "^3.2.2",
|
||||||
@@ -3257,9 +3238,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"normalize-url": {
|
"normalize-url": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
|
||||||
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
|
"integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
@@ -3326,9 +3307,9 @@
|
|||||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||||
},
|
},
|
||||||
"picomatch": {
|
"picomatch": {
|
||||||
"version": "2.2.2",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
|
||||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
|
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"please-upgrade-node": {
|
"please-upgrade-node": {
|
||||||
@@ -3346,11 +3327,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"proxy-addr": {
|
"proxy-addr": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"forwarded": "~0.1.2",
|
"forwarded": "0.2.0",
|
||||||
"ipaddr.js": "1.9.1"
|
"ipaddr.js": "1.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3413,9 +3394,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"readdirp": {
|
"readdirp": {
|
||||||
"version": "3.5.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
|
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"picomatch": "^2.2.1"
|
"picomatch": "^2.2.1"
|
||||||
@@ -3521,13 +3502,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sequelize": {
|
"sequelize": {
|
||||||
"version": "6.6.2",
|
"version": "6.6.5",
|
||||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.6.5.tgz",
|
||||||
"integrity": "sha512-H/zrzmTK+tis9PJaSigkuXI57nKBvNCtPQol0yxCvau1iWLzSOuq8t3tMOVeQ+Ep8QH2HoD9/+FCCIAqzUr/BQ==",
|
"integrity": "sha512-QyRrJrDRiwuiILqTMHUA1yWOPIL12KlfmgZ3hnzQwbMvp2vJ6fzu9bYJQB+qPMosck4mBUggY4Cjoc6Et8FBIQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"dottie": "^2.0.0",
|
"dottie": "^2.0.0",
|
||||||
"inflection": "1.12.0",
|
"inflection": "1.13.1",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"moment": "^2.26.0",
|
"moment": "^2.26.0",
|
||||||
"moment-timezone": "^0.5.31",
|
"moment-timezone": "^0.5.31",
|
||||||
@@ -3536,14 +3517,14 @@
|
|||||||
"sequelize-pool": "^6.0.0",
|
"sequelize-pool": "^6.0.0",
|
||||||
"toposort-class": "^1.0.1",
|
"toposort-class": "^1.0.1",
|
||||||
"uuid": "^8.1.0",
|
"uuid": "^8.1.0",
|
||||||
"validator": "^10.11.0",
|
"validator": "^13.6.0",
|
||||||
"wkx": "^0.5.0"
|
"wkx": "^0.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"ms": "2.1.2"
|
"ms": "2.1.2"
|
||||||
}
|
}
|
||||||
@@ -3763,9 +3744,9 @@
|
|||||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||||
},
|
},
|
||||||
"validator": {
|
"validator": {
|
||||||
"version": "10.11.0",
|
"version": "13.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz",
|
||||||
"integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw=="
|
"integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg=="
|
||||||
},
|
},
|
||||||
"vary": {
|
"vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
|
|||||||
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "auth-server",
|
"name": "auth-server",
|
||||||
"version": "1.0.0",
|
"version": "1.4.0",
|
||||||
"description": "An API centric auth server. Uses Sequelize and mariaDB by default.",
|
"description": "An API centric auth server. Uses Sequelize and mariaDB by default.",
|
||||||
"main": "server/server.js",
|
"main": "server/server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -22,15 +22,15 @@
|
|||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.6.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"mariadb": "^2.5.2",
|
"mariadb": "^2.5.4",
|
||||||
"node-cron": "^2.0.3",
|
"node-cron": "^2.0.3",
|
||||||
"nodemailer": "^6.5.0",
|
"nodemailer": "^6.6.3",
|
||||||
"sequelize": "^6.5.0"
|
"sequelize": "^6.6.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodemon": "^2.0.7"
|
"nodemon": "^2.0.12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
const { accounts } = require('../database/models');
|
|
||||||
|
|
||||||
//auth/account/privilege
|
|
||||||
const route = async (req, res) => {
|
|
||||||
const updated = await accounts.update({
|
|
||||||
privilege: req.body.privilege
|
|
||||||
}, {
|
|
||||||
where: {
|
|
||||||
username: req.body.username
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (updated < 1) {
|
|
||||||
return res.status(403).send(`Unknown account`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.status(200).end();
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = route;
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
const { accounts, tokens } = require('../database/models');
|
||||||
|
const Sequelize = require('sequelize');
|
||||||
|
const Op = Sequelize.Op;
|
||||||
|
|
||||||
|
//admin/banuser
|
||||||
|
const route = async (req, res) => {
|
||||||
|
const updated = await accounts.update({
|
||||||
|
banned: true
|
||||||
|
}, {
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
[Op.eq]: req.body.username || ''
|
||||||
|
},
|
||||||
|
admin: {
|
||||||
|
[Op.not]: true
|
||||||
|
},
|
||||||
|
mod: {
|
||||||
|
[Op.not]: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updated[0]) {
|
||||||
|
return res.status(500).send('Failed to set banned status');
|
||||||
|
}
|
||||||
|
|
||||||
|
//forcibly logout
|
||||||
|
tokens.destroy({
|
||||||
|
where: {
|
||||||
|
email: req.body.email || ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).end();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = route;
|
||||||
@@ -20,18 +20,21 @@ module.exports = async () => {
|
|||||||
//check for an existing admin account
|
//check for an existing admin account
|
||||||
const adminRecord = await accounts.findOne({
|
const adminRecord = await accounts.findOne({
|
||||||
where: {
|
where: {
|
||||||
privilege: 'administrator'
|
admin: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (adminRecord == null) {
|
if (adminRecord == null) {
|
||||||
|
const webAddress = process.env.WEB_ADDRESS == 'localhost' ? 'example.com' : process.env.WEB_ADDRESS; //can't log in as "localhost"
|
||||||
await accounts.create({
|
await accounts.create({
|
||||||
privilege: 'administrator',
|
email: `${process.env.ADMIN_DEFAULT_USERNAME}@${webAddress}`,
|
||||||
email: `${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}`,
|
|
||||||
username: `${process.env.ADMIN_DEFAULT_USERNAME}`,
|
username: `${process.env.ADMIN_DEFAULT_USERNAME}`,
|
||||||
hash: await bcrypt.hash(`${process.env.ADMIN_DEFAULT_PASSWORD}`, await bcrypt.genSalt(11))
|
hash: await bcrypt.hash(`${process.env.ADMIN_DEFAULT_PASSWORD}`, await bcrypt.genSalt(11)),
|
||||||
|
type: 'normal',
|
||||||
|
admin: true,
|
||||||
|
mod: true
|
||||||
});
|
});
|
||||||
|
|
||||||
console.warn(`Created default admin account (email: ${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}; password: ${process.env.ADMIN_DEFAULT_PASSWORD})`);
|
console.warn(`Created default admin account (email: ${process.env.ADMIN_DEFAULT_USERNAME}@${webAddress}; password: ${process.env.ADMIN_DEFAULT_PASSWORD})`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
const { accounts } = require('../database/models');
|
||||||
|
const Sequelize = require('sequelize');
|
||||||
|
const Op = Sequelize.Op;
|
||||||
|
|
||||||
|
//admin/admin
|
||||||
|
const route = async (req, res) => {
|
||||||
|
const updated = await accounts.update({
|
||||||
|
admin: true,
|
||||||
|
mod: true
|
||||||
|
}, {
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
[Op.eq]: req.body.username || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updated[0]) {
|
||||||
|
return res.status(500).send('Failed to set admin status');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).end();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = route;
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
const { accounts } = require('../database/models');
|
||||||
|
const Sequelize = require('sequelize');
|
||||||
|
const Op = Sequelize.Op;
|
||||||
|
|
||||||
|
//admin/mod
|
||||||
|
const route = async (req, res) => {
|
||||||
|
const updated = await accounts.update({
|
||||||
|
mod: true
|
||||||
|
}, {
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
[Op.eq]: req.body.username || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updated[0]) {
|
||||||
|
return res.status(500).send('Failed to set mod status');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).end();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = route;
|
||||||
+43
-4
@@ -1,14 +1,50 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
const { accounts } = require('../database/models');
|
||||||
|
|
||||||
//middleware
|
//middleware
|
||||||
const tokenAuth = require('../utilities/token-auth');
|
const tokenAuth = require('../utilities/token-auth');
|
||||||
|
|
||||||
router.use(tokenAuth);
|
router.use(tokenAuth);
|
||||||
|
|
||||||
|
//handle ban stuff
|
||||||
|
router.use(async (req, res, next) => {
|
||||||
|
const record = await accounts.findOne({
|
||||||
|
where: {
|
||||||
|
email: req.user.email || ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!record) {
|
||||||
|
return res.status(500).send('Account not found in banning middleware');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.banned) {
|
||||||
|
return res.status(403).send('This account has been banned');
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
//handle mod stuff
|
||||||
router.use((req, res, next) => {
|
router.use((req, res, next) => {
|
||||||
//check the user's privilege
|
//check the user's mod status
|
||||||
if (req.user.privilege != 'administrator') {
|
if (!req.user.mod) {
|
||||||
return res.status(401).send('Admins only');
|
return res.status(401).send('Mods only');
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
//routes
|
||||||
|
router.post('/banuser', require('./ban-user'));
|
||||||
|
|
||||||
|
//handle admin stuff
|
||||||
|
router.use((req, res, next) => {
|
||||||
|
//check the user's admin status
|
||||||
|
if (!req.user.admin) {
|
||||||
|
return res.status(401).send('Admin only');
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
@@ -17,6 +53,9 @@ router.use((req, res, next) => {
|
|||||||
require('./default-account')(); //generate the default accouunt
|
require('./default-account')(); //generate the default accouunt
|
||||||
|
|
||||||
//basic route management
|
//basic route management
|
||||||
router.patch('/privilege', require('./account-privilege'));
|
router.post('/admin', require('./grant-admin'));
|
||||||
|
router.delete('/admin', require('./remove-admin'));
|
||||||
|
router.post('/mod', require('./grant-mod'));
|
||||||
|
router.delete('/mod', require('./remove-mod'));
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
const { accounts } = require('../database/models');
|
||||||
|
const Sequelize = require('sequelize');
|
||||||
|
const Op = Sequelize.Op;
|
||||||
|
|
||||||
|
//admin/admin
|
||||||
|
const route = async (req, res) => {
|
||||||
|
const updated = await accounts.update({
|
||||||
|
admin: false
|
||||||
|
}, {
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
[Op.eq]: req.body.username || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updated[0]) {
|
||||||
|
return res.status(500).send('Failed to set admin status');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).end();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = route;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
const { accounts } = require('../database/models');
|
||||||
|
const Sequelize = require('sequelize');
|
||||||
|
const Op = Sequelize.Op;
|
||||||
|
|
||||||
|
//admin/admin
|
||||||
|
const route = async (req, res) => {
|
||||||
|
const updated = await accounts.update({
|
||||||
|
admin: false,
|
||||||
|
mod: false
|
||||||
|
}, {
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
[Op.eq]: req.body.username || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updated[0]) {
|
||||||
|
return res.status(500).send('Failed to set mod status');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).end();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = route;
|
||||||
@@ -9,18 +9,26 @@ const { accounts } = require('../database/models');
|
|||||||
|
|
||||||
//auth/deletion
|
//auth/deletion
|
||||||
const route = async (req, res) => {
|
const route = async (req, res) => {
|
||||||
|
if (!req.body.password) {
|
||||||
|
return res.status(401).end('Missing password');
|
||||||
|
}
|
||||||
|
|
||||||
const account = await accounts.findOne({
|
const account = await accounts.findOne({
|
||||||
where: {
|
where: {
|
||||||
id: req.user.id
|
index: req.user.index || ''
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!account) {
|
||||||
|
return res.status(401).end('Missing account');
|
||||||
|
}
|
||||||
|
|
||||||
//compare the user's password
|
//compare the user's password
|
||||||
const compare = utils.promisify(bcrypt.compare);
|
const compare = utils.promisify(bcrypt.compare);
|
||||||
const match = await compare(req.body.password || '', account.hash);
|
const match = await compare(req.body.password, account.hash);
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return res.status(401).send('incorrect password');
|
return res.status(401).send('Incorrect password');
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the deletion time (2 days from now)
|
//set the deletion time (2 days from now)
|
||||||
@@ -30,7 +38,7 @@ const route = async (req, res) => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
where: {
|
where: {
|
||||||
id: req.user.id
|
index: req.user.index
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ const { accounts } = require('../database/models');
|
|||||||
const route = async (req, res) => {
|
const route = async (req, res) => {
|
||||||
const account = await accounts.findOne({
|
const account = await accounts.findOne({
|
||||||
where: {
|
where: {
|
||||||
id: req.user.id
|
index: req.user.index || ''
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!account) {
|
if (!account) {
|
||||||
return res.status(401).send('Unknown account');
|
return res.status(401).end('Unknown account');
|
||||||
}
|
}
|
||||||
|
|
||||||
//respond with the private-facing data
|
//respond with the private-facing data
|
||||||
|
|||||||
@@ -3,20 +3,20 @@ const { accounts } = require('../database/models');
|
|||||||
|
|
||||||
//auth/update
|
//auth/update
|
||||||
const route = async (req, res) => {
|
const route = async (req, res) => {
|
||||||
//generate the password hash
|
if (!req.body.password) {
|
||||||
let hash;
|
return res.status(401).end('Missing password');
|
||||||
|
|
||||||
if (req.body.password) {
|
|
||||||
hash = await bcrypt.hash(req.body.password, await bcrypt.genSalt(11));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//generate the password hash
|
||||||
|
let hash = await bcrypt.hash(req.body.password, await bcrypt.genSalt(11));
|
||||||
|
|
||||||
//update the account
|
//update the account
|
||||||
await accounts.update({
|
await accounts.update({
|
||||||
contact: req.body.contact,
|
contact: req.body.contact,
|
||||||
hash: hash
|
hash: hash
|
||||||
}, {
|
}, {
|
||||||
where: {
|
where: {
|
||||||
id: req.user.id
|
index: req.user.index
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+23
-1
@@ -1,6 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
const { accounts } = require('../database/models');
|
||||||
|
|
||||||
//middleware
|
//middleware
|
||||||
const tokenAuth = require('../utilities/token-auth');
|
const tokenAuth = require('../utilities/token-auth');
|
||||||
|
|
||||||
@@ -15,8 +17,28 @@ router.post('/token', require('./token'));
|
|||||||
//middleware
|
//middleware
|
||||||
router.use(tokenAuth);
|
router.use(tokenAuth);
|
||||||
|
|
||||||
//basic account management (needs a token)
|
//logouts allowed when banned, still needs tokens
|
||||||
router.delete('/logout', require('./logout'));
|
router.delete('/logout', require('./logout'));
|
||||||
|
|
||||||
|
router.use(async (req, res, next) => {
|
||||||
|
const record = await accounts.findOne({
|
||||||
|
where: {
|
||||||
|
email: req.user.email || ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!record) {
|
||||||
|
return res.status(500).send('Account not found in banning middleware');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.banned) {
|
||||||
|
return res.status(403).send('This account has been banned');
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
//basic account management (needs a token)
|
||||||
router.get('/account', require('./account-query'));
|
router.get('/account', require('./account-query'));
|
||||||
router.patch('/account', require('./account-update'));
|
router.patch('/account', require('./account-update'));
|
||||||
router.delete('/account', require('./account-delete'));
|
router.delete('/account', require('./account-delete'));
|
||||||
|
|||||||
+21
-11
@@ -3,7 +3,7 @@ const utils = require('util');
|
|||||||
const bcrypt = require('bcryptjs');
|
const bcrypt = require('bcryptjs');
|
||||||
|
|
||||||
const { accounts } = require('../database/models');
|
const { accounts } = require('../database/models');
|
||||||
const generate = require('../utilities/token-generate');
|
const tokenGenerate = require('../utilities/token-generate');
|
||||||
|
|
||||||
//utilities
|
//utilities
|
||||||
const validateEmail = require('../utilities/validate-email');
|
const validateEmail = require('../utilities/validate-email');
|
||||||
@@ -13,13 +13,13 @@ const route = async (req, res) => {
|
|||||||
//validate the given details
|
//validate the given details
|
||||||
const validateErr = await validateDetails(req.body);
|
const validateErr = await validateDetails(req.body);
|
||||||
if (validateErr) {
|
if (validateErr) {
|
||||||
return res.status(401).send(validateErr);
|
return res.status(401).end(validateErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the existing account
|
//get the existing account
|
||||||
const account = await accounts.findOne({
|
const account = await accounts.findOne({
|
||||||
where: {
|
where: {
|
||||||
email: req.body.email
|
email: req.body.email || ''
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -38,25 +38,35 @@ const route = async (req, res) => {
|
|||||||
//cancel deletion if any
|
//cancel deletion if any
|
||||||
await accounts.update({ deletion: null }, {
|
await accounts.update({ deletion: null }, {
|
||||||
where: {
|
where: {
|
||||||
id: account.id
|
index: account.index
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//reject on banned
|
||||||
|
if (account.banned) {
|
||||||
|
return res.status(403).send('this account has been banned');
|
||||||
|
}
|
||||||
|
|
||||||
//generate the JWT
|
//generate the JWT
|
||||||
const tokens = generate(account.id, account.username, account.privilege);
|
const token = tokenGenerate(account.index, account.email, account.username, account.type, account.admin, account.mod);
|
||||||
|
|
||||||
//finally
|
//finally
|
||||||
res.status(200).json(tokens);
|
res.status(200).json(token);
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateDetails = async (body) => {
|
const validateDetails = async (body) => {
|
||||||
//basic formatting (with an exception for the default admin account)
|
if (!body.email) {
|
||||||
if (!validateEmail(body.email) && body.email != `${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}`) {
|
return 'Missing email';
|
||||||
return 'invalid email';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for existing (banned)
|
if (!body.password) {
|
||||||
//TODO: restore banning
|
return 'Missing password';
|
||||||
|
}
|
||||||
|
|
||||||
|
//basic formatting (with an exception for the default admin account)
|
||||||
|
if (!validateEmail(body.email) && body.email != `${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}`) {
|
||||||
|
return 'Invalid email';
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const destroy = require('../utilities/token-destroy');
|
const tokenDestroy = require('../utilities/token-destroy');
|
||||||
|
|
||||||
//auth/logout
|
//auth/logout
|
||||||
const route = (req, res) => {
|
const route = (req, res) => {
|
||||||
destroy(req.body.token);
|
tokenDestroy(req.body.token);
|
||||||
|
|
||||||
return res.status(200).end();
|
return res.status(200).end();
|
||||||
};
|
};
|
||||||
|
|||||||
+13
-6
@@ -6,7 +6,6 @@ const Op = Sequelize.Op;
|
|||||||
|
|
||||||
const { accounts, pendingSignups } = require('../database/models');
|
const { accounts, pendingSignups } = require('../database/models');
|
||||||
|
|
||||||
|
|
||||||
//utilities
|
//utilities
|
||||||
const uuid = require('../utilities/uuid');
|
const uuid = require('../utilities/uuid');
|
||||||
const validateEmail = require('../utilities/validate-email');
|
const validateEmail = require('../utilities/validate-email');
|
||||||
@@ -46,11 +45,11 @@ const route = async (req, res) => {
|
|||||||
const validateDetails = async (body) => {
|
const validateDetails = async (body) => {
|
||||||
//basic formatting
|
//basic formatting
|
||||||
if (!validateEmail(body.email)) {
|
if (!validateEmail(body.email)) {
|
||||||
return 'invalid email';
|
return 'Invalid email';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!validateUsername(body.username)) {
|
if (!validateUsername(body.username)) {
|
||||||
return 'invalid username';
|
return 'Invalid username';
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for existing (banned)
|
//check for existing (banned)
|
||||||
@@ -64,7 +63,11 @@ const validateDetails = async (body) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (emailRecord) {
|
if (emailRecord) {
|
||||||
return 'email already exists';
|
return 'Email already exists';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!body.username) {
|
||||||
|
return 'Missing username';
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for existing username
|
//check for existing username
|
||||||
@@ -75,12 +78,16 @@ const validateDetails = async (body) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (usernameRecord) {
|
if (usernameRecord) {
|
||||||
return 'username already exists';
|
return 'Username already exists';
|
||||||
}
|
}
|
||||||
|
|
||||||
//validate password
|
//validate password
|
||||||
|
if (!body.password) {
|
||||||
|
return 'Missing password';
|
||||||
|
}
|
||||||
|
|
||||||
if (body.password.length < 8) {
|
if (body.password.length < 8) {
|
||||||
return 'password too short';
|
return 'Password too short';
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
|
|
||||||
const refresh = require('../utilities/token-refresh');
|
const tokenRefresh = require('../utilities/token-refresh');
|
||||||
|
|
||||||
//auth/token
|
//auth/token
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
const refreshToken = req.body.token;
|
const refreshToken = req.body.token;
|
||||||
|
|
||||||
return refresh(refreshToken, (err, tokens) => {
|
return tokenRefresh(refreshToken, (err, token) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(err).end();
|
return res.status(err).end();
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(200).send(tokens);
|
return res.status(200).send(token);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -5,17 +5,17 @@ const route = async (req, res) => {
|
|||||||
//get the existing pending signup
|
//get the existing pending signup
|
||||||
const info = await pendingSignups.findOne({
|
const info = await pendingSignups.findOne({
|
||||||
where: {
|
where: {
|
||||||
username: req.query.username
|
username: req.query.username || ''
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//check the given info
|
//check the given info
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return res.status(401).send('validation failed');
|
return res.status(401).send('Validation failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.token != req.query.token) {
|
if (info.token != req.query.token) {
|
||||||
return res.status(401).send('tokens do not match');
|
return res.status(401).send('Tokens do not match');
|
||||||
}
|
}
|
||||||
|
|
||||||
//move data to the accounts table
|
//move data to the accounts table
|
||||||
@@ -29,7 +29,7 @@ const route = async (req, res) => {
|
|||||||
//delete the pending signup
|
//delete the pending signup
|
||||||
pendingSignups.destroy({
|
pendingSignups.destroy({
|
||||||
where: {
|
where: {
|
||||||
username: req.query.username
|
username: req.query.username || ''
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const Sequelize = require('sequelize');
|
|||||||
const sequelize = require('..');
|
const sequelize = require('..');
|
||||||
|
|
||||||
module.exports = sequelize.define('accounts', {
|
module.exports = sequelize.define('accounts', {
|
||||||
id: {
|
index: {
|
||||||
type: Sequelize.INTEGER(11),
|
type: Sequelize.INTEGER(11),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
autoIncrement: true,
|
autoIncrement: true,
|
||||||
@@ -10,12 +10,6 @@ module.exports = sequelize.define('accounts', {
|
|||||||
unique: true
|
unique: true
|
||||||
},
|
},
|
||||||
|
|
||||||
privilege: {
|
|
||||||
type: Sequelize.ENUM,
|
|
||||||
values: ['administrator', 'moderator', 'alpha', 'beta', 'gamma', 'normal'],
|
|
||||||
defaultValue: 'normal'
|
|
||||||
},
|
|
||||||
|
|
||||||
email: {
|
email: {
|
||||||
type: 'varchar(320)',
|
type: 'varchar(320)',
|
||||||
unique: true
|
unique: true
|
||||||
@@ -28,6 +22,30 @@ module.exports = sequelize.define('accounts', {
|
|||||||
|
|
||||||
hash: 'varchar(100)', //for passwords
|
hash: 'varchar(100)', //for passwords
|
||||||
|
|
||||||
|
type: {
|
||||||
|
type: Sequelize.ENUM,
|
||||||
|
values: ['normal', 'alpha', 'beta', 'gamma'],
|
||||||
|
defaultValue: 'normal'
|
||||||
|
},
|
||||||
|
|
||||||
|
admin: {
|
||||||
|
type: Sequelize.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false
|
||||||
|
},
|
||||||
|
|
||||||
|
mod: {
|
||||||
|
type: Sequelize.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false
|
||||||
|
},
|
||||||
|
|
||||||
|
banned: {
|
||||||
|
type: Sequelize.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false
|
||||||
|
},
|
||||||
|
|
||||||
contact: {
|
contact: {
|
||||||
type: Sequelize.BOOLEAN,
|
type: Sequelize.BOOLEAN,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ const sequelize = require('..');
|
|||||||
|
|
||||||
module.exports = sequelize.define('tokens', {
|
module.exports = sequelize.define('tokens', {
|
||||||
token: 'varchar(320)',
|
token: 'varchar(320)',
|
||||||
|
email: 'varchar(320)'
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-2
@@ -5,11 +5,10 @@ require('dotenv').config();
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const app = express();
|
const app = express();
|
||||||
const server = require('http').Server(app);
|
const server = require('http').Server(app);
|
||||||
const bodyParser = require('body-parser');
|
|
||||||
const cors = require('cors');
|
const cors = require('cors');
|
||||||
|
|
||||||
//config
|
//config
|
||||||
app.use(bodyParser.json());
|
app.use(express.json());
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
|
||||||
//database connection
|
//database connection
|
||||||
|
|||||||
@@ -2,17 +2,20 @@ const jwt = require('jsonwebtoken');
|
|||||||
const { tokens } = require('../database/models');
|
const { tokens } = require('../database/models');
|
||||||
|
|
||||||
//generates a JWT token based on the given arguments
|
//generates a JWT token based on the given arguments
|
||||||
module.exports = (id, username, privilege) => {
|
module.exports = (index, email, username, type, admin, mod) => {
|
||||||
const content = {
|
const content = {
|
||||||
id,
|
index,
|
||||||
|
email,
|
||||||
username,
|
username,
|
||||||
privilege
|
type,
|
||||||
|
admin,
|
||||||
|
mod,
|
||||||
};
|
};
|
||||||
|
|
||||||
const accessToken = jwt.sign(content, process.env.SECRET_ACCESS, { expiresIn: '10m' });
|
const accessToken = jwt.sign(content, process.env.SECRET_ACCESS, { expiresIn: '10m' });
|
||||||
const refreshToken = jwt.sign(content, process.env.SECRET_REFRESH, { expiresIn: '30d' });
|
const refreshToken = jwt.sign(content, process.env.SECRET_REFRESH, { expiresIn: '30d' });
|
||||||
|
|
||||||
tokens.create({ token: refreshToken });
|
tokens.create({ token: refreshToken, email: email });
|
||||||
|
|
||||||
return { accessToken, refreshToken };
|
return { accessToken, refreshToken };
|
||||||
};
|
};
|
||||||
@@ -24,7 +24,7 @@ module.exports = (token, callback) => {
|
|||||||
return callback(403);
|
return callback(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = generate(user.id, user.username, user.privilege);
|
const result = generate(user.index, user.email, user.username, user.type, user.admin, user.mod);
|
||||||
|
|
||||||
destroy(token);
|
destroy(token);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `accounts` CHANGE `id` `index` INT( 11 ) NOT NULL AUTO_INCREMENT;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
DROP TABLE tokens;
|
||||||
Reference in New Issue
Block a user