Adding Basic API Documentation
This commit is contained in:
parent
e09c6df9f6
commit
18ea5de8aa
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,3 +9,4 @@ logs/
|
|||||||
yarn-error\.log
|
yarn-error\.log
|
||||||
config.ini
|
config.ini
|
||||||
.env
|
.env
|
||||||
|
doc/
|
6
apidoc.json
Normal file
6
apidoc.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "openauth",
|
||||||
|
"description": "Open Auth REST API",
|
||||||
|
"title": "Open Auth REST",
|
||||||
|
"url": "/api"
|
||||||
|
}
|
@ -28,10 +28,10 @@
|
|||||||
"Mail linked with other account": "Mail ist bereits mit einem anderen Account verbunden",
|
"Mail linked with other account": "Mail ist bereits mit einem anderen Account verbunden",
|
||||||
"Registration code already used": "Registrierungs Schlüssel wurde bereits verwendet",
|
"Registration code already used": "Registrierungs Schlüssel wurde bereits verwendet",
|
||||||
"Administration": "Administration",
|
"Administration": "Administration",
|
||||||
"Field {{field}} is not defined": "Feld {{field}} ist nicht deklariert",
|
"Field {{field}} is not defined": "Feld {{field}} fehlt",
|
||||||
"Field {{field}} has wrong type. It should be from type {{type}}": "Feld {{field}} hat den falschen Type. Es sollte vom Typ {{type}} sein",
|
"Field {{field}} has wrong type. It should be from type {{type}}": "Feld {{field}} hat den falschen Typ. Es sollte vom Typ {{type}} sein",
|
||||||
"Client has no permission for acces password auth": "Dieser Client hat keine Berechtigung password auth zu benutzen",
|
"Client has no permission for acces password auth": "Dieser Client hat keine Berechtigung password auth zu benutzen",
|
||||||
"Invalid token": "Ungültiges Token",
|
"Invalid token": "Ungültiger Token",
|
||||||
"By clicking on ALLOW, you allow this app to access the requested recources.": "Wenn sie ALLOW drücken, berechtigen sie die Applikation die beantragten Resourcen zu benutzen.",
|
"By clicking on ALLOW, you allow this app to access the requested recources.": "Wenn sie ALLOW drücken, berechtigen sie die Applikation die beantragten Resourcen zu benutzen.",
|
||||||
"User": "User"
|
"User": "User"
|
||||||
}
|
}
|
369
package-lock.json
generated
369
package-lock.json
generated
@ -385,6 +385,78 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"apidoc": {
|
||||||
|
"version": "0.17.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/apidoc/-/apidoc-0.17.7.tgz",
|
||||||
|
"integrity": "sha512-9Wf4bRPwCuWOIOxR42dDnsXnFw+rhJg5VrMQK+KmNxJwyIh30UqX6gvjjXSG6YO74MqE87F18bbQXUENK9dPGg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"apidoc-core": "~0.8.2",
|
||||||
|
"commander": "^2.19.0",
|
||||||
|
"fs-extra": "^7.0.0",
|
||||||
|
"lodash": "^4.17.10",
|
||||||
|
"markdown-it": "^8.3.1",
|
||||||
|
"winston": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"commander": {
|
||||||
|
"version": "2.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
|
||||||
|
"integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"apidoc-core": {
|
||||||
|
"version": "0.8.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/apidoc-core/-/apidoc-core-0.8.3.tgz",
|
||||||
|
"integrity": "sha1-2dY1RYKd8lDSzKBJaDqH53U2S5Y=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fs-extra": "^3.0.1",
|
||||||
|
"glob": "^7.1.1",
|
||||||
|
"iconv-lite": "^0.4.17",
|
||||||
|
"klaw-sync": "^2.1.0",
|
||||||
|
"lodash": "~4.17.4",
|
||||||
|
"semver": "~5.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"fs-extra": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.2",
|
||||||
|
"jsonfile": "^3.0.0",
|
||||||
|
"universalify": "^0.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
||||||
|
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"argparse": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"sprintf-js": "~1.0.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"sprintf-js": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"arr-diff": {
|
"arr-diff": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
|
||||||
@ -794,6 +866,16 @@
|
|||||||
"object-visit": "^1.0.0"
|
"object-visit": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"color": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "^1.9.1",
|
||||||
|
"color-string": "^1.5.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"color-convert": {
|
"color-convert": {
|
||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
@ -809,6 +891,38 @@
|
|||||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"color-string": {
|
||||||
|
"version": "1.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
|
||||||
|
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-name": "^1.0.0",
|
||||||
|
"simple-swizzle": "^0.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"colornames": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"colors": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"colorspace": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-pI3btWyiuz7Ken0BWh9Elzsmv2bM9AhA7psXib4anUXy/orfZ/E0MbQwhSOG/9L8hLlalqrU0UhOuqxW1YjmVw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color": "3.0.x",
|
||||||
|
"text-hex": "1.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"commander": {
|
"commander": {
|
||||||
"version": "2.17.1",
|
"version": "2.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
|
||||||
@ -1052,6 +1166,17 @@
|
|||||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||||
},
|
},
|
||||||
|
"diagnostics": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"colorspace": "1.1.x",
|
||||||
|
"enabled": "1.0.x",
|
||||||
|
"kuler": "1.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dijkstrajs": {
|
"dijkstrajs": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
|
||||||
@ -1103,6 +1228,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||||
},
|
},
|
||||||
|
"enabled": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"env-variable": "0.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"encodeurl": {
|
"encodeurl": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
@ -1156,6 +1290,18 @@
|
|||||||
"has-binary2": "~1.0.2"
|
"has-binary2": "~1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"entities": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"env-variable": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz",
|
||||||
|
"integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"errlop": {
|
"errlop": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/errlop/-/errlop-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/errlop/-/errlop-1.0.3.tgz",
|
||||||
@ -1410,6 +1556,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fast-safe-stringify": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"fecha": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||||
@ -1480,6 +1638,34 @@
|
|||||||
"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="
|
||||||
},
|
},
|
||||||
|
"fs-extra": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.2",
|
||||||
|
"jsonfile": "^4.0.0",
|
||||||
|
"universalify": "^0.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"jsonfile": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||||
|
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"fsevents": {
|
"fsevents": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz",
|
||||||
@ -2047,6 +2233,20 @@
|
|||||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"glob": {
|
||||||
|
"version": "7.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||||
|
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
|
"inflight": "^1.0.4",
|
||||||
|
"inherits": "2",
|
||||||
|
"minimatch": "^3.0.4",
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"path-is-absolute": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"glob-parent": {
|
"glob-parent": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
|
||||||
@ -2522,6 +2722,15 @@
|
|||||||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
|
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"jsonfile": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"jsonwebtoken": {
|
"jsonwebtoken": {
|
||||||
"version": "8.5.0",
|
"version": "8.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz",
|
||||||
@ -2576,6 +2785,24 @@
|
|||||||
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"klaw-sync": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-2.1.0.tgz",
|
||||||
|
"integrity": "sha1-PTvNhgDnv971MjHHOf8FOu1WDkQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"kuler": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"colornames": "^1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"latest-version": {
|
"latest-version": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
|
||||||
@ -2593,6 +2820,15 @@
|
|||||||
"invert-kv": "^2.0.0"
|
"invert-kv": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"linkify-it": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"uc.micro": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"locate-path": {
|
"locate-path": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||||
@ -2642,6 +2878,27 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||||
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
|
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
|
||||||
},
|
},
|
||||||
|
"logform": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"colors": "^1.2.1",
|
||||||
|
"fast-safe-stringify": "^2.0.4",
|
||||||
|
"fecha": "^2.3.3",
|
||||||
|
"ms": "^2.1.1",
|
||||||
|
"triple-beam": "^1.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"lowercase-keys": {
|
"lowercase-keys": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
|
||||||
@ -2698,6 +2955,19 @@
|
|||||||
"object-visit": "^1.0.0"
|
"object-visit": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"markdown-it": {
|
||||||
|
"version": "8.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
|
||||||
|
"integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^1.0.7",
|
||||||
|
"entities": "~1.1.1",
|
||||||
|
"linkify-it": "^2.0.0",
|
||||||
|
"mdurl": "^1.0.1",
|
||||||
|
"uc.micro": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"math-interval-parser": {
|
"math-interval-parser": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-1.1.0.tgz",
|
||||||
@ -2706,6 +2976,12 @@
|
|||||||
"xregexp": "^2.0.0"
|
"xregexp": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mdurl": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
@ -3104,6 +3380,12 @@
|
|||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"one-time": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
|
||||||
|
"integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"optimist": {
|
"optimist": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
|
||||||
@ -3634,6 +3916,23 @@
|
|||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
||||||
},
|
},
|
||||||
|
"simple-swizzle": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||||
|
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-arrayish": "^0.3.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"is-arrayish": {
|
||||||
|
"version": "0.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||||
|
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"snapdragon": {
|
"snapdragon": {
|
||||||
"version": "0.8.2",
|
"version": "0.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||||
@ -3896,6 +4195,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz",
|
||||||
"integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw="
|
"integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw="
|
||||||
},
|
},
|
||||||
|
"stack-trace": {
|
||||||
|
"version": "0.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||||
|
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"static-extend": {
|
"static-extend": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
|
||||||
@ -4028,6 +4333,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"text-hex": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"timed-out": {
|
"timed-out": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
|
||||||
@ -4096,6 +4407,12 @@
|
|||||||
"integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==",
|
"integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"triple-beam": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
|
||||||
@ -4127,6 +4444,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/u2f/-/u2f-0.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/u2f/-/u2f-0.1.3.tgz",
|
||||||
"integrity": "sha512-/IaxeBqjo5o3D7plPkxdApbCpgGoI2bmTomS1kq5OjVflaE9UBJ0WfqoXqZryZKfFYBjQC7Tn1hA57WtRgh/Sg=="
|
"integrity": "sha512-/IaxeBqjo5o3D7plPkxdApbCpgGoI2bmTomS1kq5OjVflaE9UBJ0WfqoXqZryZKfFYBjQC7Tn1hA57WtRgh/Sg=="
|
||||||
},
|
},
|
||||||
|
"uc.micro": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
"version": "3.4.9",
|
"version": "3.4.9",
|
||||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
|
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
|
||||||
@ -4195,6 +4518,12 @@
|
|||||||
"crypto-random-string": "^1.0.0"
|
"crypto-random-string": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"universalify": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"unpipe": {
|
"unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
@ -4364,6 +4693,46 @@
|
|||||||
"resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz",
|
||||||
"integrity": "sha1-2+RboqKRqrxW1iz2bEW3+jIpRt4="
|
"integrity": "sha1-2+RboqKRqrxW1iz2bEW3+jIpRt4="
|
||||||
},
|
},
|
||||||
|
"winston": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"async": "^2.6.1",
|
||||||
|
"diagnostics": "^1.1.1",
|
||||||
|
"is-stream": "^1.1.0",
|
||||||
|
"logform": "^2.1.1",
|
||||||
|
"one-time": "0.0.4",
|
||||||
|
"readable-stream": "^3.1.1",
|
||||||
|
"stack-trace": "0.0.x",
|
||||||
|
"triple-beam": "^1.3.0",
|
||||||
|
"winston-transport": "^4.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-RV20kLjdmpZuTF1INEb9IA3L68Nmi+Ri7ppZqo78wj//Pn62fCoJyV9zalccNzDD/OuJpMG4f+pfMl8+L6QdGw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"string_decoder": "^1.1.1",
|
||||||
|
"util-deprecate": "^1.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"winston-transport": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"readable-stream": "^2.3.6",
|
||||||
|
"triple-beam": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"wordwrap": {
|
"wordwrap": {
|
||||||
"version": "0.0.3",
|
"version": "0.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node lib/index.js",
|
"start": "node lib/index.js",
|
||||||
|
"build-doc": "apidoc -i src/ -p apidoc/",
|
||||||
|
"build-ts": "tsc",
|
||||||
"build": "tsc && cd views && npm run build && cd ..",
|
"build": "tsc && cd views && npm run build && cd ..",
|
||||||
"watch-ts": "tsc -w",
|
"watch-ts": "tsc -w",
|
||||||
"watch-views": "cd views && npm run watch",
|
"watch-views": "cd views && npm run watch",
|
||||||
@ -27,6 +29,7 @@
|
|||||||
"@types/qrcode": "^1.3.1",
|
"@types/qrcode": "^1.3.1",
|
||||||
"@types/speakeasy": "^2.0.4",
|
"@types/speakeasy": "^2.0.4",
|
||||||
"@types/uuid": "^3.4.4",
|
"@types/uuid": "^3.4.4",
|
||||||
|
"apidoc": "^0.17.7",
|
||||||
"concurrently": "^4.1.0",
|
"concurrently": "^4.1.0",
|
||||||
"nodemon": "^1.18.10",
|
"nodemon": "^1.18.10",
|
||||||
"typescript": "^3.3.3333"
|
"typescript": "^3.3.3333"
|
||||||
|
@ -1,29 +1,60 @@
|
|||||||
import { Router, Request } from "express";
|
import { Router, Request } from "express";
|
||||||
import { GetUserMiddleware } from "../middlewares/user";
|
|
||||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||||
import promiseMiddleware from "../../helper/promiseMiddleware";
|
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||||||
import Client from "../../models/client";
|
import Client from "../../models/client";
|
||||||
import User from "../../models/user";
|
|
||||||
import verify, { Types } from "../middlewares/verify";
|
import verify, { Types } from "../middlewares/verify";
|
||||||
import { randomBytes } from "crypto";
|
import { randomBytes } from "crypto";
|
||||||
|
|
||||||
|
|
||||||
const ClientRouter: Router = Router();
|
const ClientRouter: Router = Router();
|
||||||
ClientRouter.use(GetUserMiddleware(true, true), (req: Request, res, next) => {
|
|
||||||
if (!req.isAdmin) res.sendStatus(HttpStatusCode.FORBIDDEN)
|
|
||||||
else next()
|
|
||||||
});
|
|
||||||
ClientRouter.route("/")
|
ClientRouter.route("/")
|
||||||
|
/**
|
||||||
|
* @api {get} /admin/client
|
||||||
|
* @apiName AdminGetClients
|
||||||
|
*
|
||||||
|
* @apiGroup admin_client
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object[]} clients
|
||||||
|
* @apiSuccess {String} clients._id The internally used id
|
||||||
|
* @apiSuccess {String} clients.maintainer
|
||||||
|
* @apiSuccess {Boolean} clients.internal
|
||||||
|
* @apiSuccess {String} clients.name
|
||||||
|
* @apiSuccess {String} clients.redirect_url
|
||||||
|
* @apiSuccess {String} clients.website
|
||||||
|
* @apiSuccess {String} clients.logo
|
||||||
|
* @apiSuccess {String} clients.client_id Client ID used outside of DB
|
||||||
|
* @apiSuccess {String} clients.client_secret
|
||||||
|
*/
|
||||||
.get(promiseMiddleware(async (req, res) => {
|
.get(promiseMiddleware(async (req, res) => {
|
||||||
let clients = await Client.find({});
|
let clients = await Client.find({});
|
||||||
//ToDo check if user is required!
|
//ToDo check if user is required!
|
||||||
res.json(clients);
|
res.json(clients);
|
||||||
}))
|
}))
|
||||||
.delete(promiseMiddleware(async (req, res) => {
|
/**
|
||||||
let { id } = req.query;
|
* @api {get} /admin/client
|
||||||
await Client.delete(id);
|
* @apiName AdminAddClients
|
||||||
res.json({ success: true });
|
*
|
||||||
}))
|
* @apiGroup admin_client
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiParam {Boolean} internal Is it an internal app
|
||||||
|
* @apiParam {String} name
|
||||||
|
* @apiParam {String} redirect_url
|
||||||
|
* @apiParam {String} website
|
||||||
|
* @apiParam {String} logo
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object[]} clients
|
||||||
|
* @apiSuccess {String} clients._id The internally used id
|
||||||
|
* @apiSuccess {String} clients.maintainer
|
||||||
|
* @apiSuccess {Boolean} clients.internal
|
||||||
|
* @apiSuccess {String} clients.name
|
||||||
|
* @apiSuccess {String} clients.redirect_url
|
||||||
|
* @apiSuccess {String} clients.website
|
||||||
|
* @apiSuccess {String} clients.logo
|
||||||
|
* @apiSuccess {String} clients.client_id Client ID used outside of DB
|
||||||
|
* @apiSuccess {String} clients.client_secret
|
||||||
|
*/
|
||||||
.post(verify({
|
.post(verify({
|
||||||
internal: {
|
internal: {
|
||||||
type: Types.BOOLEAN,
|
type: Types.BOOLEAN,
|
||||||
@ -49,11 +80,48 @@ ClientRouter.route("/")
|
|||||||
await Client.save(client)
|
await Client.save(client)
|
||||||
res.json(client);
|
res.json(client);
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
ClientRouter.route("/:id")
|
||||||
|
/**
|
||||||
|
* @api {delete} /admin/client/:id
|
||||||
|
* @apiParam {String} id Client _id
|
||||||
|
* @apiName AdminDeleteClient
|
||||||
|
*
|
||||||
|
* @apiGroup admin_client
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {Boolean} success
|
||||||
|
*/
|
||||||
|
.delete(promiseMiddleware(async (req, res) => {
|
||||||
|
let { id } = req.params;
|
||||||
|
await Client.delete(id);
|
||||||
|
res.json({ success: true });
|
||||||
|
}))
|
||||||
|
/**
|
||||||
|
* @api {put} /admin/client/:id
|
||||||
|
* @apiParam {String} id Client _id
|
||||||
|
* @apiName AdminUpdateClient
|
||||||
|
*
|
||||||
|
* @apiGroup admin_client
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiParam {Boolean} internal Is it an internal app
|
||||||
|
* @apiParam {String} name
|
||||||
|
* @apiParam {String} redirect_url
|
||||||
|
* @apiParam {String} website
|
||||||
|
* @apiParam {String} logo
|
||||||
|
*
|
||||||
|
* @apiSuccess {String} _id The internally used id
|
||||||
|
* @apiSuccess {String} maintainer UserID of client maintainer
|
||||||
|
* @apiSuccess {Boolean} internal Defines if it is a internal client
|
||||||
|
* @apiSuccess {String} name The name of the Client
|
||||||
|
* @apiSuccess {String} redirect_url Redirect URL after login
|
||||||
|
* @apiSuccess {String} website Website of Client
|
||||||
|
* @apiSuccess {String} logo The Logo of the Client (optional)
|
||||||
|
* @apiSuccess {String} client_id Client ID used outside of DB
|
||||||
|
* @apiSuccess {String} client_secret The client secret, that can be used to obtain token
|
||||||
|
*/
|
||||||
.put(verify({
|
.put(verify({
|
||||||
id: {
|
|
||||||
type: Types.STRING,
|
|
||||||
query: true
|
|
||||||
},
|
|
||||||
internal: {
|
internal: {
|
||||||
type: Types.BOOLEAN,
|
type: Types.BOOLEAN,
|
||||||
optional: true
|
optional: true
|
||||||
@ -85,4 +153,5 @@ ClientRouter.route("/")
|
|||||||
res.json(client);
|
res.json(client);
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
||||||
export default ClientRouter;
|
export default ClientRouter;
|
@ -3,8 +3,16 @@ import ClientRoute from "./client";
|
|||||||
import UserRoute from "./user";
|
import UserRoute from "./user";
|
||||||
import RegCodeRoute from "./regcode";
|
import RegCodeRoute from "./regcode";
|
||||||
import PermissionRoute from "./permission";
|
import PermissionRoute from "./permission";
|
||||||
|
import { GetUserMiddleware } from "../middlewares/user";
|
||||||
|
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||||
|
|
||||||
const AdminRoute: Router = Router();
|
const AdminRoute: Router = Router();
|
||||||
|
|
||||||
|
AdminRoute.use(GetUserMiddleware(true, true), (req: Request, res, next) => {
|
||||||
|
if (!req.isAdmin) throw new RequestError("You have no permission to access this API", HttpStatusCode.FORBIDDEN);
|
||||||
|
else next()
|
||||||
|
});
|
||||||
|
|
||||||
AdminRoute.use("/client", ClientRoute);
|
AdminRoute.use("/client", ClientRoute);
|
||||||
AdminRoute.use("/regcode", RegCodeRoute)
|
AdminRoute.use("/regcode", RegCodeRoute)
|
||||||
AdminRoute.use("/user", UserRoute)
|
AdminRoute.use("/user", UserRoute)
|
||||||
|
@ -8,13 +8,22 @@ import Client from "../../models/client";
|
|||||||
import { ObjectID } from "bson";
|
import { ObjectID } from "bson";
|
||||||
|
|
||||||
const PermissionRoute: Router = Router();
|
const PermissionRoute: Router = Router();
|
||||||
PermissionRoute.use(GetUserMiddleware(true, true), (req: Request, res, next) => {
|
|
||||||
if (!req.isAdmin) res.sendStatus(HttpStatusCode.FORBIDDEN)
|
|
||||||
else next()
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
PermissionRoute.route("/")
|
PermissionRoute.route("/")
|
||||||
|
/**
|
||||||
|
* @api {get} /admin/permission
|
||||||
|
* @apiName AdminGetPermissions
|
||||||
|
*
|
||||||
|
* @apiParam client Optionally filter by client _id
|
||||||
|
*
|
||||||
|
* @apiGroup admin_permission
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object[]} permissions
|
||||||
|
* @apiSuccess {String} permissions._id The ID
|
||||||
|
* @apiSuccess {String} permissions.name Permission name
|
||||||
|
* @apiSuccess {String} permissions.description A description, that makes it clear to the user, what this Permission allows to do
|
||||||
|
* @apiSuccess {String} permissions.client The ID of the owning client
|
||||||
|
*/
|
||||||
.get(promiseMiddleware(async (req, res) => {
|
.get(promiseMiddleware(async (req, res) => {
|
||||||
let query = {};
|
let query = {};
|
||||||
if (req.query.client) {
|
if (req.query.client) {
|
||||||
@ -23,6 +32,23 @@ PermissionRoute.route("/")
|
|||||||
let permission = await Permission.find(query);
|
let permission = await Permission.find(query);
|
||||||
res.json(permission);
|
res.json(permission);
|
||||||
}))
|
}))
|
||||||
|
/**
|
||||||
|
* @api {post} /admin/permission
|
||||||
|
* @apiName AdminAddPermission
|
||||||
|
*
|
||||||
|
* @apiParam client The ID of the owning client
|
||||||
|
* @apiParam name Permission name
|
||||||
|
* @apiParam description A description, that makes it clear to the user, what this Permission allows to do
|
||||||
|
*
|
||||||
|
* @apiGroup admin_permission
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object[]} permissions
|
||||||
|
* @apiSuccess {String} permissions._id The ID
|
||||||
|
* @apiSuccess {String} permissions.name Permission name
|
||||||
|
* @apiSuccess {String} permissions.description A description, that makes it clear to the user, what this Permission allows to do
|
||||||
|
* @apiSuccess {String} permissions.client The ID of the owning client
|
||||||
|
*/
|
||||||
.post(verify({
|
.post(verify({
|
||||||
client: {
|
client: {
|
||||||
type: Types.STRING
|
type: Types.STRING
|
||||||
@ -45,7 +71,19 @@ PermissionRoute.route("/")
|
|||||||
});
|
});
|
||||||
await Permission.save(permission);
|
await Permission.save(permission);
|
||||||
res.json(permission);
|
res.json(permission);
|
||||||
})).delete(promiseMiddleware(async (req, res) => {
|
}))
|
||||||
|
/**
|
||||||
|
* @api {delete} /admin/permission
|
||||||
|
* @apiName AdminDeletePermission
|
||||||
|
*
|
||||||
|
* @apiParam id The permission ID
|
||||||
|
*
|
||||||
|
* @apiGroup admin_permission
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {Boolean} success
|
||||||
|
*/
|
||||||
|
.delete(promiseMiddleware(async (req, res) => {
|
||||||
let { id } = req.query;
|
let { id } = req.query;
|
||||||
await Permission.delete(id);
|
await Permission.delete(id);
|
||||||
res.json({ success: true });
|
res.json({ success: true });
|
||||||
|
@ -7,20 +7,49 @@ import { GetUserMiddleware } from "../middlewares/user";
|
|||||||
import { HttpStatusCode } from "../../helper/request_error";
|
import { HttpStatusCode } from "../../helper/request_error";
|
||||||
|
|
||||||
const RegCodeRoute: Router = Router();
|
const RegCodeRoute: Router = Router();
|
||||||
RegCodeRoute.use(GetUserMiddleware(true, true), (req: Request, res, next) => {
|
|
||||||
if (!req.isAdmin) res.sendStatus(HttpStatusCode.FORBIDDEN)
|
|
||||||
else next()
|
|
||||||
});
|
|
||||||
RegCodeRoute.route("/")
|
RegCodeRoute.route("/")
|
||||||
|
/**
|
||||||
|
* @api {get} /admin/regcode
|
||||||
|
* @apiName AdminGetRegcodes
|
||||||
|
*
|
||||||
|
* @apiGroup admin_regcode
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object[]} regcodes
|
||||||
|
* @apiSuccess {String} permissions._id The ID
|
||||||
|
* @apiSuccess {String} permissions.token The Regcode Token
|
||||||
|
* @apiSuccess {String} permissions.valid Defines if the Regcode is valid
|
||||||
|
* @apiSuccess {String} permissions.validTill Expiration date of RegCode
|
||||||
|
*/
|
||||||
.get(promiseMiddleware(async (req, res) => {
|
.get(promiseMiddleware(async (req, res) => {
|
||||||
let regcodes = await RegCode.find({});
|
let regcodes = await RegCode.find({});
|
||||||
res.json(regcodes);
|
res.json(regcodes);
|
||||||
}))
|
}))
|
||||||
|
/**
|
||||||
|
* @api {delete} /admin/regcode
|
||||||
|
* @apiName AdminDeleteRegcode
|
||||||
|
*
|
||||||
|
* @apiParam {String} id The id of the RegCode
|
||||||
|
*
|
||||||
|
* @apiGroup admin_regcode
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {Boolean} success
|
||||||
|
*/
|
||||||
.delete(promiseMiddleware(async (req, res) => {
|
.delete(promiseMiddleware(async (req, res) => {
|
||||||
let { id } = req.query;
|
let { id } = req.query;
|
||||||
await RegCode.delete(id);
|
await RegCode.delete(id);
|
||||||
res.json({ success: true });
|
res.json({ success: true });
|
||||||
}))
|
}))
|
||||||
|
/**
|
||||||
|
* @api {post} /admin/regcode
|
||||||
|
* @apiName AdminAddRegcode
|
||||||
|
*
|
||||||
|
* @apiGroup admin_regcode
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {String} code The newly created code
|
||||||
|
*/
|
||||||
.post(promiseMiddleware(async (req, res) => {
|
.post(promiseMiddleware(async (req, res) => {
|
||||||
let regcode = RegCode.new({
|
let regcode = RegCode.new({
|
||||||
token: randomBytes(10).toString("hex"),
|
token: randomBytes(10).toString("hex"),
|
||||||
|
@ -14,10 +14,37 @@ UserRoute.use(GetUserMiddleware(true, true), (req: Request, res, next) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
UserRoute.route("/")
|
UserRoute.route("/")
|
||||||
|
/**
|
||||||
|
* @api {get} /admin/user
|
||||||
|
* @apiName AdminGetUsers
|
||||||
|
*
|
||||||
|
* @apiGroup admin_user
|
||||||
|
* @apiPermission admin
|
||||||
|
* @apiSuccess {Object[]} user
|
||||||
|
* @apiSuccess {String} user._id The internal id of the user
|
||||||
|
* @apiSuccess {String} user.uid The public UID of the user
|
||||||
|
* @apiSuccess {String} user.username The username
|
||||||
|
* @apiSuccess {String} user.name The real name
|
||||||
|
* @apiSuccess {Date} user.birthday The birthday
|
||||||
|
* @apiSuccess {Number} user.gender 0 = none, 1 = male, 2 = female, 3 = other
|
||||||
|
* @apiSuccess {Boolean} user.admin Is admin or not
|
||||||
|
*/
|
||||||
.get(promiseMiddleware(async (req, res) => {
|
.get(promiseMiddleware(async (req, res) => {
|
||||||
let users = await User.find({});
|
let users = await User.find({});
|
||||||
|
users.forEach(e => delete e.password && delete e.salt && delete e.encryption_key);
|
||||||
res.json(users);
|
res.json(users);
|
||||||
}))
|
}))
|
||||||
|
/**
|
||||||
|
* @api {delete} /admin/user
|
||||||
|
* @apiName AdminDeleteUser
|
||||||
|
*
|
||||||
|
* @apiParam {String} id The User ID
|
||||||
|
*
|
||||||
|
* @apiGroup admin_user
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {Boolean} success
|
||||||
|
*/
|
||||||
.delete(promiseMiddleware(async (req, res) => {
|
.delete(promiseMiddleware(async (req, res) => {
|
||||||
let { id } = req.query;
|
let { id } = req.query;
|
||||||
let user = await User.findById(id);
|
let user = await User.findById(id);
|
||||||
@ -32,7 +59,23 @@ UserRoute.route("/")
|
|||||||
|
|
||||||
await User.delete(user);
|
await User.delete(user);
|
||||||
res.json({ success: true });
|
res.json({ success: true });
|
||||||
})).put(promiseMiddleware(async (req, res) => {
|
}))
|
||||||
|
/**
|
||||||
|
* @api {put} /admin/user
|
||||||
|
* @apiName AdminChangeUser
|
||||||
|
*
|
||||||
|
* @apiParam {String} id The User ID
|
||||||
|
*
|
||||||
|
* @apiGroup admin_user
|
||||||
|
* @apiPermission admin
|
||||||
|
*
|
||||||
|
* @apiSuccess {Boolean} success
|
||||||
|
*
|
||||||
|
* @apiDescription Flipps the user role:
|
||||||
|
* admin -> user
|
||||||
|
* user -> admin
|
||||||
|
*/
|
||||||
|
.put(promiseMiddleware(async (req, res) => {
|
||||||
let { id } = req.query;
|
let { id } = req.query;
|
||||||
let user = await User.findById(id);
|
let user = await User.findById(id);
|
||||||
user.admin = !user.admin;
|
user.admin = !user.admin;
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
import { Request, Response, Router } from "express"
|
||||||
|
import Stacker from "../middlewares/stacker";
|
||||||
|
import { GetClientAuthMiddleware } from "../middlewares/client";
|
||||||
|
import { GetUserMiddleware } from "../middlewares/user";
|
||||||
|
import { createJWT } from "../../keys";
|
||||||
|
|
||||||
|
|
||||||
|
const ClientRouter = Router();
|
||||||
|
/**
|
||||||
|
* @api {get} /client/user
|
||||||
|
* @apiName ClientUser
|
||||||
|
*
|
||||||
|
* @apiGroup client
|
||||||
|
* @apiPermission user_client Requires ClientID and Authenticated User
|
||||||
|
*
|
||||||
|
* @apiParam {String} redirect_uri URL to redirect to on success
|
||||||
|
*/
|
||||||
|
ClientRouter.get("/user", Stacker(GetClientAuthMiddleware(false), GetUserMiddleware(true, false), async (req: Request, res: Response) => {
|
||||||
|
let jwt = await createJWT({
|
||||||
|
client: req.client.client_id,
|
||||||
|
uid: req.user.uid,
|
||||||
|
username: req.user.username
|
||||||
|
}, 30); //after 30 seconds this token is invalid
|
||||||
|
res.redirect(req.query.redirect_uri + "?jwt=" + jwt)
|
||||||
|
}));
|
||||||
|
|
||||||
|
export default ClientRouter;
|
@ -1,14 +0,0 @@
|
|||||||
import { Request, Response } from "express"
|
|
||||||
import Stacker from "../middlewares/stacker";
|
|
||||||
import { GetClientAuthMiddleware } from "../middlewares/client";
|
|
||||||
import { GetUserMiddleware } from "../middlewares/user";
|
|
||||||
import { createJWT } from "../../keys";
|
|
||||||
|
|
||||||
export const AuthGetUser = Stacker(GetClientAuthMiddleware(false), GetUserMiddleware(true, false), async (req: Request, res: Response) => {
|
|
||||||
let jwt = await createJWT({
|
|
||||||
client: req.client.client_id,
|
|
||||||
uid: req.user.uid,
|
|
||||||
username: req.user.username
|
|
||||||
}, 30); //after 30 seconds this token is invalid
|
|
||||||
res.redirect(req.query.redirect_uri + "?jwt=" + jwt)
|
|
||||||
});
|
|
@ -3,7 +3,7 @@ import AdminRoute from "./admin";
|
|||||||
import UserRoute from "./user";
|
import UserRoute from "./user";
|
||||||
import InternalRoute from "./internal";
|
import InternalRoute from "./internal";
|
||||||
import Login from "./user/login";
|
import Login from "./user/login";
|
||||||
import { AuthGetUser } from "./client/user";
|
import ClientRouter from "./client";
|
||||||
import * as cors from "cors";
|
import * as cors from "cors";
|
||||||
import OAuthRoute from "./oauth";
|
import OAuthRoute from "./oauth";
|
||||||
|
|
||||||
@ -14,10 +14,10 @@ ApiRouter.use("/user", UserRoute);
|
|||||||
ApiRouter.use("/internal", InternalRoute);
|
ApiRouter.use("/internal", InternalRoute);
|
||||||
ApiRouter.use("/oauth", OAuthRoute);
|
ApiRouter.use("/oauth", OAuthRoute);
|
||||||
|
|
||||||
ApiRouter.use("/client/user", AuthGetUser);
|
ApiRouter.use("/client", ClientRouter);
|
||||||
|
|
||||||
// Legacy reasons (deprecated)
|
// Legacy reasons (deprecated)
|
||||||
ApiRouter.use("/user", AuthGetUser);
|
ApiRouter.use("/", ClientRouter);
|
||||||
|
|
||||||
// Legacy reasons (deprecated)
|
// Legacy reasons (deprecated)
|
||||||
ApiRouter.post("/login", Login);
|
ApiRouter.post("/login", Login);
|
||||||
|
@ -3,6 +3,28 @@ import { OAuthInternalApp } from "./oauth";
|
|||||||
import PasswordAuth from "./password";
|
import PasswordAuth from "./password";
|
||||||
|
|
||||||
const InternalRoute: Router = Router();
|
const InternalRoute: Router = Router();
|
||||||
|
/**
|
||||||
|
* @api {get} /internal/oauth
|
||||||
|
* @apiName ClientInteralOAuth
|
||||||
|
*
|
||||||
|
* @apiGroup client_internal
|
||||||
|
* @apiPermission client_internal Only ClientID
|
||||||
|
*
|
||||||
|
* @apiParam {String} redirect_uri Redirect URI called after success
|
||||||
|
* @apiParam {String} state State will be set in RedirectURI for the client to check
|
||||||
|
*/
|
||||||
InternalRoute.get("/oauth", OAuthInternalApp);
|
InternalRoute.get("/oauth", OAuthInternalApp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} /internal/password
|
||||||
|
* @apiName ClientInteralPassword
|
||||||
|
*
|
||||||
|
* @apiGroup client_internal
|
||||||
|
* @apiPermission client_internal Requires ClientID and Secret
|
||||||
|
*
|
||||||
|
* @apiParam {String} username Username (either username or UID)
|
||||||
|
* @apiParam {String} uid User ID (either username or UID)
|
||||||
|
* @apiParam {String} password Hashed and Salted according to specification
|
||||||
|
*/
|
||||||
InternalRoute.post("/password", PasswordAuth)
|
InternalRoute.post("/password", PasswordAuth)
|
||||||
export default InternalRoute;
|
export default InternalRoute;
|
@ -5,9 +5,59 @@ import Public from "./public";
|
|||||||
import RefreshTokenRoute from "./refresh";
|
import RefreshTokenRoute from "./refresh";
|
||||||
|
|
||||||
const OAuthRoue: Router = Router();
|
const OAuthRoue: Router = Router();
|
||||||
|
/**
|
||||||
|
* @api {post} /oauth/auth
|
||||||
|
* @apiName OAuthAuth
|
||||||
|
*
|
||||||
|
* @apiGroup oauth
|
||||||
|
* @apiPermission user Special required
|
||||||
|
*
|
||||||
|
* @apiParam {String} response_type must be "code" others are not supported
|
||||||
|
* @apiParam {String} client_id ClientID
|
||||||
|
* @apiParam {String} redirect_uri The URI to redirect with code
|
||||||
|
* @apiParam {String} scope Scope that contains the requested permissions (comma seperated list of permissions)
|
||||||
|
* @apiParam {String} state State, that will be passed to redirect_uri for client
|
||||||
|
* @apiParam {String} nored Deactivates the Redirect response from server and instead returns the redirect URI in JSON response
|
||||||
|
*/
|
||||||
OAuthRoue.post("/auth", AuthRoute);
|
OAuthRoue.post("/auth", AuthRoute);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} /oauth/jwt
|
||||||
|
* @apiName OAuthJwt
|
||||||
|
*
|
||||||
|
* @apiGroup oauth
|
||||||
|
* @apiPermission none
|
||||||
|
*
|
||||||
|
* @apiParam {String} refreshtoken
|
||||||
|
*
|
||||||
|
* @apiSuccess {String} token The JWT that allowes the application to access the recources granted for refresh token
|
||||||
|
*/
|
||||||
OAuthRoue.get("/jwt", JWTRoute)
|
OAuthRoue.get("/jwt", JWTRoute)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} /oauth/public
|
||||||
|
* @apiName OAuthPublic
|
||||||
|
*
|
||||||
|
* @apiGroup oauth
|
||||||
|
* @apiPermission none
|
||||||
|
*
|
||||||
|
* @apiSuccess {String} public_key The applications public_key. Used to verify JWT.
|
||||||
|
*/
|
||||||
OAuthRoue.get("/public", Public)
|
OAuthRoue.get("/public", Public)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} /oauth/refresh
|
||||||
|
* @apiName OAuthRefreshGet
|
||||||
|
*
|
||||||
|
* @apiGroup oauth
|
||||||
|
*/
|
||||||
OAuthRoue.get("/refresh", RefreshTokenRoute);
|
OAuthRoue.get("/refresh", RefreshTokenRoute);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} /oauth/refresh
|
||||||
|
* @apiName OAuthRefreshPost
|
||||||
|
*
|
||||||
|
* @apiGroup oauth
|
||||||
|
*/
|
||||||
OAuthRoue.post("/refresh", RefreshTokenRoute);
|
OAuthRoue.post("/refresh", RefreshTokenRoute);
|
||||||
export default OAuthRoue;
|
export default OAuthRoue;
|
@ -3,7 +3,6 @@ import promiseMiddleware from "../../helper/promiseMiddleware";
|
|||||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||||||
import RefreshToken from "../../models/refresh_token";
|
import RefreshToken from "../../models/refresh_token";
|
||||||
import User from "../../models/user";
|
import User from "../../models/user";
|
||||||
import Permission from "../../models/permissions";
|
|
||||||
import Client from "../../models/client";
|
import Client from "../../models/client";
|
||||||
import getOAuthJWT from "../../helper/jwt";
|
import getOAuthJWT from "../../helper/jwt";
|
||||||
|
|
||||||
@ -16,7 +15,9 @@ const JWTRoute = promiseMiddleware(async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
let user = await User.findById(token.user);
|
let user = await User.findById(token.user);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
//TODO handle error!
|
token.valid = false;
|
||||||
|
await RefreshToken.save(token);
|
||||||
|
throw new RequestError(req.__("Invalid token"), HttpStatusCode.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
let client = await Client.findById(token.client);
|
let client = await Client.findById(token.client);
|
||||||
|
@ -5,10 +5,91 @@ import TwoFactorRoute from "./twofactor";
|
|||||||
import { GetToken, DeleteToken } from "./token";
|
import { GetToken, DeleteToken } from "./token";
|
||||||
|
|
||||||
const UserRoute: Router = Router();
|
const UserRoute: Router = Router();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} /user/register
|
||||||
|
* @apiName UserRegister
|
||||||
|
*
|
||||||
|
* @apiGroup user
|
||||||
|
* @apiPermission none
|
||||||
|
*
|
||||||
|
* @apiParam {String} mail EMail linked to this Account
|
||||||
|
* @apiParam {String} username The new Username
|
||||||
|
* @apiParam {String} password Password hashed and salted like specification
|
||||||
|
* @apiParam {String} salt The Salt used for password hashing
|
||||||
|
* @apiParam {String} regcode The regcode, that should be used
|
||||||
|
* @apiParam {String} gender Gender can be: "male", "female", "other", "none"
|
||||||
|
* @apiParam {String} name The real name of the User
|
||||||
|
*
|
||||||
|
* @apiSuccess {Boolean} success
|
||||||
|
*
|
||||||
|
* @apiErrorExample {Object} Error-Response:
|
||||||
|
{
|
||||||
|
error: [
|
||||||
|
{
|
||||||
|
message: "Some Error",
|
||||||
|
field: "username"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status: 400
|
||||||
|
}
|
||||||
|
*/
|
||||||
UserRoute.post("/register", Register);
|
UserRoute.post("/register", Register);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} /user/login?type=:type
|
||||||
|
* @apiName UserLogin
|
||||||
|
*
|
||||||
|
* @apiParam {String} type Type could be either "username" or "password"
|
||||||
|
*
|
||||||
|
* @apiGroup user
|
||||||
|
* @apiPermission none
|
||||||
|
*
|
||||||
|
* @apiParam {String} username Username (either username or uid required)
|
||||||
|
* @apiParam {String} uid (either username or uid required)
|
||||||
|
* @apiParam {String} password Password hashed and salted like specification (only on type password)
|
||||||
|
*
|
||||||
|
* @apiSuccess {String} uid On type = "username"
|
||||||
|
* @apiSuccess {String} salt On type = "username"
|
||||||
|
*
|
||||||
|
* @apiSuccess {String} login On type = "password". Login Token
|
||||||
|
* @apiSuccess {String} special On type = "password". Special Token
|
||||||
|
* @apiSuccess {Object[]} tfa Will be set when TwoFactorAuthentication is required
|
||||||
|
* @apiSuccess {String} tfa.id The ID of the TFA Method
|
||||||
|
* @apiSuccess {String} tfa.name The name of the TFA Method
|
||||||
|
* @apiSuccess {String} tfa.type The type of the TFA Method
|
||||||
|
*/
|
||||||
UserRoute.post("/login", Login)
|
UserRoute.post("/login", Login)
|
||||||
UserRoute.use("/twofactor", TwoFactorRoute);
|
UserRoute.use("/twofactor", TwoFactorRoute);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} /user/token
|
||||||
|
* @apiName UserGetToken
|
||||||
|
*
|
||||||
|
* @apiGroup user
|
||||||
|
* @apiPermission user
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object[]} token
|
||||||
|
* @apiSuccess {String} token.id The Token ID
|
||||||
|
* @apiSuccess {String} token.special Identifies Special Token
|
||||||
|
* @apiSuccess {String} token.ip IP the token was optained from
|
||||||
|
* @apiSuccess {String} token.browser The Browser the token was optained from (User Agent)
|
||||||
|
* @apiSuccess {Boolean} token.isthis Shows if it is token used by this session
|
||||||
|
*/
|
||||||
UserRoute.get("/token", GetToken);
|
UserRoute.get("/token", GetToken);
|
||||||
UserRoute.delete("/token", DeleteToken);
|
|
||||||
|
/**
|
||||||
|
* @api {delete} /user/token/:id
|
||||||
|
* @apiParam {String} id The id of the token to be deleted
|
||||||
|
*
|
||||||
|
* @apiName UserDeleteToken
|
||||||
|
*
|
||||||
|
* @apiParam {String} type Type could be either "username" or "password"
|
||||||
|
*
|
||||||
|
* @apiGroup user
|
||||||
|
* @apiPermission user
|
||||||
|
*
|
||||||
|
* @apiSuccess {Boolean} success
|
||||||
|
*/
|
||||||
|
UserRoute.delete("/token/:id", DeleteToken);
|
||||||
export default UserRoute;
|
export default UserRoute;
|
@ -3,9 +3,7 @@ import User, { IUser } from "../../models/user";
|
|||||||
import { randomBytes } from "crypto";
|
import { randomBytes } from "crypto";
|
||||||
import moment = require("moment");
|
import moment = require("moment");
|
||||||
import LoginToken from "../../models/login_token";
|
import LoginToken from "../../models/login_token";
|
||||||
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
|
||||||
import promiseMiddleware from "../../helper/promiseMiddleware";
|
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||||||
import * as speakeasy from "speakeasy";
|
|
||||||
import TwoFactor from "../../models/twofactor";
|
import TwoFactor from "../../models/twofactor";
|
||||||
|
|
||||||
const Login = promiseMiddleware(async (req: Request, res: Response) => {
|
const Login = promiseMiddleware(async (req: Request, res: Response) => {
|
||||||
@ -19,8 +17,7 @@ const Login = promiseMiddleware(async (req: Request, res: Response) => {
|
|||||||
res.json({ salt: user.salt, uid: user.uid });
|
res.json({ salt: user.salt, uid: user.uid });
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
} else if (type === "password") {
|
||||||
|
|
||||||
const sendToken = async (user: IUser, tfa?: any[]) => {
|
const sendToken = async (user: IUser, tfa?: any[]) => {
|
||||||
let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress
|
let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress
|
||||||
let client = {
|
let client = {
|
||||||
@ -61,7 +58,8 @@ const Login = promiseMiddleware(async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === "password") {
|
|
||||||
|
|
||||||
let { username, password, uid } = req.body;
|
let { username, password, uid } = req.body;
|
||||||
|
|
||||||
let user = await User.findOne(username ? { username: username.toLowerCase() } : { uid: uid })
|
let user = await User.findOne(username ? { username: username.toLowerCase() } : { uid: uid })
|
||||||
|
@ -6,7 +6,6 @@ import TwoFactor from "../../../models/twofactor";
|
|||||||
import * as moment from "moment"
|
import * as moment from "moment"
|
||||||
import RequestError, { HttpStatusCode } from "../../../helper/request_error";
|
import RequestError, { HttpStatusCode } from "../../../helper/request_error";
|
||||||
|
|
||||||
|
|
||||||
const TwoFactorRouter = Router();
|
const TwoFactorRouter = Router();
|
||||||
|
|
||||||
TwoFactorRouter.get("/", Stacker(GetUserMiddleware(true, true), async (req, res) => {
|
TwoFactorRouter.get("/", Stacker(GetUserMiddleware(true, true), async (req, res) => {
|
||||||
|
@ -82,9 +82,10 @@ export default class Web {
|
|||||||
private registerErrorHandler() {
|
private registerErrorHandler() {
|
||||||
this.server.use((error, req: express.Request, res, next) => {
|
this.server.use((error, req: express.Request, res, next) => {
|
||||||
if (!(error instanceof RequestError)) {
|
if (!(error instanceof RequestError)) {
|
||||||
Logging.error(error);
|
error = new RequestError(error.message, error.status || HttpStatusCode.INTERNAL_SERVER_ERROR, error.nolog || false);
|
||||||
error = new RequestError(error.message, HttpStatusCode.INTERNAL_SERVER_ERROR);
|
}
|
||||||
} else if (error.status === 500 && !(<any>error).nolog) {
|
|
||||||
|
if (error.status === 500 && !(<any>error).nolog) {
|
||||||
Logging.error(error);
|
Logging.error(error);
|
||||||
} else {
|
} else {
|
||||||
Logging.log(typeof error.message === "string" ? error.message.split("\n", 1)[0] : error.message);
|
Logging.log(typeof error.message === "string" ? error.message.split("\n", 1)[0] : error.message);
|
||||||
|
@ -136,7 +136,7 @@ Handlebars.registerHelper("formatDate", function (datetime, format) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.deleteClient = (id) => {
|
window.deleteClient = (id) => {
|
||||||
request("/api/admin/client?id=" + id, "DELETE").then(() => loadList()).catch(catchError)
|
request("/api/admin/client/id=" + id, "DELETE").then(() => loadList()).catch(catchError)
|
||||||
}
|
}
|
||||||
|
|
||||||
window.createClientSubmit = (elm) => {
|
window.createClientSubmit = (elm) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user