|
@ -4,6 +4,7 @@
|
||||||
dist/
|
dist/
|
||||||
tmp/
|
tmp/
|
||||||
etc/
|
etc/
|
||||||
|
api/apib/documentation.apib
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
node_modules
|
node_modules
|
||||||
|
@ -46,7 +47,8 @@ Thumbs.db
|
||||||
# Internal Data
|
# Internal Data
|
||||||
public/
|
public/
|
||||||
mongodb-data/
|
mongodb-data/
|
||||||
resource/
|
api/resource/
|
||||||
|
api/apib/dredd/data/tmp-resource
|
||||||
backup/
|
backup/
|
||||||
|
|
||||||
# System
|
# System
|
||||||
|
|
|
@ -25,7 +25,7 @@ In addition, it sets up the mongo deamon to start up automatically with the syst
|
||||||
|
|
||||||
For production setup run the script, described in _Setup for development_, adding the parameter `prod`
|
For production setup run the script, described in _Setup for development_, adding the parameter `prod`
|
||||||
|
|
||||||
./docs/opt-cc-environment/3rd-party-install.sh prod
|
./docs/opt-cc-environment/3rd-party-install.sh prod
|
||||||
|
|
||||||
This adds the [`pm2` process manager](http://pm2.keymetrics.io/) to be installed and start the _opt-cc_ server as `pm2` process.
|
This adds the [`pm2` process manager](http://pm2.keymetrics.io/) to be installed and start the _opt-cc_ server as `pm2` process.
|
||||||
Run the `sudo` command printed as last output to configure the `pm2` process for automatic start on the system.
|
Run the `sudo` command printed as last output to configure the `pm2` process for automatic start on the system.
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
module.exports = {
|
||||||
|
'extends': 'google',
|
||||||
|
'parserOptions': {
|
||||||
|
'ecmaVersion': 6
|
||||||
|
},
|
||||||
|
'rules': {
|
||||||
|
'max-len': [2, 120, 4, {
|
||||||
|
'ignoreUrls': true
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,39 @@
|
||||||
|
### List App Users [GET /account]
|
||||||
|
|
||||||
|
List all app users, ordered by username
|
||||||
|
|
||||||
|
**Permission: 4**
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (array[AppUser], fixed-type)
|
||||||
|
|
||||||
|
|
||||||
|
### Update App User [PATCH /account/{id}]
|
||||||
|
|
||||||
|
Update an app user, identified by its id
|
||||||
|
|
||||||
|
**Permission: 4**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abf5064861d950f157c4a09` (string, required) - unique id of app user
|
||||||
|
|
||||||
|
+ Request (application/json)
|
||||||
|
|
||||||
|
+ Attributes (UpdateAppUser)
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (AppUser, fixed-type)
|
||||||
|
|
||||||
|
|
||||||
|
### Delete App User [DELETE /account/{id}]
|
||||||
|
|
||||||
|
**Permission: 4**
|
||||||
|
|
||||||
|
Delete an app user
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5ac0de67b5edc7771c027b94` (string, required) - unique id of app user
|
||||||
|
|
||||||
|
+ Response 204
|
|
@ -0,0 +1,16 @@
|
||||||
|
### Update signature image [POST /cmd/createSignature/{userId}]
|
||||||
|
|
||||||
|
Update an army members signature image
|
||||||
|
|
||||||
|
**Permission: 4**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ userId: `5ab68d42f547ed304064e5f7` (string, required) - army members unique user id
|
||||||
|
|
||||||
|
+ Request (application/json)
|
||||||
|
{}
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ status: `success` (string, required) - action result message
|
|
@ -0,0 +1,7 @@
|
||||||
|
### Get Army Overview [GET /overview]
|
||||||
|
|
||||||
|
Get bundled army, squad and member data for the participating fractions
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (array[Fraction])
|
|
@ -0,0 +1,60 @@
|
||||||
|
### Get Awardings [GET /awardings{?userId,inProgress,fractFilter}]
|
||||||
|
|
||||||
|
List all awardings
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ userId: `5ab68d42f547ed304064e5f7` (string, optional)
|
||||||
|
specific army member Id to show the awardings for
|
||||||
|
|
||||||
|
+ inProgress: false (boolean, optional)
|
||||||
|
true to filter by awarding state 'in progress'
|
||||||
|
|
||||||
|
+ Default: false
|
||||||
|
|
||||||
|
+ fractFilter: `BLUFOR` (enum[string], optional)
|
||||||
|
Field to filter by fraction
|
||||||
|
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `GLOBAL`
|
||||||
|
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (array[AwardingPopulated], fixed-type)
|
||||||
|
|
||||||
|
### Create Awarding [POST /awardings]
|
||||||
|
|
||||||
|
Create a new awarding which is immediatly assigned to the user
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Request (application/json)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ userId: `5ab68d42f547ed304064e5f7` (string, required) - unique id of the army member to give award
|
||||||
|
+ decorationId: `5abd3dff6e6a0334d95b8ba0` (string, required) - unique id of the decoration
|
||||||
|
+ reason: `Good boy` (string, required) - reason for giving the awarding
|
||||||
|
+ proposer: `5ab68ceef547ed304064e5f6` (string, required) - app user id, who requested this awarding
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Awarding, fixed-type)
|
||||||
|
|
||||||
|
### Create Awarding Proposal [POST /request/award]
|
||||||
|
|
||||||
|
Create a new awarding proposal, that needs to be approved by higher permission level user to take effect
|
||||||
|
|
||||||
|
**Permission: 1**
|
||||||
|
|
||||||
|
+ Request (application/json)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ userId: `5ab68d42f547ed304064e5f7` (string, required) - unique id of the army member to give award
|
||||||
|
+ decorationId: `5abd3dff6e6a0334d95b8ba0` (string, required) - unique id of the decoration
|
||||||
|
+ reason: `Good boy` (string, required) - reason for giving the awarding
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Awarding, fixed-type)
|
|
@ -0,0 +1,127 @@
|
||||||
|
### List Decorations [GET /decorations{?q,fractFilter}]
|
||||||
|
|
||||||
|
List all decorations
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ q: `tapferkeit` (string, optional)
|
||||||
|
Filter string for the partial decoration name
|
||||||
|
|
||||||
|
+ fractFilter: `BLUFOR` (enum[string], optional)
|
||||||
|
Field to filter by fraction
|
||||||
|
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `GLOBAL`
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (array[Decoration], fixed-type)
|
||||||
|
|
||||||
|
|
||||||
|
### Get Decoration [GET /decorations/{id}]
|
||||||
|
|
||||||
|
Retrieve single decoration data
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abd3dff6e6a0334d95b8ba0` (string, required) - unique id of the decoration to fetch
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Decoration, fixed-type)
|
||||||
|
|
||||||
|
### Create Decoration [POST /decorations]
|
||||||
|
|
||||||
|
Create a new decoration
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Request (multipart/form-data; boundary=---BOUNDARY)
|
||||||
|
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="name"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
Super medal 2000
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="fraction"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
OPFOR
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="description"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
For good performance in a battle
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="isMedal"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
true
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="image"; filename="image.png"
|
||||||
|
Content-Type: image/png
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlMA
|
||||||
|
QObYZgAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII=
|
||||||
|
-----BOUNDARY--
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Decoration, fixed-type)
|
||||||
|
|
||||||
|
### Update Decoration [PATCH /decorations/{id}]
|
||||||
|
|
||||||
|
Update decoration, identified by its id
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abeb420b987672bb1ede643` (string, required) - unique id of the decoration
|
||||||
|
|
||||||
|
+ Request (multipart/form-data; boundary=---BOUNDARY)
|
||||||
|
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="name"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
Super medal 2000
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="fraction"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
OPFOR
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="description"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
For good performance in a battle
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="sortingNumber"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
2
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="image"; filename="image.png"
|
||||||
|
Content-Type: image/png
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlMA
|
||||||
|
QObYZgAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII=
|
||||||
|
-----BOUNDARY--
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Decoration, fixed-type)
|
||||||
|
|
||||||
|
### Delete Decoration [DELETE /decorations/{id}]
|
||||||
|
|
||||||
|
Delete a decoration
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abeb43cb987672bb1ede644` (string, required) - unique id of the decoration
|
||||||
|
|
||||||
|
+ Response 204
|
|
@ -0,0 +1,65 @@
|
||||||
|
### List Promotions [GET /request/promotion{?squadId,inProgress,fractFilter}]
|
||||||
|
|
||||||
|
List all promotion requests
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ squadId: `591470249e9fae286e008e31` (string, optional)
|
||||||
|
specific squad Id to show the promotion requests for
|
||||||
|
|
||||||
|
+ inProgress: false (boolean, optional)
|
||||||
|
true to filter by promotion state 'in progress'
|
||||||
|
|
||||||
|
+ Default: false
|
||||||
|
|
||||||
|
+ fractFilter: `BLUFOR` (enum[string], optional)
|
||||||
|
Field to filter by fraction
|
||||||
|
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `GLOBAL`
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (array[PromotionPopulated])
|
||||||
|
|
||||||
|
### Create Promotion Proposal [POST /request/promotion]
|
||||||
|
|
||||||
|
Create a new proposal for a promotion, that needs to be approved by higher permission level user to take effect
|
||||||
|
|
||||||
|
**Permission: 1**
|
||||||
|
|
||||||
|
+ Request (application/json)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ userId: `5ab68d42f547ed304064e5f7` (string, required) - id of the army member to promote
|
||||||
|
+ oldRankLvl: 0 (number, required) - previous rank level
|
||||||
|
+ newRankLvl: 5 (number, required) - new rank level to apply
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Promotion, fixed-type)
|
||||||
|
|
||||||
|
|
||||||
|
### Update Promotion Proposal [PATCH /request/promotion/{id}]
|
||||||
|
|
||||||
|
Update the promotion proposal
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abf50d9861d950f157c4a0a` (string, required) - unique id of the promotion
|
||||||
|
|
||||||
|
+ Request (application/json)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ _id: `5abf50d9861d950f157c4a0a` (string, optional) - id of the promotion proposal
|
||||||
|
+ userId: `5ab68d42f547ed304064e5f7` (string, optional) - id of the army member to promote
|
||||||
|
+ proposer: `5abf5064861d950f157c4a09` (string, optional) - id of the proposing app user
|
||||||
|
+ oldRankLvl: 0 (number, optional) - previous rank level
|
||||||
|
+ newRankLvl: 5 (number, optional) - new rank level to apply
|
||||||
|
+ confirmed: 1 (number, optional) confirmation status of the promotion (0 - in progress, 1 - approved & applied, 2 - rejected) \nThis automatically applies the *newRankLvl*value as new rank level to the target user when confirmed = 1
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Promotion, fixed-type)
|
|
@ -0,0 +1,116 @@
|
||||||
|
### List Ranks [GET /ranks{?q,fractFilter}]
|
||||||
|
|
||||||
|
List all ranks
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ q: `Gefr` (string, optional) - filter string which filters for partial rank name
|
||||||
|
|
||||||
|
+ fractFilter: `BLUFOR` (enum[string], optional)
|
||||||
|
Field to filter by fraction
|
||||||
|
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `GLOBAL`
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (array[Rank], fixed-type)
|
||||||
|
|
||||||
|
|
||||||
|
### Get Rank [GET /ranks/{id}]
|
||||||
|
|
||||||
|
Retrieve single rank data
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5aba5504eadcce6332c6a775` (string, required) - unique id of the rank to fetch
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Rank, fixed-type)
|
||||||
|
|
||||||
|
### Create Rank [POST /ranks]
|
||||||
|
|
||||||
|
Create a new rank
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Request (multipart/form-data; boundary=---BOUNDARY)
|
||||||
|
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="name"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
Obergefreiter
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="fraction"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
BLUFOR
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="level"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
2
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="image"; filename="image.png"
|
||||||
|
Content-Type: image/png
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlMA
|
||||||
|
QObYZgAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII=
|
||||||
|
-----BOUNDARY--
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Rank, fixed-type)
|
||||||
|
|
||||||
|
### Update Rank [PATCH /ranks/{id}]
|
||||||
|
|
||||||
|
Update rank, identified by its id
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abeb23995cf43205225710b` (string, required) - unique id of the rank
|
||||||
|
|
||||||
|
+ Request (multipart/form-data; boundary=---BOUNDARY)
|
||||||
|
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="name"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
Stabsunteroffizier
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="fraction"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
BLUFOR
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="level"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
10
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="image"; filename="image.png"
|
||||||
|
Content-Type: image/png
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlMA
|
||||||
|
QObYZgAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII=
|
||||||
|
-----BOUNDARY--
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Rank, fixed-type)
|
||||||
|
|
||||||
|
### Delete Rank [DELETE /ranks/{id}]
|
||||||
|
|
||||||
|
Delete a rank
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abeb1b995cf43205225710a` (string, required) - unique id of the rank
|
||||||
|
|
||||||
|
+ Response 204
|
|
@ -0,0 +1,110 @@
|
||||||
|
### List Squads [GET /squads{?q,fractFilter}]
|
||||||
|
|
||||||
|
Get single army member information
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ q: `alpha` (string, optional) - filter string which filters for partial squadname
|
||||||
|
|
||||||
|
+ fractFilter: `BLUFOR` (enum[string], optional)
|
||||||
|
Field to filter by fraction
|
||||||
|
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `GLOBAL`
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (array[Squad], fixed-type)
|
||||||
|
|
||||||
|
### Get Squad [GET /squads/{id}]
|
||||||
|
|
||||||
|
Get single squad information
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5aba54eaeadcce6332c6a774` (string, required) - unique id of the squad
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Squad, fixed-type)
|
||||||
|
|
||||||
|
### Create Squad [POST /squads]
|
||||||
|
|
||||||
|
Create a new squad
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Request (multipart/form-data; boundary=---BOUNDARY)
|
||||||
|
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="name"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
Delta
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="fraction"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
BLUFOR
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="image"; filename="image.png"
|
||||||
|
Content-Type: image/png
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlMA
|
||||||
|
QObYZgAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII=
|
||||||
|
-----BOUNDARY--
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Squad, fixed-type)
|
||||||
|
|
||||||
|
### Update Squad [PATCH /squads/{id}]
|
||||||
|
|
||||||
|
Update squad, identified by its id
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abe166f8b7488392a623f12` (string, required) - unique id of the squad
|
||||||
|
|
||||||
|
+ Request (multipart/form-data; boundary=---BOUNDARY)
|
||||||
|
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="name"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
test-CSAT
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="fraction"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
OPFOR
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="sortingNumber"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
3
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="image"; filename="image.png"
|
||||||
|
Content-Type: image/png
|
||||||
|
Content-Transfer-Encoding: base64
|
||||||
|
|
||||||
|
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlMA
|
||||||
|
QObYZgAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII=
|
||||||
|
-----BOUNDARY--
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Squad, fixed-type)
|
||||||
|
|
||||||
|
### Delete Squad [DELETE /squads/{id}]
|
||||||
|
|
||||||
|
Delete a squad
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abe16f98b7488392a623f17` (string, required) - unique id of the squad
|
||||||
|
|
||||||
|
+ Response 204
|
|
@ -0,0 +1,93 @@
|
||||||
|
### List Users [GET /users{?q,fractFilter,limit,offset}]
|
||||||
|
|
||||||
|
Get single army member information
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ q: `hardi` (string, optional) - filter string which filters for partial username
|
||||||
|
|
||||||
|
+ fractFilter: `BLUFOR` (enum[string], optional)
|
||||||
|
Field to filter by fraction
|
||||||
|
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `GLOBAL`
|
||||||
|
|
||||||
|
+ limit: 20 (number, optional)
|
||||||
|
Maximum number of users to return
|
||||||
|
|
||||||
|
+ Default: Infinity
|
||||||
|
|
||||||
|
+ offset: 0 (number, optional)
|
||||||
|
Offset into result-set (useful for pagination)
|
||||||
|
|
||||||
|
+ Default: 0
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Headers
|
||||||
|
|
||||||
|
X-Total-Count: 1
|
||||||
|
|
||||||
|
+ Attributes (array[UserPopulated], fixed-type)
|
||||||
|
|
||||||
|
|
||||||
|
### Get User [GET /users/{id}]
|
||||||
|
|
||||||
|
Get single army member information
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5ab68d42f547ed304064e5f7` (string, required) - unique id of army-member
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (UserPopulated, fixed-type)
|
||||||
|
|
||||||
|
|
||||||
|
### Create User [POST /users]
|
||||||
|
|
||||||
|
Create a new army member
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Request (application/json)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ username: `[GNC]Paolo` (string, required) - display name of the user
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (UserInclTimestamp, fixed-type)
|
||||||
|
|
||||||
|
### Update User [PUT /users/{id}]
|
||||||
|
|
||||||
|
Update an army member, identified by its id
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abd4780396bc0487068be0e` (string, required) - unique id of army-member
|
||||||
|
|
||||||
|
+ Request (application/json)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ _id: `5abd4780396bc0487068be0e` (string, required) - unique id of army-member
|
||||||
|
+ username: `Paolo` (string, optional) - display name of the user
|
||||||
|
+ rankLvl: 22 (number, optional) - rank level representing the rank
|
||||||
|
+ squadId: `591470249e9fae286e008e31` (string, optional) - squadId of squad which army member is part of
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (User, fixed-type)
|
||||||
|
|
||||||
|
|
||||||
|
### Delete User [DELETE /users/{id}]
|
||||||
|
|
||||||
|
Delete an army member
|
||||||
|
|
||||||
|
**Permission: 2**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abd4780396bc0487068be0e` (string, required) - unique id of army-member
|
||||||
|
|
||||||
|
+ Response 204
|
|
@ -0,0 +1,11 @@
|
||||||
|
### Login - Generate Token [POST /authenticate]
|
||||||
|
|
||||||
|
Generate a token which can be used to make API requests.
|
||||||
|
|
||||||
|
+ Request Generate Token (application/json)
|
||||||
|
|
||||||
|
+ Attributes (Login)
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (LoginResponse)
|
|
@ -0,0 +1,13 @@
|
||||||
|
### Sign up - Create account [POST /authenticate/signup]
|
||||||
|
|
||||||
|
Create a new application user account.
|
||||||
|
|
||||||
|
+ Request Create Account (application/json)
|
||||||
|
|
||||||
|
+ Attributes (Registration)
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
|
||||||
|
+ message: `User successfully created` (string, required)
|
|
@ -0,0 +1,54 @@
|
||||||
|
## Location
|
||||||
|
|
||||||
|
The API can only be accessed via HTTPS in the cloud instance.
|
||||||
|
|
||||||
|
You can reach the API for the cloud instance at
|
||||||
|
|
||||||
|
```
|
||||||
|
https://cc.noarch.de/api/
|
||||||
|
```
|
||||||
|
|
||||||
|
Local installations can access the API using the respective domain with the path `/api/` appended.
|
||||||
|
|
||||||
|
So if your server is reachable at `https://cc.myserver.lan` the API endpoint is located at
|
||||||
|
|
||||||
|
```
|
||||||
|
# Note: `/api/` is appended to the locale installation server url
|
||||||
|
|
||||||
|
https://cc.myserver.lan/api/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Requests to most of the API endpoints have to be authenticated using an API token which is received after successfully providing your application credentials to the API.
|
||||||
|
|
||||||
|
Once acquired the token has to be provided in the ``X-Access-Token`` header of every request that requires authentication.
|
||||||
|
|
||||||
|
The following example illustrates how to provide the token when using `curl`
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
# via Authorization header
|
||||||
|
|
||||||
|
> curl -H "X-Access-Token: $CC_API_TOKEN" <API_RESOURCE_PATH_GOES_HERE>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Permission Levels
|
||||||
|
|
||||||
|
The permission level is resolved by the API token you send, which resolves the specific app user information.
|
||||||
|
|
||||||
|
Endpoints that require a certain permission level to be accessed, mention the **minimum** required permission level in the description.
|
||||||
|
|
||||||
|
::: note
|
||||||
|
Permission Levels:
|
||||||
|
|
||||||
|
0 - User
|
||||||
|
|
||||||
|
1 - Squadlead
|
||||||
|
|
||||||
|
2 - High Command
|
||||||
|
|
||||||
|
3 - Maintainer
|
||||||
|
|
||||||
|
4 - Administrator
|
||||||
|
:::
|
|
@ -0,0 +1,10 @@
|
||||||
|
## Timezones & Date Format
|
||||||
|
|
||||||
|
**Date Format**
|
||||||
|
|
||||||
|
In general the API returns and expects dates & times in the ISO 8601 format.
|
||||||
|
For example: `2017-02-27T17:05:33.155Z` for a time or `2017-02-27` for a date.
|
||||||
|
|
||||||
|
**Timezone**
|
||||||
|
|
||||||
|
The default timezone returned will be the UTC timezone
|
|
@ -0,0 +1,36 @@
|
||||||
|
The running express server instance saves entity related files like squad logos and statistic logs on the file system.
|
||||||
|
In the original MEAN application they are served in the `/resource` path of the application server.
|
||||||
|
|
||||||
|
The following examples show where those files are located, to be accessed on the cloud instance.
|
||||||
|
|
||||||
|
## Images
|
||||||
|
**Decoration Image**
|
||||||
|
|
||||||
|
`https://cc.noarch.de/resource/decoration/{decorationId}.png`
|
||||||
|
|
||||||
|
**Rank Image**
|
||||||
|
|
||||||
|
`https://cc.noarch.de/resource/rank/{rankId}.png`
|
||||||
|
|
||||||
|
**Signature Image**
|
||||||
|
|
||||||
|
`https://cc.noarch.de/resource/signature/{userId}.png`
|
||||||
|
|
||||||
|
**Squad Logo**
|
||||||
|
|
||||||
|
`https://cc.noarch.de/resource/squad/{squadId}.png`
|
||||||
|
|
||||||
|
## Log-Files
|
||||||
|
|
||||||
|
**Sanitized Log File**
|
||||||
|
|
||||||
|
`https://cc.noarch.de/resource/logs/{warId}/clean.log`
|
||||||
|
|
||||||
|
**Original Uploaded Log File**
|
||||||
|
|
||||||
|
`https://cc.noarch.de/resource/logs/{warId}/war.log`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Proposer (object)
|
||||||
|
Representation of an app user who proposed an awarding or a promotion
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
+ _id: `5abf5064861d950f157c4a09` (string, required) - unique id of the app user
|
||||||
|
+ username: `hardiready` (string, required) - username of the app user
|
||||||
|
+ squad: `591470249e9fae286e308e41` (string, required) - squad id associated with the app user
|
||||||
|
|
||||||
|
# AppUser (Proposer)
|
||||||
|
An app user instance with populated squad
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ activated: true (boolean, required) - account activation status
|
||||||
|
+ password: `$1s23$1$H7dl7RTFZUBIBNUZ213IIOUasdNEI571sMuzXmzi4` (string, required) - password hash value
|
||||||
|
+ permission: 1 (number, required) - permission level
|
||||||
|
+ secret: `I like tacos` (string, required) - secret used for account activation comparison
|
||||||
|
+ squad (Squad, required, nullable) - squad the app user is responsible for
|
||||||
|
+ timestamp: `2017-08-02T07:48:56.378Z` (string, required) - creation timestamp
|
||||||
|
+ updatedAt: `2017-08-02T08:07:20.929Z` (string, required) - version timestamp
|
||||||
|
+ __v: 3 (number, required) - version number
|
||||||
|
|
||||||
|
# UpdateAppUser (Proposer)
|
||||||
|
An app user instance for PATCH updating
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ activated: true (boolean, optional) - account activation status
|
||||||
|
+ password: `$1s23$1$H7dl7RTFZUBIBNUZ213IIOUasdNEI571sMuzXmzi4` (string, optional) - password hash value
|
||||||
|
+ permission: 1 (number, optional) - permission level
|
||||||
|
+ secret: `I like tacos` (string, optional) - secret used for account activation comparison
|
||||||
|
+ squad: `5abe166f8b7488392a623f12` (string, optional) - id of squad the app user is responsible for
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Fraction (object)
|
||||||
|
Single fraction object
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ squads (array[ArmySquad], required) - Array containing all squads of the fraction, sorted by 'sortingNumber'
|
||||||
|
+ memberCount: 1 (number, required) - sum of fraction members in all squads
|
||||||
|
|
||||||
|
|
||||||
|
# ArmySquad (object)
|
||||||
|
A single squad as appearing in the army overview
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ _id: `59146e6aef2ad810623ed519` (string, required) - the unique id of the squad
|
||||||
|
+ name: `Führungsstab` (string, required) - the squad display name
|
||||||
|
+ members (array[ArmyMember], required) - List of participants being member in this squad
|
||||||
|
+ memberCount: 1 (number, required) - Number of members the squad has
|
||||||
|
|
||||||
|
|
||||||
|
# ArmyMember (object)
|
||||||
|
Unique member in a army squad
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
+ _id: `5918d2ca574b0b16820a0b28` (string, required) - unique id of the army member
|
||||||
|
+ username: `Jagernaut` (string, required) - display name of the army member
|
||||||
|
+ rank: `General` (string, required) - display name of the rank which is assigned to this army member
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Login (object)
|
||||||
|
User related entity for creating a token using application credentials
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
+ username: `testuser` (string, required) - username of the app-user
|
||||||
|
+ password: `password` (string, required) - password of the app-user
|
||||||
|
|
||||||
|
# LoginResponse (object)
|
||||||
|
Response object on successful token creation
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
+ _id: `593d632772d35225232bcabb` (string, required) - the unique id of the app-user
|
||||||
|
+ username: `kallek` (string, required) - the username of the app-user
|
||||||
|
+ permission: 3 (number, required)- the permission level of the app-user (0 - user, 1 - sql, 2 - hl, 3 - maintainer, 4 - admin)
|
||||||
|
+ squad (Squad, required) - squad the app-user is member of
|
||||||
|
+ token: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1OTNkNWUzZjcyZDM1MjI1MjIyYmNhYmEiLCJpYXQiOjE1MjEzOTQ5NDYsImV4cCI6MTUyMzgxNDE0Nn0.vOAwA5--qrx8BglhyGZWVYx7LeuRKOHH0NQXmHFNhIQ` (string,required) - generated access token
|
||||||
|
+ tokenExpireDate: `2018-04-15T17:42:25.050Z` (string,required) - expiration date of the token
|
||||||
|
|
||||||
|
|
||||||
|
# Registration (object)
|
||||||
|
User related entity for reflecting membership to another resource (groups, material databases)
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
+ username: `kallek` (string, required) - the username of the app-user
|
||||||
|
+ password: `password` (string, required) - password of the app-user
|
||||||
|
+ secret: `random secret text` (string, required) - secret used for sign-up identification in connection with board usage
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Awarding (object)
|
||||||
|
Awarding associating a decoration to a user
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ _id: `591ca81c1ee62711cfc19002` (string, required) - unique id of the awarding
|
||||||
|
+ confirmed: 1 (number, required) - status of the awarding request (0 - in progress, 1 - approved, 2 - rejected)
|
||||||
|
+ date: `2017-05-17T19:44:24.926Z` (string, required) - date when the awarding was requested
|
||||||
|
+ decorationId: `591c81981ee62711cfc18f4a` (string, required) - id of decoration that is given with the awarding
|
||||||
|
+ reason: `war dabei` (string, required) - reason for giving the awarding
|
||||||
|
+ proposer: 593d5e3f72d35225222bcaba (string, required) - id of app user who requested this awarding
|
||||||
|
+ timestamp: `2017-05-17T19:44:28.751Z` (string, required) - creation date
|
||||||
|
+ updatedAt: `"2017-05-17T19:44:28.751Z` (string, required) - version date
|
||||||
|
+ userId: `5918d2ca574b0b1d820a0b24` (string, required) - the unique id of the user who got this awarding
|
||||||
|
+ __v: 0 (number, required) - version number
|
||||||
|
|
||||||
|
|
||||||
|
# AwardingPopulated (Awarding)
|
||||||
|
Awarding with populated decoration and proposer
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ proposer (Proposer, required) - app user who requested this awarding
|
||||||
|
+ decorationId (Decoration, required) - populated decoration object that is given with the awarding
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Campaign (object)
|
||||||
|
Campaign entity
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ _id:`5abd55ea9e30a76bfef747d6` (string, required) - unique id of the campaign
|
||||||
|
+ title: `Ein Kessel Buntes` (string, required) - display title of the campaign
|
||||||
|
+ timestamp: `2017-05-17T19:44:28.751Z` (string, required) - creation date
|
||||||
|
+ updatedAt: `"2017-05-17T19:44:28.751Z` (string, required) - version date
|
||||||
|
+ __v: 0 (number, required) - version number
|
||||||
|
|
||||||
|
#WarCampaign (object)
|
||||||
|
Cmpaign entity with attached War collection
|
||||||
|
## Properties
|
||||||
|
+ _id: `5abd55ea9e30a76bfef747d6` (string, required) - unique id of the campaign
|
||||||
|
+ title: `Ein Kessel Buntes` (string, required) - display title of the campaign
|
||||||
|
+ wars (array[WarWithPlayers], requied)
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Decoration (object)
|
||||||
|
|
||||||
|
A decoration representing a ribbon or medal
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
+ _id: `591c81981ee62711cfc18f4a` (string, required) - unique id of the decoration
|
||||||
|
+ description: `Verliehen an alle Teilnehmer der ArmA3-Kampagne "Sturm über der Ägäis" im Jahr 2016` (string, required) - description expressing what the decoration should be given for
|
||||||
|
+ fraction: `GLOBAL` (string, required) - enum expressing the fraction in which the decoration is given
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `GLOBAL`
|
||||||
|
+ isMedal: false (boolean, required) - show if decoration is medal or ribbon
|
||||||
|
+ name: `OPT4 pt.1 - "Sturm über der Ägäis"` (string, required) - display name of the decoration
|
||||||
|
+ sortingNumber: 10 (number, required) - sorting number for lists
|
||||||
|
+ timestamp: `2017-05-17T17:00:08.684Z` (string, required) - creation timestamp
|
||||||
|
+ updatedAt: `2018-01-13T09:57:50.827Z` (string, required) - version timestamp
|
||||||
|
+ __v: 2 (number, required) - version number
|
|
@ -0,0 +1,79 @@
|
||||||
|
# Log (object)
|
||||||
|
## Properties
|
||||||
|
+ _id: `` (string, required) - log entry id
|
||||||
|
+ war: `` (string, required) - warId
|
||||||
|
+ time: `` (string, required) - logging timestamp
|
||||||
|
+ __v: 0 (number, required) - object version number
|
||||||
|
|
||||||
|
# LogPoints (Log)
|
||||||
|
## Properties
|
||||||
|
+ ptBlufor: 2 (number, required) - standings for BLUFOR
|
||||||
|
+ ptOpfor: 4 (number, required) - standings for OPFOR
|
||||||
|
+ fraction: `OPFOR` (enum, required) - dominating fraction
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `NONE`
|
||||||
|
|
||||||
|
#LogBudget (Log)
|
||||||
|
## Properties
|
||||||
|
+ oldBudget: 400000 (number, required) - budget before buy action
|
||||||
|
+ newBudget: 380000 (number, required) - budget after buy action
|
||||||
|
+ fraction: `BLUFOR` (enum, required) - buying fraction
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
|
||||||
|
#LogFlag (Log)
|
||||||
|
## Properties
|
||||||
|
+ player: `HardiReady` (string, required) - name of player who captured/secured flag
|
||||||
|
+ capture: true (boolean, required) - true if flag was captured, false if it was secured
|
||||||
|
+ flagFraction: `BLUFOR` (enum, required) - fraction who owns the flag
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
|
||||||
|
#LogKill (Log)
|
||||||
|
## Properties
|
||||||
|
+ shooter: `HardiReady` (string, required) - name of player who made the kill
|
||||||
|
+ target: `KalleK` (string, required) - name of player which got killed
|
||||||
|
+ friendlyFire: true (boolean, required) - true if it was a friendly fire kill, false if it was a normal kill
|
||||||
|
+ fraction: `BLUFOR` (enum, required) - fraction of shooter
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `NONE`
|
||||||
|
|
||||||
|
#LogRespawn (Log)
|
||||||
|
## Properties
|
||||||
|
+ player: `radical1976` (string, required) - name of the player who respawns
|
||||||
|
|
||||||
|
#LogRevive (Log)
|
||||||
|
## Properties
|
||||||
|
+ medic: `radical1976` (string, required) - name of the player who revives/stabilizes
|
||||||
|
+ patient: `HardiReady` (string, required) - name of the player who is revived/stabilized
|
||||||
|
+ stabilized: false (boolean, required) - false if it is a revive, true if it is stabilizing
|
||||||
|
+ fraction: `BLUFOR` (enum, required) - fraction of the medic
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
|
||||||
|
#LogTransport (Log)
|
||||||
|
## Properties
|
||||||
|
+ driver: `radical1976` (string, required) - name of the vehicle driver/pilot
|
||||||
|
+ passenger: `radical1976` (string, required) - name of the passenger being transported
|
||||||
|
+ distance: 2435 (number, required) - distance of transport in meters
|
||||||
|
+ fraction: `BLUFOR` (enum, required) - fraction of the driver
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
|
||||||
|
#LogVehicle (Log)
|
||||||
|
## Properties
|
||||||
|
+ shooter: `HardiReady` (string, required) - name of player who shot the vehicle
|
||||||
|
+ target: `T-100` (string, required) - name of the vehicle
|
||||||
|
+ fraction: `BLUFOR` (enum, required) - fraction of the shooter
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `NONE`
|
|
@ -0,0 +1,34 @@
|
||||||
|
# BasicPlayer (object)
|
||||||
|
|
||||||
|
Basic player statistic information object
|
||||||
|
|
||||||
|
##Properties
|
||||||
|
+ name: `Jagernaut` (string, required) - the displayed username of the army member
|
||||||
|
+ fraction: `OPFOR` (string, required) - fraction of the player
|
||||||
|
+ kill: 5 (number, required) - sum of kills
|
||||||
|
+ friendlyFire: 0 (number, required) - sum of friendly fire kills
|
||||||
|
+ vehicle: 1 (number, required) - sum of vehicle kills
|
||||||
|
+ death: 3 (number, required) - sum of deaths
|
||||||
|
+ respawn: 2 (number, required) - sum of respawns
|
||||||
|
+ flagTouch: 1 (number, required) - sum of flag captures
|
||||||
|
+ revive: 0 (number, required) - sum of revives
|
||||||
|
|
||||||
|
|
||||||
|
# WarPlayer (BasicPlayer)
|
||||||
|
A player campaign statistics object
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ _id: `5ab68d42f547ed304064e5f7` (string, required) - unique id of the army member
|
||||||
|
+ warId: `5abf65ae3fc5fa349ffd5ca3` (string, required) - war in which this player took part
|
||||||
|
+ steamUUID: `76561192214911200` (string, required) - unique ID for STEAM platform account
|
||||||
|
+ sort: 1 (number, required) - sorting number calculated by (kill + revive + flagTouch - friendlyFire - death - respawn)
|
||||||
|
+ timestamp: `2018-02-24T01:01:25.825Z` - the entity creation timestamp
|
||||||
|
+ updatedAt: `2018-02-24T01:01:25.825Z` - the version timestamp
|
||||||
|
+ __v: 0 (number, required) - the version number of the object
|
||||||
|
|
||||||
|
|
||||||
|
# HighscorePlayer (BasicPlayer)
|
||||||
|
A player object as resturned for the highscore arrays
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ num: 1
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Promotion (object)
|
||||||
|
Representation of a promotion request for a army member
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ _id: `5as7d05dcb90ce4da68c4f5f` (string, required) - unique id of the promotion request
|
||||||
|
+ confirmed: 0 (number, required) - number representing status of the promotion (0 - in progress, 1 - approved, 2 - rejected)
|
||||||
|
+ newRankLvl: 14 (number, required)- new rank level that is requested in this promotion
|
||||||
|
+ oldRankLvl: 10 (number, required)- old rank level of the user
|
||||||
|
+ proposer: `5abf5064861d950f157c4a09` (string, required) - id of app user who requested the promotion
|
||||||
|
+ timestamp: `2018-03-25T18:54:21.609Z` (string, required) - creation timestamp
|
||||||
|
+ updatedAt: `2018-03-25T18:54:21.609Z` (string, required) - version timestamp
|
||||||
|
+ userId: `5ab68d42f547ed304064e5f7` (string, required) - id of army member the promotion is requested for
|
||||||
|
+ __v: 0 (number, required) - version number of promotion instance
|
||||||
|
|
||||||
|
# PromotionPopulated (object)
|
||||||
|
Promotion with populated proposer and army member
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ proposer (Proposer, required) - app user who requested the promotion
|
||||||
|
+ userId (User, required) - populated user instance of user the promotion is requested for
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Rank (object)
|
||||||
|
|
||||||
|
A rank that can be applied to army members by level/fraction
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ _id: `591469c9ef4a6810623ed4ea` (string, required) - the unique id of the rank
|
||||||
|
+ name: `Gefreiter` (string, required) - display name of the rank
|
||||||
|
+ fraction: `BLUFOR` (enum, required) - enum expressing the fraction in which the decoration is given
|
||||||
|
+ Members
|
||||||
|
+ `BLUFOR`
|
||||||
|
+ `OPFOR`
|
||||||
|
+ `GLOBAL`
|
||||||
|
+ level: 1 (number, required) - rank level
|
||||||
|
+ updatedAt: `2017-09-20T20:25:29.995Z` (string, required) - the version timestamp
|
||||||
|
+ timestamp: `2017-05-11T13:40:25.051Z` (string, required) - the creation timestamp
|
||||||
|
+ __v: 1 (number, required) - version number
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Squad (object)
|
||||||
|
|
||||||
|
A Squad entity
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
+ _id: `591470249e9fae286e008e31` (string, required) - the unique id of the squad
|
||||||
|
+ sortingNumber: 30 (number, required) - the number for orders in lists of squads
|
||||||
|
+ updatedAt: `2017-05-31T20:43:07.165Z` (string, required) - version timestamp
|
||||||
|
+ timestamp: `2017-05-11T14:07:32.471Z` (string, required) - creation timestamp
|
||||||
|
+ name: `Alpha` (string, required) - display name of the squad
|
||||||
|
+ fraction: `BLUFOR` (string, required) - fraction the squad is part of
|
||||||
|
+ __v: 2 (number, required) - version number
|
|
@ -0,0 +1,22 @@
|
||||||
|
# User (object)
|
||||||
|
A participant managed in the system
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ _id: `5ab68d42f547ed304064e5f7` (string, required) - unique id of the army member
|
||||||
|
+ username: `Jagernaut` (string, required) - the displayed username of the army member
|
||||||
|
+ rankLvl: 22 (number, required) - rank level representing the rank
|
||||||
|
+ squadId: `591470249e9fae286e008e31` (string, required, nullable) - id of squad which the army member is part of
|
||||||
|
+ updatedAt: `2018-02-24T01:01:25.825Z` - the version timestamp
|
||||||
|
+ __v: 35 (number, required) - the version number of the object
|
||||||
|
|
||||||
|
# UserPopulated (User)
|
||||||
|
User object with populated squad
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ squadId (Squad, required) - populated squad which the army member is part of
|
||||||
|
|
||||||
|
# UserInclTimestamp (User)
|
||||||
|
A participant managed in the system, incl. creation timestamp
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ timestamp: 2018-01-20T12:11:23.125Z (string, required) - instance creation timestamp
|
|
@ -0,0 +1,26 @@
|
||||||
|
# War (object)
|
||||||
|
A war as used in statistics
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ _id: `5ab68d41f537ed304064e5f7` (string, required) - unique id of the war
|
||||||
|
+ title: `Battle No.1` (string, required) - the display neme of the war
|
||||||
|
+ date: `2018-02-24T20:01:25.825Z` (string, required) - war start timestamp
|
||||||
|
+ endDate: `2018-02-24T22:31:26.855Z` (string, required) - war end timestamp
|
||||||
|
+ ptBlufor: 11 (number, required) - final points fraction Blufor
|
||||||
|
+ ptOpfor: 12 (number, required) - final points fraction Opfor
|
||||||
|
+ playersBlufor: 36 (number, required) - player count of fraction Blufor
|
||||||
|
+ playersOpfor: 34 (number, required) - player count of fraction opfor
|
||||||
|
+ campaign: `5abd55ea9e30a76bfef747d6` (string, required) - uniquer id of the campaign in which the war was played
|
||||||
|
+ budgetBlufor: 3900000 (number, required) - start budget of fraction Blufor
|
||||||
|
+ budgetOpfor: 4100000 (number, required) - start budget of fraction Opfor
|
||||||
|
+ endBudgetBlufor: 924000 (number, required) - end budget of fraction Blufor
|
||||||
|
+ endBudgetOpfor: 12400 (number, required) - end budget of fraction Opfor
|
||||||
|
+ timestamp: `2018-02-24T01:01:25.825Z` (string, required) - creation date
|
||||||
|
+ updatedAt: `2018-02-24T01:01:25.825Z` (string, required) - the version timestamp
|
||||||
|
+ __v: 0 (number, required) - the version number of the object
|
||||||
|
|
||||||
|
# WarWithPlayers (War)
|
||||||
|
A war response object on creation
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
+ players (array[WarPlayer], required) - collection of all participating players with their statistics
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Data Structures
|
||||||
|
|
||||||
|
:[Gists](_app-user.apib)
|
||||||
|
|
||||||
|
:[Gists](_army.apib)
|
||||||
|
|
||||||
|
:[Gists](_auth.apib)
|
||||||
|
|
||||||
|
:[Gists](_awarding.apib)
|
||||||
|
|
||||||
|
:[Gists](_campaign.apib)
|
||||||
|
|
||||||
|
:[Gists](_decoration.apib)
|
||||||
|
|
||||||
|
:[Gists](_log.apib)
|
||||||
|
|
||||||
|
:[Gists](_player.apib)
|
||||||
|
|
||||||
|
:[Gists](_promotion.apib)
|
||||||
|
|
||||||
|
:[Gists](_rank.apib)
|
||||||
|
|
||||||
|
:[Gists](_squad.apib)
|
||||||
|
|
||||||
|
:[Gists](_user.apib)
|
||||||
|
|
||||||
|
:[Gists](_war.apib)
|
|
@ -0,0 +1,71 @@
|
||||||
|
FORMAT: 1A
|
||||||
|
|
||||||
|
# Operation Pandora Trigger Command Center API Documentation
|
||||||
|
|
||||||
|
:[Gists](data_structures/index.apib)
|
||||||
|
|
||||||
|
# Group General Introduction
|
||||||
|
|
||||||
|
:[Gists](base/access.apib)
|
||||||
|
|
||||||
|
:[Gists](base/datetime.apib)
|
||||||
|
|
||||||
|
# Group File Resources
|
||||||
|
|
||||||
|
:[Gists](base/file-resources.apib)
|
||||||
|
|
||||||
|
# Group Access
|
||||||
|
|
||||||
|
:[Gists](auth/signup.apib)
|
||||||
|
|
||||||
|
:[Gists](auth/login.apib)
|
||||||
|
|
||||||
|
# Group Admin
|
||||||
|
|
||||||
|
:[Gists](admin/account.apib)
|
||||||
|
|
||||||
|
:[Gists](admin/signature.apib)
|
||||||
|
|
||||||
|
# Group Army Overview
|
||||||
|
|
||||||
|
:[Gists](army-management/army.apib)
|
||||||
|
|
||||||
|
# Group Awardings
|
||||||
|
|
||||||
|
:[Gists](army-management/awardings.apib)
|
||||||
|
|
||||||
|
# Group Campaigns
|
||||||
|
|
||||||
|
:[Gists](statistics/campaigns.apib)
|
||||||
|
|
||||||
|
# Group Decorations
|
||||||
|
|
||||||
|
:[Gists](army-management/decorations.apib)
|
||||||
|
|
||||||
|
# Group Logs
|
||||||
|
|
||||||
|
:[Gists](statistics/logs.apib)
|
||||||
|
|
||||||
|
# Group Players
|
||||||
|
|
||||||
|
:[Gists](statistics/players.apib)
|
||||||
|
|
||||||
|
# Group Promotion
|
||||||
|
|
||||||
|
:[Gists](army-management/promotions.apib)
|
||||||
|
|
||||||
|
# Group Ranks
|
||||||
|
|
||||||
|
:[Gists](army-management/ranks.apib)
|
||||||
|
|
||||||
|
# Group Squads
|
||||||
|
|
||||||
|
:[Gists](army-management/squads.apib)
|
||||||
|
|
||||||
|
# Group Users
|
||||||
|
|
||||||
|
:[Gists](army-management/users.apib)
|
||||||
|
|
||||||
|
# Group Wars
|
||||||
|
|
||||||
|
:[Gists](statistics/wars.apib)
|
|
@ -0,0 +1,3 @@
|
||||||
|
{"_id":{"$oid":"5abf5064861d950f157c4a09"},"squad":{"$oid":"5aba54eaeadcce6332c6a774"},"permission":1,"activated":true,"username":"some-squadlead","secret":"asd","password":"$2a$10$PGUw2F6HY.2Q3h0AL4Mea.3EKAGFO8S897z56CyU8q/5BC.5VEPAy","timestamp":{"$date":"2018-03-31T09:09:56.161Z"},"updatedAt":{"$date":"2018-03-31T09:09:56.161Z"},"__v":1}
|
||||||
|
{"_id":{"$oid":"5ab68ceef547ed304064e5f6"},"squad":{"$oid":"5aba54eaeadcce6332c6a774"},"permission":4,"activated":true,"username":"testuser","secret":"my secret","password":"$2a$10$wvgBbcckHrFu8Ctw8hSPNuFLoBy4sRubioyiK1NabOC0UgYD.KITi","timestamp":{"$date":"2018-03-24T17:37:50.668Z"},"updatedAt":{"$date":"2018-03-24T17:37:50.668Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5ac0de67b5edc7771c027b94"},"squad":null,"permission":0,"activated":false,"username":"lord","secret":"tank","password":"$2a$10$k9LG.OiedyyGrySbDX7KZekesHEU.BadBhUUyS2ujM07NpIrLPFxe","timestamp":{"$date":"2018-04-01T13:28:07.147Z"},"updatedAt":{"$date":"2018-04-01T13:28:07.147Z"},"__v":0}
|
|
@ -0,0 +1 @@
|
||||||
|
{"_id":{"$oid":"5abf50e7861d950f157c4a0b"},"confirmed":0,"date":{"$date":"2018-03-31T09:12:07.861Z"},"userId":{"$oid":"5ab68d42f547ed304064e5f7"},"decorationId":{"$oid":"5abd3dff6e6a0334d95b8ba0"},"reason":"bester mann!","proposer":{"$oid":"5abf5064861d950f157c4a09"},"timestamp":{"$date":"2018-03-31T09:12:07.873Z"},"updatedAt":{"$date":"2018-03-31T09:12:07.873Z"},"__v":0}
|
|
@ -0,0 +1,2 @@
|
||||||
|
{"_id":{"$oid":"5abd55ea9e30a76bfef747d6"},"title":"Ein Kessel Buntes","timestamp":{"$date":"2018-03-29T21:08:58.123Z"},"updatedAt":{"$date":"2018-03-29T21:08:58.123Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abd58989e30a76bfef747e6"},"title":"This Is The End","timestamp":{"$date":"2018-03-29T21:20:24.558Z"},"updatedAt":{"$date":"2018-03-29T21:20:24.558Z"},"__v":0}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{"_id":{"$oid":"5abeb420b987672bb1ede643"},"sortingNumber":0,"name":"Teilnehmer der Kampagne X","fraction":"GLOBAL","isMedal":false,"description":"Dabei sein ist alles","timestamp":{"$date":"2018-03-30T22:03:12.228Z"},"updatedAt":{"$date":"2018-03-30T22:03:12.228Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abd3dff6e6a0334d95b8ba0"},"sortingNumber":0,"name":"Orden der Tapferkeit","fraction":"BLUFOR","isMedal":true,"description":"Das ist ein Orden den tapfere Leute bekommen","timestamp":{"$date":"2018-03-29T19:26:55.387Z"},"updatedAt":{"$date":"2018-03-29T19:26:55.387Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abeb43cb987672bb1ede644"},"sortingNumber":0,"name":"Ehrenmedaille","fraction":"OPFOR","isMedal":true,"description":"Fuer die Ehre","timestamp":{"$date":"2018-03-30T22:03:40.560Z"},"updatedAt":{"$date":"2018-03-30T22:03:40.560Z"},"__v":0}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb6"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:01:00.000Z"},"fraction":"BLUFOR","oldBudget":4535500,"newBudget":4195500,"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5ccf"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:04:00.000Z"},"fraction":"OPFOR","oldBudget":2384250,"newBudget":2324250,"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cce"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:01:00.000Z"},"fraction":"BLUFOR","oldBudget":4535500,"newBudget":4195500,"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb7"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:04:00.000Z"},"fraction":"OPFOR","oldBudget":2384250,"newBudget":2324250,"__v":0}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb5"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:13:00.000Z"},"player":"ALASTOR","flagFraction":"OPFOR","capture":false,"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5ccc"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:12:00.000Z"},"player":"Wiesl","flagFraction":"OPFOR","capture":true,"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5ccd"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:13:00.000Z"},"player":"ALASTOR","flagFraction":"OPFOR","capture":false,"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb4"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:12:00.000Z"},"player":"Wiesl","flagFraction":"OPFOR","capture":true,"__v":0}
|
|
@ -0,0 +1,8 @@
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cac"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:04:00.000Z"},"shooter":null,"target":"Saxe","friendlyFire":false,"fraction":"NONE","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cae"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:12:00.000Z"},"shooter":"Wiesl","target":"patze","friendlyFire":false,"fraction":"BLUFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cad"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:04:00.000Z"},"shooter":"Saxe","target":"Pumarang","friendlyFire":true,"fraction":"BLUFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5caf"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:12:00.000Z"},"shooter":"Wiesl","target":"Nicolas","friendlyFire":true,"fraction":"BLUFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc4"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:04:00.000Z"},"shooter":null,"target":"Saxe","friendlyFire":false,"fraction":"NONE","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc5"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:04:00.000Z"},"shooter":"Saxe","target":"Pumarang","friendlyFire":true,"fraction":"BLUFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc7"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:12:00.000Z"},"shooter":"Wiesl","target":"Nicolas","friendlyFire":true,"fraction":"BLUFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc6"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:12:00.000Z"},"shooter":"Wiesl","target":"patze","friendlyFire":false,"fraction":"BLUFOR","__v":0}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cba"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:13:00.000Z"},"ptBlufor":1,"ptOpfor":0,"fraction":"BLUFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb9"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:10:00.000Z"},"ptBlufor":0,"ptOpfor":0,"fraction":"NONE","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cd1"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:10:00.000Z"},"ptBlufor":0,"ptOpfor":0,"fraction":"NONE","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cd2"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:13:00.000Z"},"ptBlufor":1,"ptOpfor":0,"fraction":"BLUFOR","__v":0}
|
|
@ -0,0 +1,2 @@
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc9"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:04:00.000Z"},"player":"Pumarang","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb1"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:04:00.000Z"},"player":"Pumarang","__v":0}
|
|
@ -0,0 +1,4 @@
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb3"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:35:00.000Z"},"stabilized":false,"medic":"Wiesl","patient":"Andi-de","fraction":"BLUFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5ccb"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:35:00.000Z"},"stabilized":false,"medic":"Wiesl","patient":"Andi-de","fraction":"BLUFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb2"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:35:00.000Z"},"stabilized":true,"medic":"ALASTOR","patient":"Bodochecker","fraction":"OPFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cca"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:35:00.000Z"},"stabilized":true,"medic":"ALASTOR","patient":"Bodochecker","fraction":"OPFOR","__v":0}
|
|
@ -0,0 +1,2 @@
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb8"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:31:00.000Z"},"driver":"Ponykloete","passenger":" Dominik","fraction":"BLUFOR","distance":8666,"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cd0"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:31:00.000Z"},"driver":"Ponykloete","passenger":" Dominik","fraction":"BLUFOR","distance":8666,"__v":0}
|
|
@ -0,0 +1,2 @@
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cb0"},"war":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"time":{"$date":"2018-03-19T23:16:00.000Z"},"shooter":"Murda]X[","target":"Hunter-HMG","fraction":"OPFOR","__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc8"},"war":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"time":{"$date":"2018-03-19T23:16:00.000Z"},"shooter":"Murda]X[","target":"Hunter-HMG","fraction":"OPFOR","__v":0}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca4"},"name":"Pumarang","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119805032149e+16,"respawn":1,"kill":0,"vehicle":0,"friendlyFire":0,"death":1,"revive":0,"flagTouch":0,"sort":-2,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca5"},"name":"Mercurat","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.65611982788425e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca6"},"name":"KalleK","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119797767603e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca7"},"name":"MAPster","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119800988213e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca8"},"name":"LyrikEmu","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.65611982189104e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca9"},"name":"Philipp","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119804179206e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5caa"},"name":"Wiesl","fraction":"BLUFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.65611980596481e+16,"respawn":0,"kill":1,"vehicle":0,"friendlyFire":1,"death":0,"revive":1,"flagTouch":1,"sort":2,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5cab"},"name":"Murda]X[","fraction":"OPFOR","warId":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"steamUUID":7.656119797112163e+16,"respawn":0,"kill":0,"vehicle":1,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:40:46.712Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.712Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbc"},"name":"Pumarang","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119805032149e+16,"respawn":1,"kill":0,"vehicle":0,"friendlyFire":0,"death":1,"revive":0,"flagTouch":0,"sort":-2,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbd"},"name":"Mercurat","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.65611982788425e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbe"},"name":"KalleK","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119797767603e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc1"},"name":"Philipp","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119804179206e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc0"},"name":"LyrikEmu","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.65611982189104e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc2"},"name":"Wiesl","fraction":"BLUFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.65611980596481e+16,"respawn":0,"kill":1,"vehicle":0,"friendlyFire":1,"death":0,"revive":1,"flagTouch":1,"sort":2,"timestamp":{"$date":"2018-03-31T10:41:28.460Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.460Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cc3"},"name":"Murda]X[","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119797112163e+16,"respawn":0,"kill":0,"vehicle":1,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.460Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.460Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbf"},"name":"MAPster","fraction":"OPFOR","warId":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"steamUUID":7.656119800988213e+16,"respawn":0,"kill":0,"vehicle":0,"friendlyFire":0,"death":0,"revive":0,"flagTouch":0,"sort":0,"timestamp":{"$date":"2018-03-31T10:41:28.459Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.459Z"},"__v":0}
|
|
@ -0,0 +1 @@
|
||||||
|
{"_id":{"$oid":"5abf50d9861d950f157c4a0a"},"userId":{"$oid":"5ab68d42f547ed304064e5f7"},"oldRankLvl":0,"newRankLvl":10,"confirmed":0,"proposer":{"$oid":"5abf5064861d950f157c4a09"},"timestamp":{"$date":"2018-03-31T09:11:53.364Z"},"updatedAt":{"$date":"2018-03-31T09:11:53.364Z"},"__v":0}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{"_id":{"$oid":"5abeb23995cf43205225710b"},"name":"Unteroffizier","fraction":"BLUFOR","level":10,"timestamp":{"$date":"2018-03-30T21:55:05.625Z"},"updatedAt":{"$date":"2018-03-30T21:55:05.625Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5aba5504eadcce6332c6a775"},"name":"Gefreiter","fraction":"BLUFOR","level":0,"timestamp":{"$date":"2018-03-27T14:28:20.948Z"},"updatedAt":{"$date":"2018-03-27T14:28:20.948Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abeb1b995cf43205225710a"},"name":"General","fraction":"OPFOR","level":22,"timestamp":{"$date":"2018-03-30T21:52:57.204Z"},"updatedAt":{"$date":"2018-03-30T21:52:57.204Z"},"__v":0}
|
After Width: | Height: | Size: 95 B |
After Width: | Height: | Size: 95 B |
After Width: | Height: | Size: 95 B |
|
@ -0,0 +1,34 @@
|
||||||
|
2018/03/20, 20:05:43 "[OPT] (Budget) LOG: 0:00:00 --- Startbudget: NATO 4.5355e+006 - CSAT 4.22125e+006"
|
||||||
|
|
||||||
|
2018/03/20, 20:06:45 "[OPT] (Budget) LOG: 0:01:02 --- NATO alt: 4.5355e+006 - neu: 4.1955e+006 - Differenz: -340000"
|
||||||
|
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Saxe (WEST) von: Selbstverschulden."
|
||||||
|
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Pumarang (WEST) von: Saxe (WEST)."
|
||||||
|
|
||||||
|
2018/03/20, 20:10:13 "[OPT] (Budget) LOG: 0:04:30 --- CSAT alt: 2.38425e+006 - neu: 2.32425e+006 - Differenz: -60000"
|
||||||
|
|
||||||
|
2018/03/20, 20:15:54 "[OPT] (Punkte) LOG: 0:10:11 --- Kein Dominator (NATO 0 | CSAT 0)"
|
||||||
|
|
||||||
|
2018/03/20, 20:17:51 "[OPT] (Abschuss) LOG: 0:12:08 --- patze (EAST) von: Wiesl (WEST)."
|
||||||
|
|
||||||
|
2018/03/20, 20:18:20 "[OPT] (Fahne) LOG: 0:12:37 --- CSAT Flagge erobert von Wiesl"
|
||||||
|
|
||||||
|
2018/03/20, 20:18:38 "[OPT] (Abschuss) LOG: 0:12:55 --- Nicolas (WEST) von: Wiesl (WEST)."
|
||||||
|
|
||||||
|
2018/03/20, 20:18:59 "[OPT] (Punkte) LOG: 0:13:16 --- NATO +1 (NATO 1 | CSAT 0)"
|
||||||
|
|
||||||
|
2018/03/20, 20:19:38 "[OPT] (Fahne) LOG: 0:13:56 --- CSAT Flagge gesichert von ALASTOR"
|
||||||
|
|
||||||
|
2018/03/20, 20:22:18 "[OPT] (Abschuss) LOG: 0:16:35 --- Fahrzeug: Hunter-HMG (OPT_NATO) von: Murda]X[ (EAST)."
|
||||||
|
|
||||||
|
2018/03/20, 20:37:19 "[OPT] (Transport) LOG: 0:31:36 --- Dominik (WEST) wurde von Ponykloete (WEST) eingeflogen (8666.94 m)"
|
||||||
|
|
||||||
|
2018/03/20, 20:41:27 "[OPT] (Revive) LOG: 0:35:44 --- Bodochecker (EAST) wurde von ALASTOR (EAST) stabilisiert."
|
||||||
|
|
||||||
|
2018/03/20, 20:41:35 "[OPT] (Revive) LOG: 0:35:52 --- Andi-de (WEST) wurde von Wiesl (WEST) wiederbelebt."
|
||||||
|
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Budget) LOG: 2:30:00 --- Endbudget: (NATO 1997000 | CSAT 512000)"
|
||||||
|
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Punkte) LOG: 2:30:00 --- Endpunktestand: (NATO 34 | CSAT 25)"
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
Error: ENOENT: no such file or directory, open '
|
||||||
|
2018/03/20, 20:05:43 "[OPT] (Budget) LOG: 0:00:00 --- Startbudget: NATO 4.5355e+006 - CSAT 4.22125e+006"
|
||||||
|
2018/03/20, 20:06:45 "[OPT] (Budget) LOG: 0:01:02 --- NATO alt: 4.5355e+006 - neu: 4.1955e+006 - Differenz: -340000"
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Saxe (WEST) von: Selbstverschulden."
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Pumarang (WEST) von: Saxe (WEST)."
|
||||||
|
2018/03/20, 20:10:13 "[OPT] (Budget) LOG: 0:04:30 --- CSAT alt: 2.38425e+006 - neu: 2.32425e+006 - Differenz: -60000"
|
||||||
|
2018/03/20, 20:10:38 "[OPT] (Respawn) LOG: 0:04:55 --- Spieler: Pumarang - Kosten: 3000"
|
||||||
|
2018/03/20, 20:15:54 "[OPT] (Punkte) LOG: 0:10:11 --- Kein Dominator (NATO 0 | CSAT 0)"
|
||||||
|
2018/03/20, 20:17:51 "[OPT] (Abschuss) LOG: 0:12:08 --- patze (EAST) von: Wiesl (WEST)."
|
||||||
|
2018/03/20, 20:18:20 "[OPT] (Fahne) LOG: 0:12:37 --- CSAT Flagge erobert von Wiesl"
|
||||||
|
2018/03/20, 20:18:38 "[OPT] (Abschuss) LOG: 0:12:55 --- Nicolas (WEST) von: Wiesl (WEST)."
|
||||||
|
2018/03/20, 20:18:59 "[OPT] (Punkte) LOG: 0:13:16 --- NATO +1 (NATO 1 | CSAT 0)"
|
||||||
|
2018/03/20, 20:19:38 "[OPT] (Fahne) LOG: 0:13:56 --- CSAT Flagge gesichert von ALASTOR"
|
||||||
|
2018/03/20, 20:22:18 "[OPT] (Abschuss) LOG: 0:16:35 --- Fahrzeug: Hunter-HMG (OPT_NATO) von: Murda]X[ (EAST)."
|
||||||
|
2018/03/20, 20:37:19 "[OPT] (Transport) LOG: 0:31:36 --- Dominik (WEST) wurde von Ponykloete (WEST) eingeflogen (8666.94 m)"
|
||||||
|
2018/03/20, 20:41:27 "[OPT] (Revive) LOG: 0:35:44 --- Bodochecker (EAST) wurde von ALASTOR (EAST) stabilisiert."
|
||||||
|
2018/03/20, 20:41:35 "[OPT] (Revive) LOG: 0:35:52 --- Andi-de (WEST) wurde von Wiesl (WEST) wiederbelebt."
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Mission) LOG: 2:30:00 --- Missionzeit abgelaufen"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Pumarang (WEST), PUID 76561198050321485"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Mercurat (WEST), PUID 76561198278842491"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- KalleK (EAST), PUID 76561197977676036"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- MAPster (EAST), PUID 76561198009882133"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- LyrikEmu (WEST), PUID 76561198218910400"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Philipp (EAST), PUID 76561198041792069"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Wiesl (WEST), PUID 76561198059648090"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Murda]X[ (EAST), PUID 76561197971121630"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Budget) LOG: 2:30:00 --- Endbudget: (NATO 1997000 | CSAT 512000)"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Punkte) LOG: 2:30:00 --- Endpunktestand: (NATO 34 | CSAT 25)"
|
||||||
|
'
|
|
@ -0,0 +1,34 @@
|
||||||
|
2018/03/20, 20:05:43 "[OPT] (Budget) LOG: 0:00:00 --- Startbudget: NATO 4.5355e+006 - CSAT 4.22125e+006"
|
||||||
|
|
||||||
|
2018/03/20, 20:06:45 "[OPT] (Budget) LOG: 0:01:02 --- NATO alt: 4.5355e+006 - neu: 4.1955e+006 - Differenz: -340000"
|
||||||
|
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Saxe (WEST) von: Selbstverschulden."
|
||||||
|
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Pumarang (WEST) von: Saxe (WEST)."
|
||||||
|
|
||||||
|
2018/03/20, 20:10:13 "[OPT] (Budget) LOG: 0:04:30 --- CSAT alt: 2.38425e+006 - neu: 2.32425e+006 - Differenz: -60000"
|
||||||
|
|
||||||
|
2018/03/20, 20:15:54 "[OPT] (Punkte) LOG: 0:10:11 --- Kein Dominator (NATO 0 | CSAT 0)"
|
||||||
|
|
||||||
|
2018/03/20, 20:17:51 "[OPT] (Abschuss) LOG: 0:12:08 --- patze (EAST) von: Wiesl (WEST)."
|
||||||
|
|
||||||
|
2018/03/20, 20:18:20 "[OPT] (Fahne) LOG: 0:12:37 --- CSAT Flagge erobert von Wiesl"
|
||||||
|
|
||||||
|
2018/03/20, 20:18:38 "[OPT] (Abschuss) LOG: 0:12:55 --- Nicolas (WEST) von: Wiesl (WEST)."
|
||||||
|
|
||||||
|
2018/03/20, 20:18:59 "[OPT] (Punkte) LOG: 0:13:16 --- NATO +1 (NATO 1 | CSAT 0)"
|
||||||
|
|
||||||
|
2018/03/20, 20:19:38 "[OPT] (Fahne) LOG: 0:13:56 --- CSAT Flagge gesichert von ALASTOR"
|
||||||
|
|
||||||
|
2018/03/20, 20:22:18 "[OPT] (Abschuss) LOG: 0:16:35 --- Fahrzeug: Hunter-HMG (OPT_NATO) von: Murda]X[ (EAST)."
|
||||||
|
|
||||||
|
2018/03/20, 20:37:19 "[OPT] (Transport) LOG: 0:31:36 --- Dominik (WEST) wurde von Ponykloete (WEST) eingeflogen (8666.94 m)"
|
||||||
|
|
||||||
|
2018/03/20, 20:41:27 "[OPT] (Revive) LOG: 0:35:44 --- Bodochecker (EAST) wurde von ALASTOR (EAST) stabilisiert."
|
||||||
|
|
||||||
|
2018/03/20, 20:41:35 "[OPT] (Revive) LOG: 0:35:52 --- Andi-de (WEST) wurde von Wiesl (WEST) wiederbelebt."
|
||||||
|
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Budget) LOG: 2:30:00 --- Endbudget: (NATO 1997000 | CSAT 512000)"
|
||||||
|
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Punkte) LOG: 2:30:00 --- Endpunktestand: (NATO 34 | CSAT 25)"
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
Error: ENOENT: no such file or directory, open '
|
||||||
|
2018/03/20, 20:05:43 "[OPT] (Budget) LOG: 0:00:00 --- Startbudget: NATO 4.5355e+006 - CSAT 4.22125e+006"
|
||||||
|
2018/03/20, 20:06:45 "[OPT] (Budget) LOG: 0:01:02 --- NATO alt: 4.5355e+006 - neu: 4.1955e+006 - Differenz: -340000"
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Saxe (WEST) von: Selbstverschulden."
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Pumarang (WEST) von: Saxe (WEST)."
|
||||||
|
2018/03/20, 20:10:13 "[OPT] (Budget) LOG: 0:04:30 --- CSAT alt: 2.38425e+006 - neu: 2.32425e+006 - Differenz: -60000"
|
||||||
|
2018/03/20, 20:10:38 "[OPT] (Respawn) LOG: 0:04:55 --- Spieler: Pumarang - Kosten: 3000"
|
||||||
|
2018/03/20, 20:15:54 "[OPT] (Punkte) LOG: 0:10:11 --- Kein Dominator (NATO 0 | CSAT 0)"
|
||||||
|
2018/03/20, 20:17:51 "[OPT] (Abschuss) LOG: 0:12:08 --- patze (EAST) von: Wiesl (WEST)."
|
||||||
|
2018/03/20, 20:18:20 "[OPT] (Fahne) LOG: 0:12:37 --- CSAT Flagge erobert von Wiesl"
|
||||||
|
2018/03/20, 20:18:38 "[OPT] (Abschuss) LOG: 0:12:55 --- Nicolas (WEST) von: Wiesl (WEST)."
|
||||||
|
2018/03/20, 20:18:59 "[OPT] (Punkte) LOG: 0:13:16 --- NATO +1 (NATO 1 | CSAT 0)"
|
||||||
|
2018/03/20, 20:19:38 "[OPT] (Fahne) LOG: 0:13:56 --- CSAT Flagge gesichert von ALASTOR"
|
||||||
|
2018/03/20, 20:22:18 "[OPT] (Abschuss) LOG: 0:16:35 --- Fahrzeug: Hunter-HMG (OPT_NATO) von: Murda]X[ (EAST)."
|
||||||
|
2018/03/20, 20:37:19 "[OPT] (Transport) LOG: 0:31:36 --- Dominik (WEST) wurde von Ponykloete (WEST) eingeflogen (8666.94 m)"
|
||||||
|
2018/03/20, 20:41:27 "[OPT] (Revive) LOG: 0:35:44 --- Bodochecker (EAST) wurde von ALASTOR (EAST) stabilisiert."
|
||||||
|
2018/03/20, 20:41:35 "[OPT] (Revive) LOG: 0:35:52 --- Andi-de (WEST) wurde von Wiesl (WEST) wiederbelebt."
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Mission) LOG: 2:30:00 --- Missionzeit abgelaufen"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Pumarang (WEST), PUID 76561198050321485"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Mercurat (WEST), PUID 76561198278842491"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- KalleK (EAST), PUID 76561197977676036"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- MAPster (EAST), PUID 76561198009882133"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- LyrikEmu (WEST), PUID 76561198218910400"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Philipp (EAST), PUID 76561198041792069"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Wiesl (WEST), PUID 76561198059648090"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Murda]X[ (EAST), PUID 76561197971121630"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Budget) LOG: 2:30:00 --- Endbudget: (NATO 1997000 | CSAT 512000)"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Punkte) LOG: 2:30:00 --- Endpunktestand: (NATO 34 | CSAT 25)"
|
||||||
|
'
|
After Width: | Height: | Size: 95 B |
After Width: | Height: | Size: 95 B |
After Width: | Height: | Size: 95 B |
After Width: | Height: | Size: 95 B |
After Width: | Height: | Size: 95 B |
After Width: | Height: | Size: 95 B |
|
@ -0,0 +1,3 @@
|
||||||
|
{"_id":{"$oid":"5aba54eaeadcce6332c6a774"},"sortingNumber":0,"name":"Alpha","fraction":"BLUFOR","timestamp":{"$date":"2018-03-27T14:27:54.399Z"},"updatedAt":{"$date":"2018-03-27T14:27:54.399Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abe166f8b7488392a623f12"},"sortingNumber":0,"name":"Führungsstab","fraction":"OPFOR","timestamp":{"$date":"2018-03-30T10:50:23.121Z"},"updatedAt":{"$date":"2018-03-30T10:50:23.121Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abe16f98b7488392a623f17"},"sortingNumber":4,"name":"Bravo","fraction":"BLUFOR","timestamp":{"$date":"2018-03-30T10:52:41.396Z"},"updatedAt":{"$date":"2018-03-30T10:52:41.396Z"},"__v":0}
|
|
@ -0,0 +1,2 @@
|
||||||
|
{"_id":{"$oid":"5ab68d42f547ed304064e5f7"},"rankLvl":0,"squadId":{"$oid":"5aba54eaeadcce6332c6a774"},"username":"hardiready","updatedAt":{"$date":"2018-03-27T14:28:04.533Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abd4780396bc0487068be0e"},"rankLvl":0,"squadId":null,"username":"KalleK","timestamp":{"$date":"2018-03-29T20:07:28.960Z"},"updatedAt":{"$date":"2018-03-29T20:07:28.960Z"},"__v":0}
|
|
@ -0,0 +1,2 @@
|
||||||
|
{"_id":{"$oid":"5abf65d83fc5fa349ffd5cbb"},"playersBlufor":4,"playersOpfor":4,"budgetBlufor":4535500,"budgetOpfor":4221250,"endBudgetBlufor":997000,"endBudgetOpfor":512000,"title":"Battle #1","campaign":{"$oid":"5abd55ea9e30a76bfef747d6"},"date":{"$date":"2018-03-19T23:00:00.000Z"},"endDate":{"$date":"2018-03-20T01:30:00.000Z"},"ptBlufor":34,"ptOpfor":25,"timestamp":{"$date":"2018-03-31T10:41:28.451Z"},"updatedAt":{"$date":"2018-03-31T10:41:28.451Z"},"__v":0}
|
||||||
|
{"_id":{"$oid":"5abf65ae3fc5fa349ffd5ca3"},"playersBlufor":4,"playersOpfor":4,"budgetBlufor":4535500,"budgetOpfor":4221250,"endBudgetBlufor":997000,"endBudgetOpfor":512000,"title":"Test Battle #0","campaign":{"$oid":"5abd55ea9e30a76bfef747d6"},"date":{"$date":"2018-03-19T23:00:00.000Z"},"endDate":{"$date":"2018-03-20T01:30:00.000Z"},"ptBlufor":34,"ptOpfor":25,"timestamp":{"$date":"2018-03-31T10:40:46.695Z"},"updatedAt":{"$date":"2018-03-31T10:40:46.695Z"},"__v":0}
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
########### IMPORT EXPORT/SCRIPT FOR DREDD TEST DATA ##############
|
||||||
|
###-------------------------------------------------------------###
|
||||||
|
###------------------- HOW TO USE THIS FILE --------------------###
|
||||||
|
###-------------------------------------------------------------###
|
||||||
|
### 1. start express server with `npm run start-test` ###
|
||||||
|
### 2. import data by executing script: `./populate-data.sh` ###
|
||||||
|
### 3. change data in app as you need for tests ###
|
||||||
|
### 4. export data state with: `./populate-data.sh -m save` ###
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# execute script in its location folder
|
||||||
|
cd $(dirname $0)
|
||||||
|
|
||||||
|
while getopts m:p:d: option
|
||||||
|
do
|
||||||
|
case "${option}"
|
||||||
|
in
|
||||||
|
m) MODE=${OPTARG};;
|
||||||
|
p) PORT=${OPTARG};;
|
||||||
|
d) DATABASE=${OPTARG};;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# array of available collection names
|
||||||
|
col=(app_user awarding campaign decoration logBudget logFlag logKill logPoints logRespawn logRevive logTransport logVehicle player promotion rank squad user war )
|
||||||
|
|
||||||
|
for i in "${col[@]}"
|
||||||
|
do
|
||||||
|
# provide date for restore process, if data import is needed
|
||||||
|
if [ "$MODE" == "save" ]
|
||||||
|
then
|
||||||
|
echo -e "$(date "+%Y-%m-%dT%T.%3N%z")\tTable: ${i}"
|
||||||
|
mongoexport --db ${DATABASE} --port ${PORT} --collection $i --out data/${i}.json;
|
||||||
|
else
|
||||||
|
mongoimport --db ${DATABASE} --port ${PORT} --collection $i --drop --file data/${i}.json
|
||||||
|
fi
|
||||||
|
done
|
|
@ -0,0 +1,37 @@
|
||||||
|
### Get Campaign [GET /campaigns/{id}]
|
||||||
|
|
||||||
|
Get single campaign information
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abd55ea9e30a76bfef747d6` (string, required) - unique id of campaign
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Campaign, fixed-type)
|
||||||
|
|
||||||
|
### Create Campaign [POST /campaigns]
|
||||||
|
|
||||||
|
Create a new campaign
|
||||||
|
|
||||||
|
**Permission: 3**
|
||||||
|
|
||||||
|
+ Request Create new army member (application/json)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ title: `Return To Kessel In A Schmelz` (string, required) - display name of the campaign
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (Campaign, fixed-type)
|
||||||
|
|
||||||
|
### Delete Campaign [DELETE /campaigns/{id}]
|
||||||
|
|
||||||
|
Delete a campaign
|
||||||
|
|
||||||
|
**Permission: 3**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abd58989e30a76bfef747e6` (string, required) - unique id of campaign
|
||||||
|
|
||||||
|
+ Response 204
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
### Get War Logs [GET /logs/{warId}]
|
||||||
|
|
||||||
|
Ge the combined log object, containing all events in collections, for a single war
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ warId: `5abf65ae3fc5fa349ffd5ca3` (string, required) - unique id of the war
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ points (array[LogPoints], required)
|
||||||
|
+ budget (array[LogBudget], required)
|
||||||
|
+ respawn (array[LogRespawn], required)
|
||||||
|
+ revive (array[LogRevive], required)
|
||||||
|
+ kill (array[LogKill], required)
|
||||||
|
+ vehicle (array[LogVehicle], required)
|
||||||
|
+ transport (array[LogTransport], required)
|
||||||
|
+ flag (array[LogFlag], required)
|
|
@ -0,0 +1,34 @@
|
||||||
|
### Get Player Highscore [GET /players/ranking/{campaignId}]
|
||||||
|
|
||||||
|
List highscores for player statistics over all wars of a certain campaign.
|
||||||
|
Every highscore player object contains a field *sum*, representing its order number in the collection
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ campaignId: `5abd55ea9e30a76bfef747d6` (string, required) - unique id of the campaign
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ kill (array[HighscorePlayer],required) - player highscore for kill
|
||||||
|
+ death (array[HighscorePlayer],required) - player highscore for death
|
||||||
|
+ friendlyFire (array[HighscorePlayer],required) - player highscore for friendly fire
|
||||||
|
+ vehicle (array[HighscorePlayer],required) - player highscore for vehicle
|
||||||
|
+ revive (array[HighscorePlayer],required) - player highscore for revive
|
||||||
|
+ respawn (array[HighscorePlayer],required) - player highscore for respawn
|
||||||
|
+ flagTouch (array[HighscorePlayer],required) - player highscore for flag captures
|
||||||
|
|
||||||
|
|
||||||
|
### Get Player Campaign Statistics [GET /players/single/{campaignId}/{playerSteamId}]
|
||||||
|
|
||||||
|
Get statistics for a single player for all wars of a campaign he took part at
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ campaignId: `5abd55ea9e30a76bfef747d6` (string, required) - unique id of the campaign
|
||||||
|
+ playerSteamId: `76561198050321490` (string, required) - STEAM application unique user id of player
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes
|
||||||
|
+ name: `Pumarang` (string, required) - latest used playername
|
||||||
|
+ campaign (Campaign,required) - campaign reflected from request is
|
||||||
|
+ players (array[WarPlayer],required) - collection of player instances in the campaign
|
|
@ -0,0 +1,89 @@
|
||||||
|
### List Wars [GET /wars]
|
||||||
|
|
||||||
|
List all wars, subordinate to their campaign
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (array[WarCampaign], fixed-type)
|
||||||
|
|
||||||
|
### Get War [GET /wars/{id}]
|
||||||
|
|
||||||
|
Retrieve single war data
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abf65ae3fc5fa349ffd5ca3` (string, required) - unique id of the war to fetch
|
||||||
|
|
||||||
|
+ Response 200 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (WarWithPlayers, fixed-type)
|
||||||
|
|
||||||
|
|
||||||
|
### Create War [POST /wars]
|
||||||
|
|
||||||
|
Create a new war
|
||||||
|
|
||||||
|
**Permission: 3**
|
||||||
|
|
||||||
|
*NOTE: First line of the log file sent should be NOT beginning of actual game logs! This might result in unparsable line.*
|
||||||
|
|
||||||
|
+ Request (multipart/form-data; boundary=---BOUNDARY)
|
||||||
|
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="title"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
Battle XY
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="campaign"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
5abd55ea9e30a76bfef747d6
|
||||||
|
-----BOUNDARY
|
||||||
|
Content-Disposition: form-data; name="log"; filename="war_2018_log.rpt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
\
|
||||||
|
2018/03/20, 20:05:43 "[OPT] (Budget) LOG: 0:00:00 --- Startbudget: NATO 4.5355e+006 - CSAT 4.22125e+006"
|
||||||
|
2018/03/20, 20:06:45 "[OPT] (Budget) LOG: 0:01:02 --- NATO alt: 4.5355e+006 - neu: 4.1955e+006 - Differenz: -340000"
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Saxe (WEST) von: Selbstverschulden."
|
||||||
|
2018/03/20, 20:10:11 "[OPT] (Abschuss) LOG: 0:04:28 --- Pumarang (WEST) von: Saxe (WEST)."
|
||||||
|
2018/03/20, 20:10:13 "[OPT] (Budget) LOG: 0:04:30 --- CSAT alt: 2.38425e+006 - neu: 2.32425e+006 - Differenz: -60000"
|
||||||
|
2018/03/20, 20:10:38 "[OPT] (Respawn) LOG: 0:04:55 --- Spieler: Pumarang - Kosten: 3000"
|
||||||
|
2018/03/20, 20:15:54 "[OPT] (Punkte) LOG: 0:10:11 --- Kein Dominator (NATO 0 | CSAT 0)"
|
||||||
|
2018/03/20, 20:17:51 "[OPT] (Abschuss) LOG: 0:12:08 --- patze (EAST) von: Wiesl (WEST)."
|
||||||
|
2018/03/20, 20:18:20 "[OPT] (Fahne) LOG: 0:12:37 --- CSAT Flagge erobert von Wiesl"
|
||||||
|
2018/03/20, 20:18:38 "[OPT] (Abschuss) LOG: 0:12:55 --- Nicolas (WEST) von: Wiesl (WEST)."
|
||||||
|
2018/03/20, 20:18:59 "[OPT] (Punkte) LOG: 0:13:16 --- NATO +1 (NATO 1 | CSAT 0)"
|
||||||
|
2018/03/20, 20:19:38 "[OPT] (Fahne) LOG: 0:13:56 --- CSAT Flagge gesichert von ALASTOR"
|
||||||
|
2018/03/20, 20:22:18 "[OPT] (Abschuss) LOG: 0:16:35 --- Fahrzeug: Hunter-HMG (OPT_NATO) von: Murda]X[ (EAST)."
|
||||||
|
2018/03/20, 20:37:19 "[OPT] (Transport) LOG: 0:31:36 --- Dominik (WEST) wurde von Ponykloete (WEST) eingeflogen (8666.94 m)"
|
||||||
|
2018/03/20, 20:41:27 "[OPT] (Revive) LOG: 0:35:44 --- Bodochecker (EAST) wurde von ALASTOR (EAST) stabilisiert."
|
||||||
|
2018/03/20, 20:41:35 "[OPT] (Revive) LOG: 0:35:52 --- Andi-de (WEST) wurde von Wiesl (WEST) wiederbelebt."
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Mission) LOG: 2:30:00 --- Missionzeit abgelaufen"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Pumarang (WEST), PUID 76561198050321485"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Mercurat (WEST), PUID 76561198278842491"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- KalleK (EAST), PUID 76561197977676036"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- MAPster (EAST), PUID 76561198009882133"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- LyrikEmu (WEST), PUID 76561198218910400"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Philipp (EAST), PUID 76561198041792069"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Wiesl (WEST), PUID 76561198059648090"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Fraktionsuebersicht) LOG: 2:30:00 --- Murda]X[ (EAST), PUID 76561197971121630"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Budget) LOG: 2:30:00 --- Endbudget: (NATO 1997000 | CSAT 512000)"
|
||||||
|
2018/03/20, 22:35:43 "[OPT] (Punkte) LOG: 2:30:00 --- Endpunktestand: (NATO 34 | CSAT 25)"
|
||||||
|
-----BOUNDARY--
|
||||||
|
|
||||||
|
+ Response 201 (application/json; charset=utf-8)
|
||||||
|
|
||||||
|
+ Attributes (War, fixed-type)
|
||||||
|
|
||||||
|
### Delete War [DELETE /wars/{id}]
|
||||||
|
|
||||||
|
Delete a war
|
||||||
|
|
||||||
|
**Permission: 3**
|
||||||
|
|
||||||
|
+ Parameters
|
||||||
|
+ id: `5abf65d83fc5fa349ffd5cbb` (string, required) - unique id of the war
|
||||||
|
|
||||||
|
+ Response 204
|
||||||
|
|
|
@ -17,5 +17,5 @@ module.exports = {
|
||||||
signUp: rootRoute + '/authenticate/signup',
|
signUp: rootRoute + '/authenticate/signup',
|
||||||
squads: rootRoute + '/squads',
|
squads: rootRoute + '/squads',
|
||||||
users: rootRoute + '/users',
|
users: rootRoute + '/users',
|
||||||
wars: rootRoute + '/wars'
|
wars: rootRoute + '/wars',
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
port: 8091,
|
port: 8091,
|
||||||
|
resourceLocation: __dirname + '/../resource',
|
||||||
|
|
||||||
database: {
|
database: {
|
||||||
uri: 'mongodb://localhost:27017/',
|
uri: 'mongodb://localhost:27017/',
|
||||||
|
@ -7,17 +8,22 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
prod: {
|
prod: {
|
||||||
env: 'production'
|
env: 'production',
|
||||||
},
|
},
|
||||||
|
|
||||||
dev: {
|
dev: {
|
||||||
env: 'dev'
|
env: 'dev',
|
||||||
},
|
},
|
||||||
|
|
||||||
test: {
|
test: {
|
||||||
port: 3001,
|
|
||||||
db: 'cc-test',
|
db: 'cc-test',
|
||||||
env: 'test'
|
port: 3001,
|
||||||
}
|
dredd: {
|
||||||
|
env: 'dreddTest',
|
||||||
|
resourceLocation: __dirname + '/../apib/dredd/data/tmp-resource',
|
||||||
|
},
|
||||||
|
unit: {
|
||||||
|
env: 'unitTest',
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const cron = require('cron');
|
const cron = require('cron');
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -19,8 +19,8 @@ const createAllSignatures = () => {
|
||||||
// mock response
|
// mock response
|
||||||
const res = {
|
const res = {
|
||||||
locals: {
|
locals: {
|
||||||
items: {}
|
items: {},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// re-create signature image for each active user
|
// re-create signature image for each active user
|
||||||
|
@ -29,21 +29,21 @@ const createAllSignatures = () => {
|
||||||
// mock next to execute callback
|
// mock next to execute callback
|
||||||
const next = (err) => {
|
const next = (err) => {
|
||||||
if (!err || (err && err.message.startsWith('Fraction not defined'))) {
|
if (!err || (err && err.message.startsWith('Fraction not defined'))) {
|
||||||
callback()
|
callback();
|
||||||
} else {
|
} else {
|
||||||
error('\x1b[41m%s\x1b[0m', new Date().toLocaleString()
|
error('\x1b[41m%s\x1b[0m', new Date().toLocaleString()
|
||||||
+ ': Error in execution - UPDATE SIGNATURES: ' + err.message)
|
+ ': Error in execution - UPDATE SIGNATURES: ' + err.message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
signatureTool(user._id, res, next)
|
signatureTool(user._id, res, next);
|
||||||
}, () => {
|
}, () => {
|
||||||
if (err) {
|
if (err) {
|
||||||
error('\x1b[41m%s\x1b[0m', new Date().toLocaleString()
|
error('\x1b[41m%s\x1b[0m', new Date().toLocaleString()
|
||||||
+ ': Error in execution - UPDATE SIGNATURES: ' + err.message)
|
+ ': Error in execution - UPDATE SIGNATURES: ' + err.message);
|
||||||
}
|
}
|
||||||
logger('\x1b[35m%s\x1b[0m', new Date().toLocaleString()
|
logger('\x1b[35m%s\x1b[0m', new Date().toLocaleString()
|
||||||
+ ': finished successful - UPDATE SIGNATURES');
|
+ ': finished successful - UPDATE SIGNATURES');
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ const createBackup = () => {
|
||||||
logger('\x1b[32m%s\x1b[0m', stderr);
|
logger('\x1b[32m%s\x1b[0m', stderr);
|
||||||
logger('\x1b[35m%s\x1b[0m', new Date().toLocaleString()
|
logger('\x1b[35m%s\x1b[0m', new Date().toLocaleString()
|
||||||
+ ': cron job finished - CREATE BACKUP');
|
+ ': cron job finished - CREATE BACKUP');
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Execute daily @ 02:30 AM
|
// Execute daily @ 02:30 AM
|
||||||
|
@ -69,5 +69,5 @@ const cronJobBackup = cron.job('00 00 04 * * mon,thu,sat', createBackup);
|
||||||
module.exports = {
|
module.exports = {
|
||||||
cronJobSignature: cronJobSignature,
|
cronJobSignature: cronJobSignature,
|
||||||
cronJobBackup: cronJobBackup,
|
cronJobBackup: cronJobBackup,
|
||||||
createAllSignatures: createAllSignatures
|
createAllSignatures: createAllSignatures,
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
dry-run: null
|
||||||
|
hookfiles: null
|
||||||
|
language: nodejs
|
||||||
|
sandbox: false
|
||||||
|
server: npm run start-api-test
|
||||||
|
server-wait: 3
|
||||||
|
init: false
|
||||||
|
custom: {}
|
||||||
|
names: false
|
||||||
|
only: []
|
||||||
|
reporter: base
|
||||||
|
output: []
|
||||||
|
header: ['X-Access-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1YWI2OGNlZWY1NDdlZDMwNDA2NGU1ZjYiLCJpYXQiOjE1MjIzNTMwNzAsImV4cCI6MTAyMzIyMzUzMDcwfQ.aC4TYkPc8gYcpdsYNnYcs8D8e6OPilrgSGZF6pI3g1w']
|
||||||
|
sorted: false
|
||||||
|
user: null
|
||||||
|
inline-errors: false
|
||||||
|
details: false
|
||||||
|
method: []
|
||||||
|
color: true
|
||||||
|
level: info
|
||||||
|
timestamp: false
|
||||||
|
silent: false
|
||||||
|
path: []
|
||||||
|
hooks-worker-timeout: 5000
|
||||||
|
hooks-worker-connect-timeout: 1500
|
||||||
|
hooks-worker-connect-retry: 500
|
||||||
|
hooks-worker-after-connect-wait: 100
|
||||||
|
hooks-worker-term-timeout: 5000
|
||||||
|
hooks-worker-term-retry: 500
|
||||||
|
hooks-worker-handler-host: 127.0.0.1
|
||||||
|
hooks-worker-handler-port: 61321
|
||||||
|
config: ./dredd.yml
|
||||||
|
blueprint: ./apib/documentation.apib
|
||||||
|
endpoint: 'http://localhost:3001/api'
|
|
@ -1,17 +1,15 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const config = require('../config/config');
|
const config = require('../config/config');
|
||||||
const AppUser = require('../models/app-user');
|
const AppUser = require('../models/app-user');
|
||||||
|
|
||||||
const apiAuthentication = (req, res, next) => {
|
const apiAuthentication = (req, res, next) => {
|
||||||
|
|
||||||
// check header or url parameters or post parameters for token
|
// check header or url parameters or post parameters for token
|
||||||
const token = req.body.token || req.query.token || req.headers['x-access-token'];
|
const token = req.body.token || req.query.token || req.headers['x-access-token'];
|
||||||
|
|
||||||
// decode token
|
// decode token
|
||||||
if (token) {
|
if (token) {
|
||||||
|
|
||||||
const secret = process.env.NODE_ENV === config.prod.env ? process.env.JWS_SECRET : 'dev-secret';
|
const secret = process.env.NODE_ENV === config.prod.env ? process.env.JWS_SECRET : 'dev-secret';
|
||||||
|
|
||||||
// verifies secret and checks exp
|
// verifies secret and checks exp
|
||||||
|
@ -25,7 +23,7 @@ const apiAuthentication = (req, res, next) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(403).send({
|
return res.status(403).send({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'token is not associated to any actual user'
|
message: 'token is not associated to any actual user',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
req.user = item;
|
req.user = item;
|
||||||
|
@ -33,16 +31,13 @@ const apiAuthentication = (req, res, next) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// if there is no token
|
// if there is no token
|
||||||
// return an error
|
// return an error
|
||||||
return res.status(403).send({
|
return res.status(403).send({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'No token provided.'
|
message: 'No token provided.',
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
/** This module provides middleware to respond with proper JSON error objects
|
/** This module provides middleware to respond with proper JSON error objects
|
||||||
* using NODE_ENV setting to production or development. In dev mode it send the stacktrace.
|
* using NODE_ENV setting to production or development. In dev mode it send the stacktrace.
|
||||||
*
|
*
|
||||||
* You call the returned function with an app instance
|
* You call the returned function with an app instance
|
||||||
*
|
*
|
||||||
* @author Johannes Konert
|
* @author Johannes Konert
|
||||||
* @licence CC BY-SA 4.0
|
* @licence CC BY-SA 4.0
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @module restapi/error-response
|
* @module restapi/error-response
|
||||||
* @type {Function}
|
* @type {Function}
|
||||||
*/
|
*/
|
||||||
"use strict";
|
'use strict';
|
||||||
const logger = require('debug')('me2:error-response');
|
const logger = require('debug')('me2:error-response');
|
||||||
|
|
||||||
module.exports = (app) => {
|
module.exports = (app) => {
|
||||||
// development error handler
|
// development error handler
|
||||||
// will print stacktrace as JSON response
|
// will print stacktrace as JSON response
|
||||||
if (app.get('env') === 'development') {
|
if (app.get('env') === 'development') {
|
||||||
app.use(function (err, req, res, next) {
|
app.use(function(err, req, res, next) {
|
||||||
logger('Internal Error: ', err.stack);
|
logger('Internal Error: ', err.stack);
|
||||||
res.status(err.status || 500);
|
res.status(err.status || 500);
|
||||||
res.json({
|
res.json({
|
||||||
error: {
|
error: {
|
||||||
message: err.message,
|
message: err.message,
|
||||||
error: err.stack
|
error: err.stack,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// production error handler
|
// production error handler
|
||||||
// no stacktraces leaked to user
|
// no stacktraces leaked to user
|
||||||
app.use(function (err, req, res, next) {
|
app.use(function(err, req, res, next) {
|
||||||
res.status(err.status || 500);
|
res.status(err.status || 500);
|
||||||
res.json({
|
res.json({
|
||||||
error: {
|
error: {
|
||||||
message: err.message,
|
message: err.message,
|
||||||
error: {}
|
error: {},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,104 +1,105 @@
|
||||||
/** This module defines a express.Router() instance
|
/** This module defines a express.Router() instance
|
||||||
* - supporting filter=key1,key2
|
* - supporting filter=key1,key2
|
||||||
* - it sets res.locals.filter to a string "key1 key2"
|
* - it sets res.locals.filter to a string "key1 key2"
|
||||||
* - calls next with error if a filter=key is given, but key does not exist (not raised on empty item arrays!)
|
* - calls next with error if a filter=key is given, but key does not exist (not raised on empty item arrays!)
|
||||||
*
|
*
|
||||||
* Note: it expects to be called before any data is fetched from DB
|
* Note: it expects to be called before any data is fetched from DB
|
||||||
* Note: it sets an Error-Object to next with error.status set to HTTP status code 400
|
* Note: it sets an Error-Object to next with error.status set to HTTP status code 400
|
||||||
*
|
*
|
||||||
* @author Johannes Konert
|
* @author Johannes Konert
|
||||||
* @licence CC BY-SA 4.0
|
* @licence CC BY-SA 4.0
|
||||||
*
|
*
|
||||||
* @module restapi/filter-middleware-mongo
|
* @module restapi/filter-middleware-mongo
|
||||||
* @type {Factory function returning an Router}
|
* @type {Factory function returning an Router}
|
||||||
* @param Schema {Object} a MongooseSchema.path value or similar object with attributes representing the valid keys
|
* @param Schema {Object} a MongooseSchema.path value or similar object with attributes representing the valid keys
|
||||||
* @param suppressId {Boolean} if true, the _id is not returned implicitly
|
* @param suppressId {Boolean} if true, the _id is not returned implicitly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// remember: in modules you have 3 variables given by CommonJS
|
// remember: in modules you have 3 variables given by CommonJS
|
||||||
// 1.) require() function
|
// 1.) require() function
|
||||||
// 2.) module.exports
|
// 2.) module.exports
|
||||||
// 3.) exports (which is module.exports)
|
// 3.) exports (which is module.exports)
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const logger = require('debug')('middleware:filterware');
|
const logger = require('debug')('middleware:filterware');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* private helper function to filter Objects by given keys
|
* private helper function to filter Objects by given keys
|
||||||
* @param keys {Array} the keys from GET parameter filter
|
*
|
||||||
* @param schema [Object} containing the keys as attributes that are allowed
|
* @param {Array} keys - the keys from GET parameter filter
|
||||||
* @returns {Object or Error} either the filtered items or an Error object
|
* @param {Object} schema - containing the keys as attributes that are allowed
|
||||||
*/
|
* @return {Object} either the filtered items or an Error object
|
||||||
const limitFilterToSchema = (keys, schema) => {
|
*/
|
||||||
if (!keys || !schema) { // empty arrays evaluate to false
|
const limitFilterToSchema = (keys, schema) => {
|
||||||
return undefined; // means no filter at all
|
if (!keys || !schema) { // empty arrays evaluate to false
|
||||||
}
|
return undefined; // means no filter at all
|
||||||
|
}
|
||||||
let error = null;
|
|
||||||
const result = [];
|
let error = null;
|
||||||
// now for each given filter=key1,key2in the array check that the schema allows this key and store it in result
|
const result = [];
|
||||||
keys.forEach((key) => {
|
// now for each given filter=key1,key2in the array check that the schema allows this key and store it in result
|
||||||
if (schema.hasOwnProperty(key)) {
|
keys.forEach((key) => {
|
||||||
result.push(key);
|
if (schema.hasOwnProperty(key)) {
|
||||||
} else {
|
result.push(key);
|
||||||
error = new Error('given key for filter does not exist in ressource: ' + key);
|
} else {
|
||||||
}
|
error = new Error('given key for filter does not exist in ressource: ' + key);
|
||||||
});
|
}
|
||||||
return error ? error : result
|
});
|
||||||
};
|
return error ? error : result;
|
||||||
|
};
|
||||||
/**
|
|
||||||
* closure function as factory returning the router
|
/**
|
||||||
*
|
* closure function as factory returning the router
|
||||||
* @param Schema {Object} a MongooseSchema.path value or similar object with attributes representing the valid keys
|
*
|
||||||
* @param suppressId {Boolean} if true, the _id is not returned implicitly
|
* @param Schema {Object} a MongooseSchema.path value or similar object with attributes representing the valid keys
|
||||||
* @returns {Router}
|
* @param suppressId {Boolean} if true, the _id is not returned implicitly
|
||||||
*/
|
* @returns {Router}
|
||||||
|
*/
|
||||||
const createFilterRouter = (schema, supressID) => {
|
|
||||||
const router = express.Router();
|
const createFilterRouter = (schema, supressID) => {
|
||||||
// the exported router with handler
|
const router = new express.Router();
|
||||||
router.use((req, res, next) => {
|
// the exported router with handler
|
||||||
const filterString = req.query.filter;
|
router.use((req, res, next) => {
|
||||||
let filterKeys = [];
|
const filterString = req.query.filter;
|
||||||
let err = null;
|
let filterKeys = [];
|
||||||
|
let err = null;
|
||||||
if (filterString !== undefined) {
|
|
||||||
filterKeys = filterString.split(',');
|
if (filterString !== undefined) {
|
||||||
filterKeys.forEach((item, index, array) => {
|
filterKeys = filterString.split(',');
|
||||||
array[index] = item.trim();
|
filterKeys.forEach((item, index, array) => {
|
||||||
});
|
array[index] = item.trim();
|
||||||
filterKeys = filterKeys.filter((item) => {
|
});
|
||||||
return item.length > 0;
|
filterKeys = filterKeys.filter((item) => {
|
||||||
});
|
return item.length > 0;
|
||||||
if (filterKeys.length === 0) {
|
});
|
||||||
err = new Error('given filter does not contain any keys');
|
if (filterKeys.length === 0) {
|
||||||
err.status = 400;
|
err = new Error('given filter does not contain any keys');
|
||||||
} else {
|
err.status = 400;
|
||||||
const result = limitFilterToSchema(filterKeys, schema);
|
} else {
|
||||||
if (result instanceof Error) {
|
const result = limitFilterToSchema(filterKeys, schema);
|
||||||
err = result;
|
if (result instanceof Error) {
|
||||||
err.status = 400;
|
err = result;
|
||||||
} else {
|
err.status = 400;
|
||||||
res.locals.filter = result.join(' '); // create a string with space as seperator
|
} else {
|
||||||
if (supressID) {
|
res.locals.filter = result.join(' '); // create a string with space as seperator
|
||||||
res.locals.filter = '-_id ' + res.locals.filter;
|
if (supressID) {
|
||||||
}
|
res.locals.filter = '-_id ' + res.locals.filter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (err) {
|
}
|
||||||
logger(err);
|
if (err) {
|
||||||
next(err)
|
logger(err);
|
||||||
} else {
|
next(err);
|
||||||
if (res.locals.filter) {
|
} else {
|
||||||
logger('Successfully set filter to ' + res.locals.filter);
|
if (res.locals.filter) {
|
||||||
}
|
logger('Successfully set filter to ' + res.locals.filter);
|
||||||
next()
|
}
|
||||||
}
|
next();
|
||||||
});
|
}
|
||||||
return router;
|
});
|
||||||
};
|
return router;
|
||||||
|
};
|
||||||
module.exports = createFilterRouter;
|
|
||||||
|
module.exports = createFilterRouter;
|
||||||
|
|
|
@ -17,9 +17,10 @@
|
||||||
// 1.) require() function
|
// 1.) require() function
|
||||||
// 2.) module.exports
|
// 2.) module.exports
|
||||||
// 3.) exports (which is module.exports)
|
// 3.) exports (which is module.exports)
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const router = require('express').Router();
|
const express = require('express');
|
||||||
|
const router = new express.Router();
|
||||||
const logger = require('debug')('middleware:offsetlimit');
|
const logger = require('debug')('middleware:offsetlimit');
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,10 +37,9 @@ router.use((req, res, next) => {
|
||||||
if (!isNaN(offsetString)) {
|
if (!isNaN(offsetString)) {
|
||||||
offset = parseInt(offsetString);
|
offset = parseInt(offsetString);
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
err = new Error('offset is negative')
|
err = new Error('offset is negative');
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
err = new Error('given offset is not a valid number ' + offsetString);
|
err = new Error('given offset is not a valid number ' + offsetString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,22 +47,21 @@ router.use((req, res, next) => {
|
||||||
if (!isNaN(limitString)) {
|
if (!isNaN(limitString)) {
|
||||||
limit = parseInt(limitString);
|
limit = parseInt(limitString);
|
||||||
if (limit < 1) {
|
if (limit < 1) {
|
||||||
err = new Error('limit is zero or negative')
|
err = new Error('limit is zero or negative');
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
err = new Error('given limit is not a valid number ' + limitString);
|
err = new Error('given limit is not a valid number ' + limitString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
logger('problem occurred with limit/offset values');
|
logger('problem occurred with limit/offset values');
|
||||||
err.status = 400;
|
err.status = 400;
|
||||||
next(err)
|
next(err);
|
||||||
} else {
|
} else {
|
||||||
res.locals.limitskip = {}; // mongoDB uses parameter object for skip/limit
|
res.locals.limitskip = {}; // mongoDB uses parameter object for skip/limit
|
||||||
if (limit) res.locals.limitskip.limit = limit;
|
if (limit) res.locals.limitskip.limit = limit;
|
||||||
if (offset) res.locals.limitskip.skip = offset;
|
if (offset) res.locals.limitskip.skip = offset;
|
||||||
next()
|
next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
let check = (requiredPermission, actualPermission, res, next) => {
|
let check = (requiredPermission, actualPermission, res, next) => {
|
||||||
|
@ -7,21 +7,21 @@ let check = (requiredPermission, actualPermission, res, next) => {
|
||||||
}
|
}
|
||||||
return res.status(403).send({
|
return res.status(403).send({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'permission denied'
|
message: 'permission denied',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
checkSql: (req, res, next) => {
|
checkSql: (req, res, next) => {
|
||||||
check(1, req.user.permission, res, next)
|
check(1, req.user.permission, res, next);
|
||||||
},
|
},
|
||||||
checkHl: (req, res, next) => {
|
checkHl: (req, res, next) => {
|
||||||
check(2, req.user.permission, res, next)
|
check(2, req.user.permission, res, next);
|
||||||
},
|
},
|
||||||
checkMT: (req, res, next) => {
|
checkMT: (req, res, next) => {
|
||||||
check(3, req.user.permission, res, next)
|
check(3, req.user.permission, res, next);
|
||||||
},
|
},
|
||||||
checkAdmin: (req, res, next) => {
|
checkAdmin: (req, res, next) => {
|
||||||
check(4, req.user.permission, res, next)
|
check(4, req.user.permission, res, next);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,67 +1,67 @@
|
||||||
/** This module defines a express.Router() instance
|
/** This module defines a express.Router() instance
|
||||||
* - checking Accept-Version header to be 1.0
|
* - checking Accept-Version header to be 1.0
|
||||||
* - body-data to be JSON on POST/PUT/PATCH
|
* - body-data to be JSON on POST/PUT/PATCH
|
||||||
* - body to be not empty on POST/PUT/PATCH
|
* - body to be not empty on POST/PUT/PATCH
|
||||||
* - Request accepts JSOn as reply content-type
|
* - Request accepts JSOn as reply content-type
|
||||||
*
|
*
|
||||||
* @author Johannes Konert
|
* @author Johannes Konert
|
||||||
* @licence CC BY-SA 4.0
|
* @licence CC BY-SA 4.0
|
||||||
*
|
*
|
||||||
* @module restapi/request-checks
|
* @module restapi/request-checks
|
||||||
* @type {Router}
|
* @type {Router}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// remember: in modules you have 3 variables given by CommonJS
|
// remember: in modules you have 3 variables given by CommonJS
|
||||||
// 1.) require() function
|
// 1.) require() function
|
||||||
// 2.) module.exports
|
// 2.) module.exports
|
||||||
// 3.) exports (which is module.exports)
|
// 3.) exports (which is module.exports)
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const router = require('express').Router();
|
const express = require('express');
|
||||||
|
const router = new express.Router();
|
||||||
// API-Version control. We use HTTP Header field Accept-Version instead of URL-part /v1/
|
|
||||||
router.use((req, res, next) => {
|
// API-Version control. We use HTTP Header field Accept-Version instead of URL-part /v1/
|
||||||
// expect the Accept-Version header to be NOT set or being 1.0
|
router.use((req, res, next) => {
|
||||||
const versionWanted = req.get('Accept-Version');
|
// expect the Accept-Version header to be NOT set or being 1.0
|
||||||
if (versionWanted !== undefined && versionWanted !== '1.0') {
|
const versionWanted = req.get('Accept-Version');
|
||||||
// 406 Accept-* header cannot be fulfilled.
|
if (versionWanted !== undefined && versionWanted !== '1.0') {
|
||||||
res.status(406).send('Accept-Version cannot be fulfilled').end();
|
// 406 Accept-* header cannot be fulfilled.
|
||||||
} else {
|
res.status(406).send('Accept-Version cannot be fulfilled').end();
|
||||||
next(); // all OK, call next handler
|
} else {
|
||||||
}
|
next(); // all OK, call next handler
|
||||||
});
|
}
|
||||||
|
});
|
||||||
// request type application/json check
|
|
||||||
router.use((req, res, next) => {
|
// request type application/json check
|
||||||
if (['POST', 'PUT', 'PATCH'].indexOf(req.method) > -1 &&
|
router.use((req, res, next) => {
|
||||||
(!(/multipart\/form-data/.test(req.get('Content-Type'))) &&
|
if (['POST', 'PUT', 'PATCH'].indexOf(req.method) > -1 &&
|
||||||
!(/application\/json/.test(req.get('Content-Type'))))) {
|
(!(/multipart\/form-data/.test(req.get('Content-Type'))) &&
|
||||||
// send error code 415: unsupported media type
|
!(/application\/json/.test(req.get('Content-Type'))))) {
|
||||||
res.status(415).send('wrong Content-Type'); // user has SEND the wrong type
|
// send error code 415: unsupported media type
|
||||||
} else if (!req.accepts('json')) {
|
res.status(415).send('wrong Content-Type'); // user has SEND the wrong type
|
||||||
// send 406 that response will be application/json and request does not support it by now as answer
|
} else if (!req.accepts('json')) {
|
||||||
// user has REQUESTED the wrong type
|
// send 406 that response will be application/json and request does not support it by now as answer
|
||||||
res.status(406).send('response of application/json only supported, please accept this');
|
// user has REQUESTED the wrong type
|
||||||
}
|
res.status(406).send('response of application/json only supported, please accept this');
|
||||||
else {
|
} else {
|
||||||
next(); // let this request pass through as it is OK
|
next(); // let this request pass through as it is OK
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// request POST, PUT check that any content was send
|
// request POST, PUT check that any content was send
|
||||||
router.use((req, res, next) => {
|
router.use((req, res, next) => {
|
||||||
let err = undefined;
|
let err = undefined;
|
||||||
if (['POST', 'PUT', 'PATCH'].indexOf(req.method) > -1 && parseInt(req.get('Content-Length')) === 0) {
|
if (['POST', 'PUT', 'PATCH'].indexOf(req.method) > -1 && parseInt(req.get('Content-Length')) === 0) {
|
||||||
err = new Error("content in body is missing");
|
err = new Error('content in body is missing');
|
||||||
err.status = 400;
|
err.status = 400;
|
||||||
next(err);
|
next(err);
|
||||||
} else if ('PUT' === req.method && !(req.body.id || req.body._id)) {
|
} else if ('PUT' === req.method && !(req.body.id || req.body._id)) {
|
||||||
err = new Error("content in body is missing field id");
|
err = new Error('content in body is missing field id');
|
||||||
err.status = 400;
|
err.status = 400;
|
||||||
next(err);
|
next(err);
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const config = require('../config/config');
|
||||||
|
|
||||||
|
const resourceLocation = () => {
|
||||||
|
if (process.env.NODE_ENV === config.test.dredd.env) {
|
||||||
|
return config.test.dredd.resourceLocation;
|
||||||
|
}
|
||||||
|
return config.resourceLocation;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.resourceLocation = resourceLocation;
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
// HTTP status codes by name
|
// HTTP status codes by name
|
||||||
const codes = require('../routes/http-codes');
|
const codes = require('../routes/http-codes');
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
// HTTP status codes by name
|
// HTTP status codes by name
|
||||||
const codes = require('../routes/http-codes');
|
const codes = require('../routes/http-codes');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if id has valid UUID format
|
* check if id has valid UUID format
|
||||||
|
*
|
||||||
|
* @param {object} req
|
||||||
|
* @param {function} res
|
||||||
|
* @param {function} next
|
||||||
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
const idValidator = (req, res, next) => {
|
const idValidator = (req, res, next) => {
|
||||||
const reqId = req.params.id;
|
const reqId = req.params.id;
|
||||||
|
|
||||||
if (!reqId.match(/^[0-9a-fA-F]{24}$/)) {
|
if (!reqId.match(/^[0-9a-fA-F]{24}$/)) {
|
||||||
const err = new Error("Invalid request id format");
|
const err = new Error('Invalid request id format');
|
||||||
err.status = codes.notfound;
|
err.status = codes.notfound;
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,36 +7,36 @@ const AppUserSchema = new Schema({
|
||||||
username: {
|
username: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
unique: true
|
unique: true,
|
||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
squad: {
|
squad: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'Squad',
|
ref: 'Squad',
|
||||||
default: null
|
default: null,
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 4,
|
max: 4,
|
||||||
default: 0
|
default: 0,
|
||||||
},
|
},
|
||||||
secret: {
|
secret: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
activated: {
|
activated: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'app_user',
|
collection: 'app_user',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
AppUserSchema.index({timestamp: 1});
|
AppUserSchema.index({timestamp: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -6,39 +6,39 @@ const Schema = mongoose.Schema;
|
||||||
const AwardingSchema = new Schema({
|
const AwardingSchema = new Schema({
|
||||||
userId: {
|
userId: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'User'
|
ref: 'User',
|
||||||
},
|
},
|
||||||
decorationId: {
|
decorationId: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'Decoration'
|
ref: 'Decoration',
|
||||||
},
|
},
|
||||||
reason: {
|
reason: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
proposer: {
|
proposer: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'AppUser',
|
ref: 'AppUser',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
confirmed: {
|
confirmed: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 2,
|
max: 2,
|
||||||
default: 0
|
default: 0,
|
||||||
},
|
},
|
||||||
rejectReason: {
|
rejectReason: {
|
||||||
type: String
|
type: String,
|
||||||
},
|
},
|
||||||
date: {
|
date: {
|
||||||
type: Date,
|
type: Date,
|
||||||
default: Date.now()
|
default: Date.now(),
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'awarding',
|
collection: 'awarding',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
AwardingSchema.index({timestamp: 1});
|
AwardingSchema.index({timestamp: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -6,11 +6,11 @@ const Schema = mongoose.Schema;
|
||||||
const CampaignSchema = new Schema({
|
const CampaignSchema = new Schema({
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'campaign',
|
collection: 'campaign',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
CampaignSchema.index({timestamp: 1});
|
CampaignSchema.index({timestamp: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -6,27 +6,27 @@ const Schema = mongoose.Schema;
|
||||||
const DecorationSchema = new Schema({
|
const DecorationSchema = new Schema({
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR', 'GLOBAL'],
|
enum: ['BLUFOR', 'OPFOR', 'GLOBAL'],
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
sortingNumber: {
|
sortingNumber: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
default: 0
|
default: 0,
|
||||||
},
|
},
|
||||||
isMedal: {type: Boolean, required: true}
|
isMedal: {type: Boolean, required: true},
|
||||||
}, {
|
}, {
|
||||||
collection: 'decoration',
|
collection: 'decoration',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
DecorationSchema.index({timestamp: 1});
|
DecorationSchema.index({timestamp: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,31 +7,31 @@ const LogBudgetSchema = new Schema({
|
||||||
war: {
|
war: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'War',
|
ref: 'War',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR'],
|
enum: ['BLUFOR', 'OPFOR'],
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
oldBudget: {
|
oldBudget: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
newBudget: {
|
newBudget: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logBudget'
|
collection: 'logBudget',
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogBudgetSchema.index({war: 1});
|
LogBudgetSchema.index({war: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,27 +7,27 @@ const LogFlagSchema = new Schema({
|
||||||
war: {
|
war: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'War',
|
ref: 'War',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
player: {
|
player: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
flagFraction: {
|
flagFraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR'],
|
enum: ['BLUFOR', 'OPFOR'],
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
capture: {
|
capture: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logFlag'
|
collection: 'logFlag',
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogFlagSchema.index({war: 1, player: 1});
|
LogFlagSchema.index({war: 1, player: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,30 +7,30 @@ const LogKillSchema = new Schema({
|
||||||
war: {
|
war: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'War',
|
ref: 'War',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
shooter: {
|
shooter: {
|
||||||
type: String
|
type: String,
|
||||||
},
|
},
|
||||||
target: {
|
target: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
friendlyFire: {
|
friendlyFire: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR', 'NONE'],
|
enum: ['BLUFOR', 'OPFOR', 'NONE'],
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logKill'
|
collection: 'logKill',
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogKillSchema.index({war: 1, shooter: 1, target: 1});
|
LogKillSchema.index({war: 1, shooter: 1, target: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,31 +7,31 @@ const LogKillSchema = new Schema({
|
||||||
war: {
|
war: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'War',
|
ref: 'War',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
ptBlufor: {
|
ptBlufor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
ptOpfor: {
|
ptOpfor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR', 'NONE'],
|
enum: ['BLUFOR', 'OPFOR', 'NONE'],
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logPoints'
|
collection: 'logPoints',
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogKillSchema.index({war: 1, shooter: 1, target: 1});
|
LogKillSchema.index({war: 1, shooter: 1, target: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,18 +7,18 @@ const LogRespawnSchema = new Schema({
|
||||||
war: {
|
war: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'War',
|
ref: 'War',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
player: {
|
player: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logRespawn'
|
collection: 'logRespawn',
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogRespawnSchema.index({war: 1, player: 1});
|
LogRespawnSchema.index({war: 1, player: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,31 +7,31 @@ const LogReviveSchema = new Schema({
|
||||||
war: {
|
war: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'War',
|
ref: 'War',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
medic: {
|
medic: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
patient: {
|
patient: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
stabilized: {
|
stabilized: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR'],
|
enum: ['BLUFOR', 'OPFOR'],
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logRevive'
|
collection: 'logRevive',
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogReviveSchema.index({war: 1, medic: 1});
|
LogReviveSchema.index({war: 1, medic: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,33 +7,33 @@ const LogTransportSchema = new Schema({
|
||||||
war: {
|
war: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'War',
|
ref: 'War',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
driver: {
|
driver: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
passenger: {
|
passenger: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
distance: {
|
distance: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR'],
|
enum: ['BLUFOR', 'OPFOR'],
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logTransport'
|
collection: 'logTransport',
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogTransportSchema.index({war: 1, driver: 1});
|
LogTransportSchema.index({war: 1, driver: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,26 +7,26 @@ const LogVehicleKillSchema = new Schema({
|
||||||
war: {
|
war: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'War',
|
ref: 'War',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
time: {
|
time: {
|
||||||
type: Date,
|
type: Date,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
shooter: {
|
shooter: {
|
||||||
type: String
|
type: String,
|
||||||
},
|
},
|
||||||
target: {
|
target: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR', 'NONE'],
|
enum: ['BLUFOR', 'OPFOR', 'NONE'],
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'logVehicle'
|
collection: 'logVehicle',
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
LogVehicleKillSchema.index({war: 1, shooter: 1, target: 1});
|
LogVehicleKillSchema.index({war: 1, shooter: 1, target: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -6,73 +6,73 @@ const Schema = mongoose.Schema;
|
||||||
const PlayerSchema = new Schema({
|
const PlayerSchema = new Schema({
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR'],
|
enum: ['BLUFOR', 'OPFOR'],
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
warId: {
|
warId: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'War',
|
ref: 'War',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
kill: {
|
kill: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
vehicle: {
|
vehicle: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
death: {
|
death: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
friendlyFire: {
|
friendlyFire: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
revive: {
|
revive: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
respawn: {
|
respawn: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
flagTouch: {
|
flagTouch: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
sort: {
|
sort: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v)
|
set: (v) => Math.round(v),
|
||||||
},
|
},
|
||||||
steamUUID: {
|
steamUUID: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v)
|
set: (v) => Math.round(v),
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'player',
|
collection: 'player',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
PlayerSchema.index({warId: 1});
|
PlayerSchema.index({warId: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -6,39 +6,39 @@ const Schema = mongoose.Schema;
|
||||||
const PromotionSchema = new Schema({
|
const PromotionSchema = new Schema({
|
||||||
userId: {
|
userId: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'User'
|
ref: 'User',
|
||||||
},
|
},
|
||||||
proposer: {
|
proposer: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'AppUser',
|
ref: 'AppUser',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
oldRankLvl: {
|
oldRankLvl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
newRankLvl: {
|
newRankLvl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
confirmed: {
|
confirmed: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 2,
|
max: 2,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
rejectReason: {
|
rejectReason: {
|
||||||
type: String
|
type: String,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'promotion',
|
collection: 'promotion',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
PromotionSchema.index({timestamp: 1});
|
PromotionSchema.index({timestamp: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -6,22 +6,22 @@ const Schema = mongoose.Schema;
|
||||||
const RankSchema = new Schema({
|
const RankSchema = new Schema({
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR'],
|
enum: ['BLUFOR', 'OPFOR'],
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
level: {
|
level: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'rank',
|
collection: 'rank',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
RankSchema.index({timestamp: 1});
|
RankSchema.index({timestamp: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -6,22 +6,22 @@ const Schema = mongoose.Schema;
|
||||||
const SquadSchema = new Schema({
|
const SquadSchema = new Schema({
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
fraction: {
|
fraction: {
|
||||||
type: String,
|
type: String,
|
||||||
enum: ['BLUFOR', 'OPFOR'],
|
enum: ['BLUFOR', 'OPFOR'],
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
sortingNumber: {
|
sortingNumber: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
default: 0
|
default: 0,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'squad',
|
collection: 'squad',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
SquadSchema.index({timestamp: 1});
|
SquadSchema.index({timestamp: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -7,22 +7,22 @@ const UserSchema = new Schema({
|
||||||
username: {
|
username: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
unique: true
|
unique: true,
|
||||||
},
|
},
|
||||||
rankLvl: {
|
rankLvl: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
default: 0
|
default: 0,
|
||||||
},
|
},
|
||||||
squadId: {
|
squadId: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'Squad',
|
ref: 'Squad',
|
||||||
default: null
|
default: null,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'user',
|
collection: 'user',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
UserSchema.index({timestamp: 1});
|
UserSchema.index({timestamp: 1});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict";
|
'use strict';
|
||||||
|
|
||||||
const mongoose = require('mongoose');
|
const mongoose = require('mongoose');
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
@ -6,7 +6,7 @@ const Schema = mongoose.Schema;
|
||||||
const WarSchema = new Schema({
|
const WarSchema = new Schema({
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
date: {
|
date: {
|
||||||
type: Date,
|
type: Date,
|
||||||
|
@ -16,58 +16,58 @@ const WarSchema = new Schema({
|
||||||
},
|
},
|
||||||
ptBlufor: {
|
ptBlufor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
},
|
},
|
||||||
ptOpfor: {
|
ptOpfor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
},
|
},
|
||||||
playersBlufor: {
|
playersBlufor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
default: 0
|
default: 0,
|
||||||
},
|
},
|
||||||
playersOpfor: {
|
playersOpfor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
default: 0
|
default: 0,
|
||||||
},
|
},
|
||||||
campaign: {
|
campaign: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'Campaign',
|
ref: 'Campaign',
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
budgetBlufor: {
|
budgetBlufor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
default: 0
|
default: 0,
|
||||||
},
|
},
|
||||||
budgetOpfor: {
|
budgetOpfor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
default: 0
|
default: 0,
|
||||||
},
|
},
|
||||||
endBudgetBlufor: {
|
endBudgetBlufor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
default: 0
|
default: 0,
|
||||||
},
|
},
|
||||||
endBudgetOpfor: {
|
endBudgetOpfor: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: (v) => Math.round(v),
|
||||||
set: v => Math.round(v),
|
set: (v) => Math.round(v),
|
||||||
default: 0
|
default: 0,
|
||||||
}
|
},
|
||||||
}, {
|
}, {
|
||||||
collection: 'war',
|
collection: 'war',
|
||||||
timestamps: {createdAt: 'timestamp'}
|
timestamps: {createdAt: 'timestamp'},
|
||||||
});
|
});
|
||||||
// optional more indices
|
// optional more indices
|
||||||
WarSchema.index({timestamp: 1});
|
WarSchema.index({timestamp: 1});
|
||||||
|
|