mirror of
https://codeberg.org/timelimit/timelimit-server.git
synced 2026-08-31 19:03:45 +02:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c711845e6f | ||
|
|
6d635b7e25 | ||
|
|
7c65aba589 | ||
|
|
b148492d59 | ||
|
|
f028b99bbc | ||
|
|
b43059f8e2 | ||
|
|
5825ac617f | ||
|
|
387d4cd53c | ||
|
|
e1bbff7e07 |
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules
|
||||||
|
build
|
||||||
|
scripts
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
plugins: [
|
||||||
|
'@typescript-eslint',
|
||||||
|
],
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
],
|
||||||
|
env: {
|
||||||
|
node: true
|
||||||
|
}
|
||||||
|
};
|
||||||
+1
-1
@@ -5,7 +5,7 @@ RUN mkdir -p /usr/src/app
|
|||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
# Install app dependencies
|
# Install app dependencies
|
||||||
COPY package.json package-lock.json tsconfig.json tslint.json Readme.md /usr/src/app/
|
COPY package.json package-lock.json tsconfig.json .eslintignore .eslintrc.js Readme.md /usr/src/app/
|
||||||
COPY src/ /usr/src/app/src/
|
COPY src/ /usr/src/app/src/
|
||||||
COPY scripts/ /usr/src/app/scripts/
|
COPY scripts/ /usr/src/app/scripts/
|
||||||
COPY other/ /usr/src/app/other/
|
COPY other/ /usr/src/app/other/
|
||||||
|
|||||||
@@ -160,16 +160,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"additionalItems": {
|
"maxItems": 2
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sdl": {
|
"sdl": {
|
||||||
@@ -191,22 +182,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minItems": 4,
|
"minItems": 4,
|
||||||
"additionalItems": {
|
"maxItems": 4
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -343,16 +319,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"additionalItems": {
|
"maxItems": 2
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"updatedOrAdded": {
|
"updatedOrAdded": {
|
||||||
|
|||||||
+2
-2
@@ -18,8 +18,8 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
|
|
||||||
2. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-1.md "check type definition")
|
2. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
## items Constraints
|
## items Constraints
|
||||||
|
|
||||||
|
**maximum number of items**: the maximum number of items for this array is: `2`
|
||||||
|
|
||||||
**minimum number of items**: the minimum number of items for this array is: `2`
|
**minimum number of items**: the minimum number of items for this array is: `2`
|
||||||
|
|||||||
-2
@@ -17,5 +17,3 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
1. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-0.md "check type definition")
|
1. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-0.md "check type definition")
|
||||||
|
|
||||||
2. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-1.md "check type definition")
|
2. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-additionalitems.md "check type definition")
|
|
||||||
|
|||||||
+2
-2
@@ -22,8 +22,8 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
|
|
||||||
4. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-3.md "check type definition")
|
4. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-3.md "check type definition")
|
||||||
|
|
||||||
5. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
## items Constraints
|
## items Constraints
|
||||||
|
|
||||||
|
**maximum number of items**: the maximum number of items for this array is: `4`
|
||||||
|
|
||||||
**minimum number of items**: the minimum number of items for this array is: `4`
|
**minimum number of items**: the minimum number of items for this array is: `4`
|
||||||
|
|||||||
-2
@@ -21,5 +21,3 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
3. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-2.md "check type definition")
|
3. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-2.md "check type definition")
|
||||||
|
|
||||||
4. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-3.md "check type definition")
|
4. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-3.md "check type definition")
|
||||||
|
|
||||||
5. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-additionalitems.md "check type definition")
|
|
||||||
|
|||||||
-8
@@ -92,8 +92,6 @@ https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedAddUsedTime
|
|||||||
|
|
||||||
2. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-1.md "check type definition")
|
2. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
* cannot be null
|
* cannot be null
|
||||||
|
|
||||||
* defined in: [SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as.md "https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedAddUsedTimeActionVersion2/properties/i/items/properties/as")
|
* defined in: [SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as.md "https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedAddUsedTimeActionVersion2/properties/i/items/properties/as")
|
||||||
@@ -106,8 +104,6 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
|
|
||||||
2. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-1.md "check type definition")
|
2. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-as-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
## sdl
|
## sdl
|
||||||
|
|
||||||
|
|
||||||
@@ -126,8 +122,6 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
|
|
||||||
4. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-3.md "check type definition")
|
4. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-3.md "check type definition")
|
||||||
|
|
||||||
5. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
* cannot be null
|
* cannot be null
|
||||||
|
|
||||||
* defined in: [SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl.md "https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedAddUsedTimeActionVersion2/properties/i/items/properties/sdl")
|
* defined in: [SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl.md "https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedAddUsedTimeActionVersion2/properties/i/items/properties/sdl")
|
||||||
@@ -143,5 +137,3 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
3. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-2.md "check type definition")
|
3. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-2.md "check type definition")
|
||||||
|
|
||||||
4. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-3.md "check type definition")
|
4. [Untitled number in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-items-3.md "check type definition")
|
||||||
|
|
||||||
5. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedaddusedtimeactionversion2-properties-i-items-properties-sdl-items-additionalitems.md "check type definition")
|
|
||||||
|
|||||||
+2
-2
@@ -18,8 +18,8 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
|
|
||||||
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
## items Constraints
|
## items Constraints
|
||||||
|
|
||||||
|
**maximum number of items**: the maximum number of items for this array is: `2`
|
||||||
|
|
||||||
**minimum number of items**: the minimum number of items for this array is: `2`
|
**minimum number of items**: the minimum number of items for this array is: `2`
|
||||||
|
|||||||
-2
@@ -17,5 +17,3 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
1. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-0.md "check type definition")
|
1. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-0.md "check type definition")
|
||||||
|
|
||||||
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-additionalitems.md "check type definition")
|
|
||||||
|
|||||||
-4
@@ -62,8 +62,6 @@ https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedUpdateAppAc
|
|||||||
|
|
||||||
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
* cannot be null
|
* cannot be null
|
||||||
|
|
||||||
* defined in: [SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed.md "https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedUpdateAppActivitiesAction/properties/removed")
|
* defined in: [SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed.md "https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedUpdateAppActivitiesAction/properties/removed")
|
||||||
@@ -76,8 +74,6 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
|
|
||||||
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
## updatedOrAdded
|
## updatedOrAdded
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -694,8 +694,6 @@ Reference this group by using
|
|||||||
|
|
||||||
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
* cannot be null
|
* cannot be null
|
||||||
|
|
||||||
* defined in: [SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed.md "https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedUpdateAppActivitiesAction/properties/removed")
|
* defined in: [SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed.md "https://timelimit.io/SerializedAppLogicAction#/definitions/SerializedUpdateAppActivitiesAction/properties/removed")
|
||||||
@@ -708,8 +706,6 @@ an array where each item follows the corresponding schema in the following list:
|
|||||||
|
|
||||||
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
2. [Untitled string in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-items-1.md "check type definition")
|
||||||
|
|
||||||
3. and all following items must follow the schema: [Untitled undefined type in SerializedAppLogicAction](serializedapplogicaction-definitions-serializedupdateappactivitiesaction-properties-removed-items-additionalitems.md "check type definition")
|
|
||||||
|
|
||||||
### updatedOrAdded
|
### updatedOrAdded
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
- default value: 8080
|
- default value: 8080
|
||||||
- NODE_ENV
|
- NODE_ENV
|
||||||
- should be set to ``production`` in production
|
- should be set to ``production`` in production
|
||||||
- when using ``development``, then mails are not sent; instead they are written to a html file which is opened
|
- when using ``development``, then mails are not sent; instead they are print to the console
|
||||||
- GOOGLE_PLAY_PUBLIC_KEY
|
- GOOGLE_PLAY_PUBLIC_KEY
|
||||||
- key for validating purchases
|
- key for validating purchases
|
||||||
- purchases using google play don't work without it/ when it is not set
|
- purchases using google play don't work without it/ when it is not set
|
||||||
|
|||||||
Generated
+15270
-5627
File diff suppressed because it is too large
Load Diff
+11
-10
@@ -6,8 +6,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./build/index.js",
|
"start": "node ./build/index.js",
|
||||||
"test": "node scripts/test-launch-with-different-databases.js",
|
"test": "node scripts/test-launch-with-different-databases.js",
|
||||||
"lint": "tslint --project .",
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
||||||
"lint:fix": "tslint --project . --fix",
|
"lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
|
||||||
"build": "npm run build:clean && npm run build:json && npm run build:ts && npm run lint && npm run build:doc",
|
"build": "npm run build:clean && npm run build:json && npm run build:ts && npm run lint && npm run build:doc",
|
||||||
"build:clean": "rimraf build",
|
"build:clean": "rimraf build",
|
||||||
"build:json": "node ./scripts/build-schemas.js",
|
"build:json": "node ./scripts/build-schemas.js",
|
||||||
@@ -32,18 +32,19 @@
|
|||||||
"@adobe/jsonschema2md": "^6.0.3",
|
"@adobe/jsonschema2md": "^6.0.3",
|
||||||
"@types/basic-auth": "^1.1.3",
|
"@types/basic-auth": "^1.1.3",
|
||||||
"@types/body-parser": "^1.19.0",
|
"@types/body-parser": "^1.19.0",
|
||||||
"@types/email-templates": "^8.0.0",
|
"@types/ejs": "^3.1.0",
|
||||||
"@types/express": "^4.17.9",
|
"@types/express": "^4.17.9",
|
||||||
"@types/http-errors": "^1.8.0",
|
"@types/http-errors": "^1.8.0",
|
||||||
"@types/lodash": "^4.14.166",
|
"@types/lodash": "^4.14.166",
|
||||||
"@types/node": "^14.14.16",
|
"@types/node": "^14.14.16",
|
||||||
"@types/socket.io": "^2.1.12",
|
"@types/nodemailer": "^6.4.4",
|
||||||
"@types/tokgen": "^1.0.0",
|
"@types/tokgen": "^1.0.0",
|
||||||
"@types/umzug": "^2.3.0",
|
"@types/umzug": "^2.3.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||||
|
"@typescript-eslint/parser": "^5.10.0",
|
||||||
|
"eslint": "^8.7.0",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"tslint": "^6.1.3",
|
"typescript": "^4.4.4",
|
||||||
"tslint-config-standard": "^9.0.0",
|
|
||||||
"typescript": "^4.1.3",
|
|
||||||
"typescript-json-schema": "^0.52.0"
|
"typescript-json-schema": "^0.52.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -52,22 +53,22 @@
|
|||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"ejs": "^3.1.5",
|
"ejs": "^3.1.5",
|
||||||
"email-addresses": "^3.1.0",
|
"email-addresses": "^3.1.0",
|
||||||
"email-templates": "^8.0.2",
|
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"http-errors": "^1.8.0",
|
"http-errors": "^1.8.0",
|
||||||
"iab_verifier": "^0.1.2",
|
"iab_verifier": "^0.1.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mariadb": "^2.5.2",
|
"mariadb": "^2.5.2",
|
||||||
|
"nodemailer": "^6.7.2",
|
||||||
"pg": "^8.5.1",
|
"pg": "^8.5.1",
|
||||||
"pg-hstore": "^2.3.3",
|
"pg-hstore": "^2.3.3",
|
||||||
"rate-limiter-flexible": "^2.1.15",
|
"rate-limiter-flexible": "^2.1.15",
|
||||||
"sequelize": "^6.11.0",
|
"sequelize": "^6.11.0",
|
||||||
"socket.io": "^4.0.1",
|
"socket.io": "^4.0.1",
|
||||||
"sqlite3": "^4.0.6",
|
"sqlite3": "^4.0.0",
|
||||||
"tokgen": "^1.0.0",
|
"tokgen": "^1.0.0",
|
||||||
"umzug": "^2.3.0"
|
"umzug": "^2.3.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"sqlite3": "^4.0.6"
|
"sqlite3": "^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ types.forEach((type) => {
|
|||||||
const functionBody = 'ajv.compile(' + schemaString + ')'
|
const functionBody = 'ajv.compile(' + schemaString + ')'
|
||||||
const functionName = 'is' + type.substr(0, 1).toUpperCase() + type.substr(1)
|
const functionName = 'is' + type.substr(0, 1).toUpperCase() + type.substr(1)
|
||||||
|
|
||||||
output += 'export const ' + functionName + ': (value: object) => value is ' + type + ' = ' + functionBody + '\n'
|
output += 'export const ' + functionName + ': (value: unknown) => value is ' + type + ' = ' + functionBody + '\n'
|
||||||
})
|
})
|
||||||
|
|
||||||
allTypes.forEach((type) => {
|
allTypes.forEach((type) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -18,13 +18,11 @@
|
|||||||
import { ChildAction } from './basetypes'
|
import { ChildAction } from './basetypes'
|
||||||
|
|
||||||
export class ChildSignInAction extends ChildAction {
|
export class ChildSignInAction extends ChildAction {
|
||||||
|
static instance = new ChildSignInAction()
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
static parse = (_: SerializedChildSignInAction) => (
|
|
||||||
new ChildSignInAction()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SerializedChildSignInAction {
|
export interface SerializedChildSignInAction {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -23,8 +23,6 @@ export class ForceSyncAction extends AppLogicAction {
|
|||||||
private constructor () {
|
private constructor () {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
static parse = (_: SerializedForceSyncAction) => ForceSyncAction.instance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SerializedForceSyncAction {
|
export interface SerializedForceSyncAction {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -48,13 +48,13 @@ export const parseAppLogicAction = (serialized: SerializedAppLogicAction): AppLo
|
|||||||
} else if (serialized.type === 'ADD_INSTALLED_APPS') {
|
} else if (serialized.type === 'ADD_INSTALLED_APPS') {
|
||||||
return AddInstalledAppsAction.parse(serialized)
|
return AddInstalledAppsAction.parse(serialized)
|
||||||
} else if (serialized.type === 'FORCE_SYNC') {
|
} else if (serialized.type === 'FORCE_SYNC') {
|
||||||
return ForceSyncAction.parse(serialized)
|
return ForceSyncAction.instance
|
||||||
} else if (serialized.type === 'MARK_TASK_PENDING') {
|
} else if (serialized.type === 'MARK_TASK_PENDING') {
|
||||||
return MarkTaskPendingAction.parse(serialized)
|
return MarkTaskPendingAction.parse(serialized)
|
||||||
} else if (serialized.type === 'REMOVE_INSTALLED_APPS') {
|
} else if (serialized.type === 'REMOVE_INSTALLED_APPS') {
|
||||||
return RemoveInstalledAppsAction.parse(serialized)
|
return RemoveInstalledAppsAction.parse(serialized)
|
||||||
} else if (serialized.type === 'SIGN_OUT_AT_DEVICE') {
|
} else if (serialized.type === 'SIGN_OUT_AT_DEVICE') {
|
||||||
return SignOutAtDeviceAction.parse(serialized)
|
return SignOutAtDeviceAction.instance
|
||||||
} else if (serialized.type === 'TRIED_DISABLING_DEVICE_ADMIN') {
|
} else if (serialized.type === 'TRIED_DISABLING_DEVICE_ADMIN') {
|
||||||
return new TriedDisablingDeviceAdminAction()
|
return new TriedDisablingDeviceAdminAction()
|
||||||
} else if (serialized.type === 'UPDATE_APP_ACTIVITIES') {
|
} else if (serialized.type === 'UPDATE_APP_ACTIVITIES') {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -25,7 +25,7 @@ export const parseChildAction = (serialized: SerializedChildAction) => {
|
|||||||
if (serialized.type === 'CHILD_CHANGE_PASSWORD') {
|
if (serialized.type === 'CHILD_CHANGE_PASSWORD') {
|
||||||
return ChildChangePasswordAction.parse(serialized)
|
return ChildChangePasswordAction.parse(serialized)
|
||||||
} else if (serialized.type === 'CHILD_SIGN_IN') {
|
} else if (serialized.type === 'CHILD_SIGN_IN') {
|
||||||
return ChildSignInAction.parse(serialized)
|
return ChildSignInAction.instance
|
||||||
} else {
|
} else {
|
||||||
throw new UnknownActionTypeException({ group: 'child' })
|
throw new UnknownActionTypeException({ group: 'child' })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ export class SignOutAtDeviceAction extends AppLogicAction {
|
|||||||
private constructor () {
|
private constructor () {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
static parse = (_: SerializedSignOutAtDeviceAction) => SignOutAtDeviceAction.instance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SerializedSignOutAtDeviceAction {
|
export interface SerializedSignOutAtDeviceAction {
|
||||||
|
|||||||
+22
-55
@@ -1504,16 +1504,7 @@ const definitions = {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"additionalItems": {
|
"maxItems": 2
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sdl": {
|
"sdl": {
|
||||||
@@ -1535,22 +1526,7 @@ const definitions = {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minItems": 4,
|
"minItems": 4,
|
||||||
"additionalItems": {
|
"maxItems": 4
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1681,16 +1657,7 @@ const definitions = {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"additionalItems": {
|
"maxItems": 2
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"updatedOrAdded": {
|
"updatedOrAdded": {
|
||||||
@@ -2459,7 +2426,7 @@ const definitions = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isClientPushChangesRequest: (value: object) => value is ClientPushChangesRequest = ajv.compile({
|
export const isClientPushChangesRequest: (value: unknown) => value is ClientPushChangesRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"deviceAuthToken": {
|
"deviceAuthToken": {
|
||||||
@@ -2480,7 +2447,7 @@ export const isClientPushChangesRequest: (value: object) => value is ClientPushC
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isClientPullChangesRequest: (value: object) => value is ClientPullChangesRequest = ajv.compile({
|
export const isClientPullChangesRequest: (value: unknown) => value is ClientPullChangesRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"deviceAuthToken": {
|
"deviceAuthToken": {
|
||||||
@@ -2498,7 +2465,7 @@ export const isClientPullChangesRequest: (value: object) => value is ClientPullC
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isMailAuthTokenRequestBody: (value: object) => value is MailAuthTokenRequestBody = ajv.compile({
|
export const isMailAuthTokenRequestBody: (value: unknown) => value is MailAuthTokenRequestBody = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"mailAuthToken": {
|
"mailAuthToken": {
|
||||||
@@ -2512,7 +2479,7 @@ export const isMailAuthTokenRequestBody: (value: object) => value is MailAuthTok
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isCreateFamilyByMailTokenRequest: (value: object) => value is CreateFamilyByMailTokenRequest = ajv.compile({
|
export const isCreateFamilyByMailTokenRequest: (value: unknown) => value is CreateFamilyByMailTokenRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"mailAuthToken": {
|
"mailAuthToken": {
|
||||||
@@ -2546,7 +2513,7 @@ export const isCreateFamilyByMailTokenRequest: (value: object) => value is Creat
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isSignIntoFamilyRequest: (value: object) => value is SignIntoFamilyRequest = ajv.compile({
|
export const isSignIntoFamilyRequest: (value: unknown) => value is SignIntoFamilyRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"mailAuthToken": {
|
"mailAuthToken": {
|
||||||
@@ -2568,7 +2535,7 @@ export const isSignIntoFamilyRequest: (value: object) => value is SignIntoFamily
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isRecoverParentPasswordRequest: (value: object) => value is RecoverParentPasswordRequest = ajv.compile({
|
export const isRecoverParentPasswordRequest: (value: unknown) => value is RecoverParentPasswordRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"mailAuthToken": {
|
"mailAuthToken": {
|
||||||
@@ -2586,7 +2553,7 @@ export const isRecoverParentPasswordRequest: (value: object) => value is Recover
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isRegisterChildDeviceRequest: (value: object) => value is RegisterChildDeviceRequest = ajv.compile({
|
export const isRegisterChildDeviceRequest: (value: unknown) => value is RegisterChildDeviceRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"registerToken": {
|
"registerToken": {
|
||||||
@@ -2608,7 +2575,7 @@ export const isRegisterChildDeviceRequest: (value: object) => value is RegisterC
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isSerializedParentAction: (value: object) => value is SerializedParentAction = ajv.compile({
|
export const isSerializedParentAction: (value: unknown) => value is SerializedParentAction = ajv.compile({
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"$ref": "#/definitions/SerializedAddCategoryAppsAction"
|
"$ref": "#/definitions/SerializedAddCategoryAppsAction"
|
||||||
@@ -2755,7 +2722,7 @@ export const isSerializedParentAction: (value: object) => value is SerializedPar
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isSerializedAppLogicAction: (value: object) => value is SerializedAppLogicAction = ajv.compile({
|
export const isSerializedAppLogicAction: (value: unknown) => value is SerializedAppLogicAction = ajv.compile({
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"$ref": "#/definitions/SerializedAddInstalledAppsAction"
|
"$ref": "#/definitions/SerializedAddInstalledAppsAction"
|
||||||
@@ -2791,7 +2758,7 @@ export const isSerializedAppLogicAction: (value: object) => value is SerializedA
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isSerializedChildAction: (value: object) => value is SerializedChildAction = ajv.compile({
|
export const isSerializedChildAction: (value: unknown) => value is SerializedChildAction = ajv.compile({
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"$ref": "#/definitions/SerializedChildChangePasswordAction"
|
"$ref": "#/definitions/SerializedChildChangePasswordAction"
|
||||||
@@ -2803,7 +2770,7 @@ export const isSerializedChildAction: (value: object) => value is SerializedChil
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isCreateRegisterDeviceTokenRequest: (value: object) => value is CreateRegisterDeviceTokenRequest = ajv.compile({
|
export const isCreateRegisterDeviceTokenRequest: (value: unknown) => value is CreateRegisterDeviceTokenRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"deviceAuthToken": {
|
"deviceAuthToken": {
|
||||||
@@ -2825,7 +2792,7 @@ export const isCreateRegisterDeviceTokenRequest: (value: object) => value is Cre
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isCanDoPurchaseRequest: (value: object) => value is CanDoPurchaseRequest = ajv.compile({
|
export const isCanDoPurchaseRequest: (value: unknown) => value is CanDoPurchaseRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": {
|
"type": {
|
||||||
@@ -2847,7 +2814,7 @@ export const isCanDoPurchaseRequest: (value: object) => value is CanDoPurchaseRe
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isFinishPurchaseByGooglePlayRequest: (value: object) => value is FinishPurchaseByGooglePlayRequest = ajv.compile({
|
export const isFinishPurchaseByGooglePlayRequest: (value: unknown) => value is FinishPurchaseByGooglePlayRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"deviceAuthToken": {
|
"deviceAuthToken": {
|
||||||
@@ -2869,7 +2836,7 @@ export const isFinishPurchaseByGooglePlayRequest: (value: object) => value is Fi
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isLinkParentMailAddressRequest: (value: object) => value is LinkParentMailAddressRequest = ajv.compile({
|
export const isLinkParentMailAddressRequest: (value: unknown) => value is LinkParentMailAddressRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"mailAuthToken": {
|
"mailAuthToken": {
|
||||||
@@ -2895,7 +2862,7 @@ export const isLinkParentMailAddressRequest: (value: object) => value is LinkPar
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isUpdatePrimaryDeviceRequest: (value: object) => value is UpdatePrimaryDeviceRequest = ajv.compile({
|
export const isUpdatePrimaryDeviceRequest: (value: unknown) => value is UpdatePrimaryDeviceRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"action": {
|
"action": {
|
||||||
@@ -2921,7 +2888,7 @@ export const isUpdatePrimaryDeviceRequest: (value: object) => value is UpdatePri
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isRemoveDeviceRequest: (value: object) => value is RemoveDeviceRequest = ajv.compile({
|
export const isRemoveDeviceRequest: (value: unknown) => value is RemoveDeviceRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"deviceAuthToken": {
|
"deviceAuthToken": {
|
||||||
@@ -2947,7 +2914,7 @@ export const isRemoveDeviceRequest: (value: object) => value is RemoveDeviceRequ
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isRequestWithAuthToken: (value: object) => value is RequestWithAuthToken = ajv.compile({
|
export const isRequestWithAuthToken: (value: unknown) => value is RequestWithAuthToken = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"deviceAuthToken": {
|
"deviceAuthToken": {
|
||||||
@@ -2961,7 +2928,7 @@ export const isRequestWithAuthToken: (value: object) => value is RequestWithAuth
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isSendMailLoginCodeRequest: (value: object) => value is SendMailLoginCodeRequest = ajv.compile({
|
export const isSendMailLoginCodeRequest: (value: unknown) => value is SendMailLoginCodeRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"mail": {
|
"mail": {
|
||||||
@@ -2982,7 +2949,7 @@ export const isSendMailLoginCodeRequest: (value: object) => value is SendMailLog
|
|||||||
"definitions": definitions,
|
"definitions": definitions,
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#"
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
})
|
})
|
||||||
export const isSignInByMailCodeRequest: (value: object) => value is SignInByMailCodeRequest = ajv.compile({
|
export const isSignInByMailCodeRequest: (value: unknown) => value is SignInByMailCodeRequest = ajv.compile({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"mailLoginToken": {
|
"mailLoginToken": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -79,12 +79,12 @@ export class VisibleConnectedDevicesManager {
|
|||||||
}): {
|
}): {
|
||||||
shutdown: () => void
|
shutdown: () => void
|
||||||
} => {
|
} => {
|
||||||
let observesDevices = new Set<string>()
|
const observesDevices = new Set<string>()
|
||||||
let devicesWithSharingEnabled = new Set<string>()
|
const devicesWithSharingEnabled = new Set<string>()
|
||||||
let connectedDevices = new Set<string>()
|
const connectedDevices = new Set<string>()
|
||||||
let sentConnectedDevices = new Set<string>()
|
const sentConnectedDevices = new Set<string>()
|
||||||
let hasShutDown = false
|
let hasShutDown = false
|
||||||
let shutdownHooks: Array<() => void> = []
|
const shutdownHooks: Array<() => void> = []
|
||||||
|
|
||||||
const shutdown = () => {
|
const shutdown = () => {
|
||||||
hasShutDown = true
|
hasShutDown = true
|
||||||
@@ -97,7 +97,7 @@ export class VisibleConnectedDevicesManager {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let result: Array<string> = []
|
const result: Array<string> = []
|
||||||
|
|
||||||
sentConnectedDevices.forEach((deviceId) => result.push(deviceId))
|
sentConnectedDevices.forEach((deviceId) => result.push(deviceId))
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ export class VisibleConnectedDevicesManager {
|
|||||||
devices.forEach(({ deviceId, showDeviceConnected }) => {
|
devices.forEach(({ deviceId, showDeviceConnected }) => {
|
||||||
addDevice({ deviceId, showDeviceConnected })
|
addDevice({ deviceId, showDeviceConnected })
|
||||||
})
|
})
|
||||||
})().catch((ex) => { /* ignore */ })
|
})().catch(() => { /* ignore */ })
|
||||||
|
|
||||||
{
|
{
|
||||||
// add all new devices + apply changes of sharing
|
// add all new devices + apply changes of sharing
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -86,7 +86,7 @@ const createDatabase = (sequelize: Sequelize.Sequelize): Database => ({
|
|||||||
transaction: <T> (autoCallback: (transaction: Transaction) => Promise<T>, options?: { transaction: Transaction }) => (sequelize.transaction({
|
transaction: <T> (autoCallback: (transaction: Transaction) => Promise<T>, options?: { transaction: Transaction }) => (sequelize.transaction({
|
||||||
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE,
|
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE,
|
||||||
transaction: options?.transaction
|
transaction: options?.transaction
|
||||||
}, autoCallback) as any) as Promise<T>,
|
}, autoCallback)) as Promise<T>,
|
||||||
dialect: sequelize.getDialect()
|
dialect: sequelize.getDialect()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export type SequelizeAttributes<T extends { [key: string]: any }> = {
|
export type SequelizeAttributes<T extends { [key: string]: any }> = {
|
||||||
[P in keyof T]: Sequelize.ModelAttributeColumnOptions;
|
[P in keyof T]: Sequelize.ModelAttributeColumnOptions;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -21,7 +21,7 @@ import { Database } from '../main'
|
|||||||
|
|
||||||
export class SerializationFeatureCheckException extends Error {}
|
export class SerializationFeatureCheckException extends Error {}
|
||||||
|
|
||||||
export function shouldRetryWithException (database: Database, e: any): boolean {
|
export function shouldRetryWithException (database: Database, e: unknown): boolean {
|
||||||
if (e instanceof Sequelize.TimeoutError) return true
|
if (e instanceof Sequelize.TimeoutError) return true
|
||||||
|
|
||||||
if (!(e instanceof Sequelize.DatabaseError)) return false
|
if (!(e instanceof Sequelize.DatabaseError)) return false
|
||||||
@@ -32,10 +32,13 @@ export function shouldRetryWithException (database: Database, e: any): boolean {
|
|||||||
if (parent.message.startsWith('SQLITE_BUSY:')) return true
|
if (parent.message.startsWith('SQLITE_BUSY:')) return true
|
||||||
} else if (database.dialect === 'postgres') {
|
} else if (database.dialect === 'postgres') {
|
||||||
// 40001 = serialization_failure
|
// 40001 = serialization_failure
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
if ((parent as any).code === '40001') return true
|
if ((parent as any).code === '40001') return true
|
||||||
// 40P01 = deadlock detected
|
// 40P01 = deadlock detected
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
if ((parent as any).code === '40P01') return true
|
if ((parent as any).code === '40P01') return true
|
||||||
} else if (database.dialect === 'mariadb') {
|
} else if (database.dialect === 'mariadb') {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const errno = (parent as any).errno
|
const errno = (parent as any).errno
|
||||||
|
|
||||||
// ER_LOCK_DEADLOCK
|
// ER_LOCK_DEADLOCK
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
const IABVerifier: new (publicKey: string) => {
|
const IABVerifier: new (publicKey: string) => {
|
||||||
verifyReceipt: (data: string, signature: string) => boolean
|
verifyReceipt: (data: string, signature: string) => boolean
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
} = require('iab_verifier')
|
} = require('iab_verifier')
|
||||||
|
|
||||||
export const googlePlayPublicKey = process.env.GOOGLE_PLAY_PUBLIC_KEY || ''
|
export const googlePlayPublicKey = process.env.GOOGLE_PLAY_PUBLIC_KEY || ''
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export async function dispatchAddUsedTimeVersion2 ({ deviceId, action, cache, ev
|
|||||||
addUsedTimeForADifferentUserThanTheCurrentUserOfTheDevice = true
|
addUsedTimeForADifferentUserThanTheCurrentUserOfTheDevice = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// tslint:disable-next-line:no-inner-declarations
|
// eslint-disable-next-line no-inner-declarations
|
||||||
async function handle (start: number, end: number) {
|
async function handle (start: number, end: number) {
|
||||||
const lengthInMinutes = (end - start) + 1
|
const lengthInMinutes = (end - start) + 1
|
||||||
const lengthInMs = lengthInMinutes * 1000 * 60
|
const lengthInMs = lengthInMinutes * 1000 * 60
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -26,7 +26,7 @@ import { parseEncodedAction } from '../parse-encoded-action'
|
|||||||
export async function dispatch<T1 extends { type: string }, T2> ({ type, action, validator, parser, applier, eventHandler }: {
|
export async function dispatch<T1 extends { type: string }, T2> ({ type, action, validator, parser, applier, eventHandler }: {
|
||||||
type: 'app logic' | 'parent' | 'child'
|
type: 'app logic' | 'parent' | 'child'
|
||||||
action: ClientPushChangesRequestAction
|
action: ClientPushChangesRequestAction
|
||||||
validator: (input: any) => input is T1
|
validator: (input: unknown) => input is T1
|
||||||
parser: (input: T1) => T2
|
parser: (input: T1) => T2
|
||||||
applier: (input: T2) => Promise<void>
|
applier: (input: T2) => Promise<void>
|
||||||
eventHandler: EventHandler
|
eventHandler: EventHandler
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -80,6 +80,16 @@ export async function dispatchAddCategoryApps ({ action, cache, fromChildSelfLim
|
|||||||
})).map((item) => item.categoryId)
|
})).map((item) => item.categoryId)
|
||||||
|
|
||||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||||
|
for (let i = 0; i < action.packageNames.length; i++) {
|
||||||
|
const packageName = action.packageNames[i]
|
||||||
|
|
||||||
|
if (packageName.indexOf('@') !== -1) {
|
||||||
|
throw new SelfLimitationException({
|
||||||
|
staticMessage: 'can not do device specific assignments as child'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const parentCategoriesOfTargetCategory = getCategoryWithParentCategories(categoriesOfSameChild, action.categoryId)
|
const parentCategoriesOfTargetCategory = getCategoryWithParentCategories(categoriesOfSameChild, action.categoryId)
|
||||||
const userEntryUnsafe = await cache.database.user.findOne({
|
const userEntryUnsafe = await cache.database.user.findOne({
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export const generateServerDataStatus = async ({ database, clientStatus, familyI
|
|||||||
const familyEntry = await getFamilyEntry({ database, familyId, transaction })
|
const familyEntry = await getFamilyEntry({ database, familyId, transaction })
|
||||||
const doesClientSupportTasks = clientStatus.clientLevel !== undefined && clientStatus.clientLevel >= 3
|
const doesClientSupportTasks = clientStatus.clientLevel !== undefined && clientStatus.clientLevel >= 3
|
||||||
|
|
||||||
let result: ServerDataStatus = {
|
const result: ServerDataStatus = {
|
||||||
fullVersion: config.alwaysPro ? 1 : (
|
fullVersion: config.alwaysPro ? 1 : (
|
||||||
familyEntry.hasFullVersion ? parseInt(familyEntry.fullVersionUntil, 10) : 0
|
familyEntry.hasFullVersion ? parseInt(familyEntry.fullVersionUntil, 10) : 0
|
||||||
),
|
),
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2020 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -56,7 +56,7 @@ export const validateBitmask = (bitmask: string, maxLength: number) => {
|
|||||||
export const validateAndParseBitmask = (bitmask: string, maxLength: number) => {
|
export const validateAndParseBitmask = (bitmask: string, maxLength: number) => {
|
||||||
validateBitmask(bitmask, maxLength)
|
validateBitmask(bitmask, maxLength)
|
||||||
|
|
||||||
const result = range(0, maxLength).map((_) => false)
|
const result = range(0, maxLength).map(() => false)
|
||||||
|
|
||||||
const splitpoints = split(bitmask, ',').map((item) => parseInt(item, 10))
|
const splitpoints = split(bitmask, ',').map((item) => parseInt(item, 10))
|
||||||
|
|
||||||
|
|||||||
+92
-50
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -15,39 +15,85 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { compile } from 'ejs'
|
||||||
import { parseOneAddress } from 'email-addresses'
|
import { parseOneAddress } from 'email-addresses'
|
||||||
import * as Email from 'email-templates'
|
import { readFileSync } from 'fs'
|
||||||
import { join } from 'path'
|
import { createTransport } from 'nodemailer'
|
||||||
|
import { resolve } from 'path'
|
||||||
import { config } from '../config'
|
import { config } from '../config'
|
||||||
import { IllegalStateException } from '../exception'
|
import { IllegalStateException } from '../exception'
|
||||||
|
|
||||||
const mailimprint = process.env.MAIL_IMPRINT || 'not defined'
|
const mailimprint = process.env.MAIL_IMPRINT || 'not defined'
|
||||||
const mailServerBlacklist = (process.env.MAIL_SERVER_BLACKLIST || '').split(',').filter((item) => !!item)
|
const mailServerBlacklist = (process.env.MAIL_SERVER_BLACKLIST || '').split(',').filter((item) => !!item)
|
||||||
|
|
||||||
const email = new Email({
|
const mailSender = process.env.MAIL_SENDER || ''
|
||||||
message: {
|
const mailTransportConfig = JSON.parse(process.env.MAIL_TRANSPORT || 'null') || undefined
|
||||||
from: process.env.MAIL_SENDER || ''
|
const isDevMode = process.env.NODE_ENV === 'development'
|
||||||
},
|
|
||||||
transport: JSON.parse(process.env.MAIL_TRANSPORT || 'null') || undefined,
|
const mailTransport = isDevMode || mailTransportConfig !== undefined ?
|
||||||
views: {
|
createTransport(isDevMode ? {
|
||||||
options: {
|
jsonTransport: true
|
||||||
extension: 'ejs'
|
} : mailTransportConfig) :
|
||||||
|
null
|
||||||
|
|
||||||
|
function createMailTemplateSender (templateName: string) {
|
||||||
|
const compileTemplate = (filename: string) => compile(
|
||||||
|
readFileSync(resolve(__dirname, '../../other/mail', templateName, filename)).toString('utf8')
|
||||||
|
)
|
||||||
|
|
||||||
|
const subjectTemplate = compileTemplate('subject.ejs')
|
||||||
|
const textTemplate = compileTemplate('text.ejs')
|
||||||
|
const htmlTemplate = compileTemplate('html.ejs')
|
||||||
|
|
||||||
|
const sendMail = async ({ receiver, params }: {
|
||||||
|
receiver: string
|
||||||
|
params: object
|
||||||
|
}) => {
|
||||||
|
if (!mailTransport) {
|
||||||
|
throw new Error('can not send mails without mail config and without NODE_ENV=development')
|
||||||
}
|
}
|
||||||
},
|
|
||||||
juice: false
|
const subject = subjectTemplate(params).replace(/\n/g, ' ')
|
||||||
})
|
const text = textTemplate(params)
|
||||||
|
const html = htmlTemplate(params)
|
||||||
|
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
mailTransport.sendMail({
|
||||||
|
from: mailSender,
|
||||||
|
to: receiver,
|
||||||
|
subject,
|
||||||
|
text,
|
||||||
|
html
|
||||||
|
}, (err, info) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
if (isDevMode) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const data = (info as any).message
|
||||||
|
|
||||||
|
console.log(JSON.stringify(JSON.parse(data), null, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return { sendMail }
|
||||||
|
}
|
||||||
|
|
||||||
|
const loginMailSender = createMailTemplateSender('login')
|
||||||
|
|
||||||
export const sendAuthenticationMail = async ({
|
export const sendAuthenticationMail = async ({
|
||||||
receiver, code, locale, deviceName
|
receiver, code, locale, deviceName
|
||||||
}: {
|
}: {
|
||||||
receiver: string, code: string, locale: string, deviceName: string | null
|
receiver: string, code: string, locale: string, deviceName: string | null
|
||||||
}) => {
|
}) => {
|
||||||
await email.send({
|
await loginMailSender.sendMail({
|
||||||
template: join(__dirname, '../../other/mail/login'),
|
receiver,
|
||||||
message: {
|
params: {
|
||||||
to: receiver
|
|
||||||
},
|
|
||||||
locals: {
|
|
||||||
subject: locale === 'de' ? 'Anmeldung bei TimeLimit' : 'Sign in at TimeLimit',
|
subject: locale === 'de' ? 'Anmeldung bei TimeLimit' : 'Sign in at TimeLimit',
|
||||||
introtext: locale === 'de' ? 'Geben Sie zum Authentifizieren folgenden Code in TimeLimit ein' : 'To authenticate, enter the following code in TimeLimit',
|
introtext: locale === 'de' ? 'Geben Sie zum Authentifizieren folgenden Code in TimeLimit ein' : 'To authenticate, enter the following code in TimeLimit',
|
||||||
code,
|
code,
|
||||||
@@ -60,16 +106,15 @@ export const sendAuthenticationMail = async ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const manipulationMailSender = createMailTemplateSender('manipulation')
|
||||||
|
|
||||||
export const sendManipulationWarningMail = async ({ receiver, deviceName }: {
|
export const sendManipulationWarningMail = async ({ receiver, deviceName }: {
|
||||||
receiver: string
|
receiver: string
|
||||||
deviceName: string
|
deviceName: string
|
||||||
}) => {
|
}) => {
|
||||||
await email.send({
|
await manipulationMailSender.sendMail({
|
||||||
template: join(__dirname, '../../other/mail/manipulation'),
|
receiver,
|
||||||
message: {
|
params: {
|
||||||
to: receiver
|
|
||||||
},
|
|
||||||
locals: {
|
|
||||||
subject: 'TimeLimit@' + deviceName + ' - Manipulation',
|
subject: 'TimeLimit@' + deviceName + ' - Manipulation',
|
||||||
deviceName,
|
deviceName,
|
||||||
mailimprint
|
mailimprint
|
||||||
@@ -77,16 +122,15 @@ export const sendManipulationWarningMail = async ({ receiver, deviceName }: {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uninstallMailSender = createMailTemplateSender('uninstall')
|
||||||
|
|
||||||
export const sendUninstallWarningMail = async ({ receiver, deviceName }: {
|
export const sendUninstallWarningMail = async ({ receiver, deviceName }: {
|
||||||
receiver: string
|
receiver: string
|
||||||
deviceName: string
|
deviceName: string
|
||||||
}) => {
|
}) => {
|
||||||
await email.send({
|
await uninstallMailSender.sendMail({
|
||||||
template: join(__dirname, '../../other/mail/uninstall'),
|
receiver,
|
||||||
message: {
|
params: {
|
||||||
to: receiver
|
|
||||||
},
|
|
||||||
locals: {
|
|
||||||
subject: 'TimeLimit removed from ' + deviceName,
|
subject: 'TimeLimit removed from ' + deviceName,
|
||||||
deviceName,
|
deviceName,
|
||||||
mailimprint
|
mailimprint
|
||||||
@@ -94,31 +138,29 @@ export const sendUninstallWarningMail = async ({ receiver, deviceName }: {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const taskDoneSender = createMailTemplateSender('taskdone')
|
||||||
|
|
||||||
export const sendTaskDoneMail = async ({ receiver, child, task }: {
|
export const sendTaskDoneMail = async ({ receiver, child, task }: {
|
||||||
receiver: string
|
receiver: string
|
||||||
child: string
|
child: string
|
||||||
task: string
|
task: string
|
||||||
}) => {
|
}) => {
|
||||||
await email.send({
|
await taskDoneSender.sendMail({
|
||||||
template: join(__dirname, '../../other/mail/taskdone'),
|
receiver,
|
||||||
message: {
|
params: { child, task, mailimprint }
|
||||||
to: receiver
|
|
||||||
},
|
|
||||||
locals: { child, task, mailimprint }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deviceLinkedSender = createMailTemplateSender('device-linked-by-mail')
|
||||||
|
|
||||||
export const sendDeviceLinkedMail = async ({ receiver, deviceName, locale }: {
|
export const sendDeviceLinkedMail = async ({ receiver, deviceName, locale }: {
|
||||||
receiver: string
|
receiver: string
|
||||||
deviceName: string
|
deviceName: string
|
||||||
locale: string
|
locale: string
|
||||||
}) => {
|
}) => {
|
||||||
await email.send({
|
await deviceLinkedSender.sendMail({
|
||||||
template: join(__dirname, '../../other/mail/device-linked-by-mail'),
|
receiver,
|
||||||
message: {
|
params: {
|
||||||
to: receiver
|
|
||||||
},
|
|
||||||
locals: {
|
|
||||||
subject: locale === 'de' ? 'Gerät hinzugefügt' : 'Device added',
|
subject: locale === 'de' ? 'Gerät hinzugefügt' : 'Device added',
|
||||||
preText: locale === 'de' ? 'Soeben wurde das Gerät' : 'The device',
|
preText: locale === 'de' ? 'Soeben wurde das Gerät' : 'The device',
|
||||||
deviceName,
|
deviceName,
|
||||||
@@ -129,16 +171,15 @@ export const sendDeviceLinkedMail = async ({ receiver, deviceName, locale }: {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const passwordRecoveryUsedMailSender = createMailTemplateSender('password-recovery-used')
|
||||||
|
|
||||||
export const sendPasswordRecoveryUsedMail = async ({ receiver, locale }: {
|
export const sendPasswordRecoveryUsedMail = async ({ receiver, locale }: {
|
||||||
receiver: string
|
receiver: string
|
||||||
locale: string
|
locale: string
|
||||||
}) => {
|
}) => {
|
||||||
await email.send({
|
await passwordRecoveryUsedMailSender.sendMail({
|
||||||
template: join(__dirname, '../../other/mail/password-recovery-used'),
|
receiver,
|
||||||
message: {
|
params: {
|
||||||
to: receiver
|
|
||||||
},
|
|
||||||
locals: {
|
|
||||||
subject: locale === 'de' ? 'Passwort-Vergessen-Funktion verwendet' : 'Password reset',
|
subject: locale === 'de' ? 'Passwort-Vergessen-Funktion verwendet' : 'Password reset',
|
||||||
text: locale === 'de' ?
|
text: locale === 'de' ?
|
||||||
'Soeben wurde Ihr TimeLimit-Passwort mit der Passwort-Vergessen-Funktion geändert.' :
|
'Soeben wurde Ihr TimeLimit-Passwort mit der Passwort-Vergessen-Funktion geändert.' :
|
||||||
@@ -198,6 +239,7 @@ export function sanitizeMailAddress (input: string): string | null {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const address = (parsed as any).address
|
const address = (parsed as any).address
|
||||||
|
|
||||||
if (typeof address !== 'string') {
|
if (typeof address !== 'string') {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -28,7 +28,7 @@ const randomWord = () => wordlist[Math.floor(Math.random() * (wordlist.length -
|
|||||||
|
|
||||||
export const randomWords = (numberOfWords: number) => (
|
export const randomWords = (numberOfWords: number) => (
|
||||||
range(numberOfWords)
|
range(numberOfWords)
|
||||||
.map((item) => randomWord())
|
.map(() => randomWord())
|
||||||
.join(' ')
|
.join(' ')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* server component for the TimeLimit App
|
* server component for the TimeLimit App
|
||||||
* Copyright (C) 2019 - 2021 Jonas Lochmann
|
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
@@ -45,7 +45,7 @@ export const createWebsocketHandler = ({ connectedDevicesManager, database }: {
|
|||||||
socketCounter++
|
socketCounter++
|
||||||
socket.on('disconnect', () => socketCounter--)
|
socket.on('disconnect', () => socketCounter--)
|
||||||
|
|
||||||
socket.on('devicelogin', (deviceAuthToken: any, ack: any) => {
|
socket.on('devicelogin', (deviceAuthToken: unknown, ack: unknown) => {
|
||||||
socket.rooms.forEach((room) => socket.leave(room))
|
socket.rooms.forEach((room) => socket.leave(room))
|
||||||
|
|
||||||
if (typeof deviceAuthToken !== 'string') {
|
if (typeof deviceAuthToken !== 'string') {
|
||||||
@@ -95,7 +95,7 @@ export const createWebsocketHandler = ({ connectedDevicesManager, database }: {
|
|||||||
shutdown()
|
shutdown()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})().catch((ex) => { /* ignore */ })
|
})().catch(() => { /* ignore */ })
|
||||||
|
|
||||||
if (typeof ack === 'function') {
|
if (typeof ack === 'function') {
|
||||||
ack()
|
ack()
|
||||||
|
|||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"defaultSeverity": "error",
|
|
||||||
"extends": [
|
|
||||||
"tslint-config-standard"
|
|
||||||
],
|
|
||||||
"jsRules": {},
|
|
||||||
"rules": {
|
|
||||||
"await-promise": [true, "Bluebird"],
|
|
||||||
"ordered-imports": true
|
|
||||||
},
|
|
||||||
"rulesDirectory": []
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user