@internetderdinge/api 1.229.0 → 1.229.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/accounts/accounts.controller.js +89 -0
- package/dist/src/accounts/accounts.route.js +101 -0
- package/dist/src/accounts/accounts.schemas.js +12 -0
- package/dist/src/accounts/accounts.service.js +65 -0
- package/dist/src/accounts/accounts.validation.js +99 -0
- package/dist/src/accounts/auth0.service.js +188 -0
- package/dist/src/config/config.js +48 -0
- package/dist/src/config/logger.js +27 -0
- package/dist/src/config/morgan.js +16 -0
- package/dist/src/config/passport.cjs +28 -0
- package/dist/src/config/roles.js +11 -0
- package/dist/src/config/tokens.cjs +10 -0
- package/dist/src/devices/devices.controller.js +172 -0
- package/dist/src/devices/devices.model.js +94 -0
- package/dist/src/devices/devices.route.js +153 -0
- package/dist/src/devices/devices.schemas.js +84 -0
- package/dist/src/devices/devices.service.js +198 -0
- package/dist/src/devices/devices.types.js +1 -0
- package/dist/src/devices/devices.validation.js +257 -0
- package/dist/src/devicesNotifications/devicesNotifications.controller.js +69 -0
- package/dist/src/devicesNotifications/devicesNotifications.model.js +39 -0
- package/dist/src/devicesNotifications/devicesNotifications.route.js +124 -0
- package/dist/src/devicesNotifications/devicesNotifications.schemas.js +10 -0
- package/dist/src/devicesNotifications/devicesNotifications.service.js +181 -0
- package/dist/src/devicesNotifications/devicesNotifications.validation.js +46 -0
- package/dist/src/email/email.service.js +580 -0
- package/dist/src/files/upload.service.js +124 -0
- package/dist/src/i18n/i18n.js +38 -0
- package/dist/src/i18n/saveMissingLocalJsonBackend.js +53 -0
- package/dist/src/i18n/types.js +1 -0
- package/dist/src/index.js +48 -0
- package/dist/src/iotdevice/iotdevice.controller.js +96 -0
- package/dist/src/iotdevice/iotdevice.model.js +17 -0
- package/dist/src/iotdevice/iotdevice.route.js +143 -0
- package/dist/src/iotdevice/iotdevice.schemas.js +60 -0
- package/dist/src/iotdevice/iotdevice.service.js +579 -0
- package/dist/src/iotdevice/iotdevice.types.js +1 -0
- package/dist/src/iotdevice/iotdevice.validation.js +54 -0
- package/dist/src/middlewares/auth.js +75 -0
- package/dist/src/middlewares/checkJwt.cjs +17 -0
- package/dist/src/middlewares/error.js +36 -0
- package/dist/src/middlewares/mongooseValidations/ensureSameOrganization.js +13 -0
- package/dist/src/middlewares/rateLimiter.js +7 -0
- package/dist/src/middlewares/validate.js +18 -0
- package/dist/src/middlewares/validateAction.js +35 -0
- package/dist/src/middlewares/validateAdmin.js +18 -0
- package/dist/src/middlewares/validateAi.js +16 -0
- package/dist/src/middlewares/validateCurrentAuthUser.js +17 -0
- package/dist/src/middlewares/validateCurrentUser.js +20 -0
- package/dist/src/middlewares/validateDevice.js +98 -0
- package/dist/src/middlewares/validateDeviceUserOrganization.js +26 -0
- package/dist/src/middlewares/validateOrganization.js +63 -0
- package/dist/src/middlewares/validateQuerySearchUserAndOrganization.js +44 -0
- package/dist/src/middlewares/validateTokens.js +23 -0
- package/dist/src/middlewares/validateUser.js +38 -0
- package/dist/src/middlewares/validateZod.js +33 -0
- package/dist/src/models/plugins/index.js +4 -0
- package/dist/src/models/plugins/paginate.plugin.js +117 -0
- package/dist/src/models/plugins/paginateNew.plugin.js +185 -0
- package/dist/src/models/plugins/simplePopulate.js +16 -0
- package/dist/src/models/plugins/toJSON.plugin.js +35 -0
- package/dist/src/organizations/organizations.controller.js +64 -0
- package/dist/src/organizations/organizations.model.js +41 -0
- package/dist/src/organizations/organizations.route.js +98 -0
- package/dist/src/organizations/organizations.schemas.js +7 -0
- package/dist/src/organizations/organizations.service.js +59 -0
- package/dist/src/organizations/organizations.validation.js +62 -0
- package/dist/src/pdf/pdf.controller.js +24 -0
- package/dist/src/pdf/pdf.route.js +22 -0
- package/dist/src/pdf/pdf.schemas.js +6 -0
- package/dist/src/pdf/pdf.service.js +65 -0
- package/dist/src/pdf/pdf.validation.js +27 -0
- package/dist/src/tokens/tokens.controller.js +60 -0
- package/dist/src/tokens/tokens.model.js +17 -0
- package/dist/src/tokens/tokens.route.js +52 -0
- package/dist/src/tokens/tokens.schemas.js +14 -0
- package/dist/src/tokens/tokens.service.js +30 -0
- package/dist/src/tokens/tokens.validation.js +9 -0
- package/dist/src/types/routeSpec.js +1 -0
- package/dist/src/users/users.controller.js +147 -0
- package/dist/src/users/users.model.js +50 -0
- package/dist/src/users/users.route.js +137 -0
- package/dist/src/users/users.schemas.js +69 -0
- package/dist/src/users/users.service.js +295 -0
- package/dist/src/users/users.types.js +1 -0
- package/dist/src/users/users.validation.js +144 -0
- package/dist/src/utils/ApiError.js +16 -0
- package/dist/src/utils/buildRouterAndDocs.js +72 -0
- package/dist/src/utils/catchAsync.js +4 -0
- package/dist/src/utils/comparePapers.service.js +32 -0
- package/dist/src/utils/deviceUtils.js +63 -0
- package/dist/src/utils/filterOptions.js +24 -0
- package/dist/src/utils/medicationName.js +10 -0
- package/dist/src/utils/pick.js +16 -0
- package/dist/src/utils/registerOpenApi.js +67 -0
- package/dist/src/utils/urlUtils.js +15 -0
- package/dist/src/utils/userName.js +22 -0
- package/dist/src/utils/zValidations.js +143 -0
- package/dist/src/validations/auth.validation.cjs +53 -0
- package/dist/src/validations/custom.validation.js +19 -0
- package/dist/src/validations/index.cjs +3 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +97 -80
- package/scripts/release-and-sync-paperless.mjs +137 -0
- package/src/accounts/accounts.controller.ts +1 -0
- package/src/accounts/accounts.service.ts +1 -0
- package/src/accounts/accounts.validation.ts +8 -5
- package/src/accounts/auth0.service.ts +55 -28
- package/src/config/config.ts +6 -0
- package/src/config/logger.ts +15 -9
- package/src/devices/devices.controller.ts +7 -1
- package/src/devices/devices.model.ts +4 -1
- package/src/devices/devices.schemas.ts +11 -9
- package/src/devices/devices.service.ts +1 -0
- package/src/devices/devices.types.ts +1 -0
- package/src/devices/devices.validation.ts +93 -32
- package/src/devicesNotifications/devicesNotifications.controller.ts +57 -28
- package/src/devicesNotifications/devicesNotifications.model.ts +20 -12
- package/src/devicesNotifications/devicesNotifications.service.ts +35 -17
- package/src/files/upload.service.ts +52 -28
- package/src/i18n/i18n.ts +1 -1
- package/src/i18n/types.ts +1 -0
- package/src/index.ts +47 -0
- package/src/iotdevice/iotdevice.controller.ts +1 -0
- package/src/iotdevice/iotdevice.model.ts +6 -3
- package/src/iotdevice/iotdevice.route.ts +85 -76
- package/src/iotdevice/iotdevice.service.ts +4 -3
- package/src/iotdevice/iotdevice.types.ts +6 -0
- package/src/middlewares/auth.ts +2 -8
- package/src/middlewares/error.ts +26 -12
- package/src/middlewares/mongooseValidations/ensureSameOrganization.ts +4 -3
- package/src/middlewares/validateAi.ts +17 -9
- package/src/middlewares/validateDevice.ts +1 -0
- package/src/middlewares/validateDeviceUserOrganization.ts +1 -0
- package/src/middlewares/validateOrganization.ts +1 -1
- package/src/middlewares/validateQuerySearchUserAndOrganization.ts +1 -0
- package/src/middlewares/validateTokens.ts +2 -1
- package/src/middlewares/validateUser.ts +1 -0
- package/src/middlewares/validateZod.ts +5 -5
- package/src/models/plugins/index.ts +5 -4
- package/src/models/plugins/paginate.plugin.ts +26 -16
- package/src/models/plugins/paginateNew.plugin.ts +33 -21
- package/src/models/plugins/simplePopulate.ts +8 -3
- package/src/models/plugins/toJSON.plugin.ts +12 -5
- package/src/organizations/organizations.controller.ts +1 -2
- package/src/organizations/organizations.model.ts +4 -4
- package/src/organizations/organizations.route.ts +1 -1
- package/src/organizations/organizations.service.ts +15 -6
- package/src/organizations/organizations.validation.ts +1 -1
- package/src/pdf/pdf.controller.ts +18 -1
- package/src/pdf/pdf.service.ts +25 -16
- package/src/tokens/tokens.controller.ts +6 -8
- package/src/tokens/tokens.model.ts +3 -1
- package/src/tokens/tokens.service.ts +3 -2
- package/src/types/express.d.ts +17 -0
- package/src/types/mongoose.d.ts +22 -0
- package/src/users/users.controller.ts +8 -9
- package/src/users/users.model.ts +6 -5
- package/src/users/users.route.ts +0 -1
- package/src/users/users.service.ts +16 -0
- package/src/users/users.types.ts +1 -0
- package/src/users/users.validation.ts +6 -2
- package/src/utils/ApiError.ts +8 -1
- package/src/utils/buildRouterAndDocs.ts +57 -22
- package/src/utils/catchAsync.ts +27 -3
- package/src/utils/medicationName.ts +5 -4
- package/src/utils/pick.ts +5 -1
- package/src/utils/registerOpenApi.ts +75 -24
- package/src/utils/userName.ts +1 -0
- package/src/utils/zValidations.ts +98 -27
- package/tsconfig.json +13 -4
package/package.json
CHANGED
|
@@ -1,111 +1,128 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetderdinge/api",
|
|
3
|
-
"version": "1.229.
|
|
3
|
+
"version": "1.229.2",
|
|
4
4
|
"description": "Shared OpenIoT API modules",
|
|
5
|
-
"main": "src/index.
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": ">=24.0.0"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc -p tsconfig.json",
|
|
12
|
+
"dev:watch": "tsc -p tsconfig.json --watch --incremental --preserveWatchOutput",
|
|
13
|
+
"dev:yalc": "nodemon --watch src --watch package.json --ext ts,json --exec \"yarn build && yalc publish --push\"",
|
|
14
|
+
"yalc:publish": "yalc publish --push",
|
|
15
|
+
"deps:versions": "node --input-type=module -e \"import { createRequire } from 'node:module'; const require = createRequire(import.meta.url); const out = (name) => { const pkgPath = require.resolve(name + '/package.json'); const version = require(pkgPath).version; console.log(name + '@' + version + ' -> ' + pkgPath); }; out('zod'); out('@asteasolutions/zod-to-openapi');\"",
|
|
12
16
|
"deploy:version": "node ./scripts/release-version.mjs",
|
|
17
|
+
"release:paperless": "node ./scripts/release-and-sync-paperless.mjs",
|
|
13
18
|
"lint": "eslint .",
|
|
14
19
|
"lint:fix": "eslint . --fix"
|
|
15
20
|
},
|
|
16
21
|
"dependencies": {
|
|
17
|
-
"@
|
|
18
|
-
"@aws-sdk/client-
|
|
19
|
-
"@aws-sdk/client-
|
|
20
|
-
"@aws-sdk/
|
|
21
|
-
"@aws-sdk/
|
|
22
|
-
"@aws-sdk/
|
|
23
|
-
"@aws-sdk/
|
|
24
|
-
"@
|
|
25
|
-
"@sentry/node": "^10.
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"aws-
|
|
31
|
-
"aws-
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"body-parser": "~
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"date-fns": "
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"express": "^5.1.0",
|
|
22
|
+
"@aws-sdk/client-cloudwatch-events": "^3.990.0",
|
|
23
|
+
"@aws-sdk/client-s3": "^3.990.0",
|
|
24
|
+
"@aws-sdk/client-sesv2": "^3.990.0",
|
|
25
|
+
"@aws-sdk/credential-provider-node": "^3.972.9",
|
|
26
|
+
"@aws-sdk/lib-storage": "^3.990.0",
|
|
27
|
+
"@aws-sdk/s3-request-presigner": "^3.990.0",
|
|
28
|
+
"@aws-sdk/util-endpoints": "^3.990.0",
|
|
29
|
+
"@sentry/node": "^10.38.0",
|
|
30
|
+
"@sentry/profiling-node": "^10.38.0",
|
|
31
|
+
"agenda": "^6.2.2",
|
|
32
|
+
"agendash": "^8.1.1",
|
|
33
|
+
"auth0": "^5.3.1",
|
|
34
|
+
"aws-crt": "^1.29.0",
|
|
35
|
+
"aws-iot-device-sdk-v2": "^1.25.0",
|
|
36
|
+
"aws-sdk": "^2.1693.0",
|
|
37
|
+
"aws4": "^1.13.2",
|
|
38
|
+
"axios": "^1.13.5",
|
|
39
|
+
"body-parser": "~2.2.2",
|
|
40
|
+
"body-parser-xml": "~2.0.5",
|
|
41
|
+
"canvas": "^3.2.1",
|
|
42
|
+
"compression": "^1.8.1",
|
|
43
|
+
"config": "^4.3.0",
|
|
44
|
+
"cors": "^2.8.6",
|
|
45
|
+
"cron": "^4.4.0",
|
|
46
|
+
"date-fns": "^4.1.0",
|
|
47
|
+
"date-fns-tz": "3.2.0",
|
|
48
|
+
"dotenv": "^17.3.1",
|
|
49
|
+
"elevenlabs": "^1.59.0",
|
|
50
|
+
"express": "^5.2.1",
|
|
47
51
|
"express-jwt": "^8.5.1",
|
|
48
52
|
"express-mongo-sanitize": "^2.2.0",
|
|
49
|
-
"express-rate-limit": "^
|
|
53
|
+
"express-rate-limit": "^8.2.1",
|
|
50
54
|
"express-ws": "^5.0.2",
|
|
51
|
-
"
|
|
52
|
-
"
|
|
55
|
+
"file-type": "^21.3.0",
|
|
56
|
+
"firebase-admin": "^13.6.1",
|
|
57
|
+
"googleapis": "^171.4.0",
|
|
53
58
|
"he": "^1.2.0",
|
|
54
|
-
"helmet": "^
|
|
55
|
-
"http-status": "^1.
|
|
59
|
+
"helmet": "^8.1.0",
|
|
60
|
+
"http-status": "^2.1.0",
|
|
56
61
|
"https": "^1.0.0",
|
|
57
|
-
"i18next": "^
|
|
58
|
-
"joi": "^
|
|
59
|
-
"js-yaml": "^
|
|
60
|
-
"jsonwebtoken": "^
|
|
61
|
-
"jwks-rsa": "^2.
|
|
62
|
-
"moment": "^2.
|
|
63
|
-
"moment-timezone": "^0.
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"multer": "^1.4.5-lts.1",
|
|
62
|
+
"i18next": "^25.8.7",
|
|
63
|
+
"joi": "^18.0.2",
|
|
64
|
+
"js-yaml": "^4.1.1",
|
|
65
|
+
"jsonwebtoken": "^9.0.3",
|
|
66
|
+
"jwks-rsa": "^3.2.2",
|
|
67
|
+
"moment": "^2.30.1",
|
|
68
|
+
"moment-timezone": "^0.6.0",
|
|
69
|
+
"morgan": "^1.10.1",
|
|
70
|
+
"multer": "^2.0.2",
|
|
67
71
|
"multer-s3": "^3.0.1",
|
|
68
|
-
"multiparty": "~4.
|
|
69
|
-
"node-uuid": "~1.4.
|
|
70
|
-
"nodemailer": "^
|
|
71
|
-
"openai": "^
|
|
72
|
-
"passport": "^0.
|
|
73
|
-
"passport-jwt": "^4.0.
|
|
72
|
+
"multiparty": "~4.2.3",
|
|
73
|
+
"node-uuid": "~1.4.8",
|
|
74
|
+
"nodemailer": "^8.0.1",
|
|
75
|
+
"openai": "^6.22.0",
|
|
76
|
+
"passport": "^0.7.0",
|
|
77
|
+
"passport-jwt": "^4.0.1",
|
|
74
78
|
"path": "~0.12.7",
|
|
75
79
|
"pixelmatch": "^7.1.0",
|
|
76
80
|
"promise": "~8.3.0",
|
|
77
|
-
"puppeteer": "^24.
|
|
78
|
-
"qs": "^6.14.
|
|
79
|
-
"request": "^2.
|
|
80
|
-
"rrule": "^2.
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"stripe": "^
|
|
81
|
+
"puppeteer": "^24.37.3",
|
|
82
|
+
"qs": "^6.14.2",
|
|
83
|
+
"request": "^2.88.2",
|
|
84
|
+
"rrule": "^2.8.1",
|
|
85
|
+
"semver": "^7.7.4",
|
|
86
|
+
"sharp": "^0.34.5",
|
|
87
|
+
"stripe": "^20.3.1",
|
|
84
88
|
"swagger-ui-express": "^5.0.1",
|
|
85
89
|
"ts-node": "^10.9.2",
|
|
86
|
-
"typescript": "^5.
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
90
|
+
"typescript": "^5.9.3",
|
|
91
|
+
"uuid": "^13.0.0",
|
|
92
|
+
"validator": "^13.15.26",
|
|
93
|
+
"winston": "^3.19.0",
|
|
94
|
+
"xss-clean": "^0.1.4"
|
|
95
|
+
},
|
|
96
|
+
"peerDependencies": {
|
|
97
|
+
"@asteasolutions/zod-to-openapi": "^8.0.0",
|
|
98
|
+
"mongoose": "^8.15.1",
|
|
99
|
+
"zod": "^4.3.6"
|
|
91
100
|
},
|
|
92
101
|
"devDependencies": {
|
|
93
|
-
"@
|
|
102
|
+
"@asteasolutions/zod-to-openapi": "^8.0.0",
|
|
103
|
+
"@types/file-type": "^10.9.3",
|
|
104
|
+
"@types/glob": "^9.0.0",
|
|
105
|
+
"@types/passport": "^1.0.17",
|
|
106
|
+
"@types/uuid": "^11.0.0",
|
|
107
|
+
"@types/validator": "^13.15.10",
|
|
108
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
94
109
|
"coveralls": "^3.1.1",
|
|
95
|
-
"eslint": "^
|
|
96
|
-
"eslint-config-airbnb-base": "^
|
|
97
|
-
"eslint-config-prettier": "^
|
|
98
|
-
"eslint-plugin-import": "^2.
|
|
99
|
-
"eslint-plugin-prettier": "^
|
|
100
|
-
"eslint-plugin-security": "^
|
|
101
|
-
"faker": "^
|
|
102
|
-
"husky": "^
|
|
103
|
-
"lint-staged": "^
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"
|
|
110
|
+
"eslint": "^10.0.0",
|
|
111
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
112
|
+
"eslint-config-prettier": "^10.1.8",
|
|
113
|
+
"eslint-plugin-import": "^2.32.0",
|
|
114
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
115
|
+
"eslint-plugin-security": "^3.0.1",
|
|
116
|
+
"faker": "^6.6.6",
|
|
117
|
+
"husky": "^9.1.7",
|
|
118
|
+
"lint-staged": "^16.2.7",
|
|
119
|
+
"mongoose": "^9.2.1",
|
|
120
|
+
"node-mocks-http": "^1.17.2",
|
|
121
|
+
"nodemon": "^3.1.11",
|
|
122
|
+
"prettier": "^3.8.1",
|
|
123
|
+
"supertest": "^7.2.2",
|
|
124
|
+
"vitest": "^4.0.18",
|
|
125
|
+
"zod": "^4.3.6"
|
|
109
126
|
},
|
|
110
127
|
"gitHead": "9556e8e376045c1e532aded7ec7132818190fa91"
|
|
111
128
|
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
import semver from "semver";
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const repoRoot = path.resolve(__dirname, "..");
|
|
9
|
+
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const shouldPublish = !args.includes("--no-publish");
|
|
12
|
+
const versionInput = args.find((value) => !value.startsWith("-")) ?? "patch";
|
|
13
|
+
|
|
14
|
+
const readJson = (filePath) => {
|
|
15
|
+
const raw = fs.readFileSync(filePath, "utf8");
|
|
16
|
+
return JSON.parse(raw);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const writeJson = (filePath, data) => {
|
|
20
|
+
fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const resolveNextVersion = (current, input) => {
|
|
24
|
+
const cleanedCurrent = semver.valid(semver.clean(current));
|
|
25
|
+
if (!cleanedCurrent) {
|
|
26
|
+
throw new Error(`Unsupported version format: ${current}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const exact = semver.valid(input);
|
|
30
|
+
if (exact) {
|
|
31
|
+
return exact;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (input === "major" || input === "minor" || input === "patch") {
|
|
35
|
+
const bumped = semver.inc(cleanedCurrent, input);
|
|
36
|
+
if (!bumped) {
|
|
37
|
+
throw new Error(`Failed to bump version: ${current}`);
|
|
38
|
+
}
|
|
39
|
+
return bumped;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Unknown version input: ${input}. Use major/minor/patch or a semver like 1.2.3.`,
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const resolvePaperlesspaperWebRoot = () => {
|
|
48
|
+
if (process.env.PAPERLESSPAPER_WEB_PATH) {
|
|
49
|
+
return path.resolve(process.env.PAPERLESSPAPER_WEB_PATH);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return path.resolve(repoRoot, "../../paperlesspaper-web");
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const updateDependencyVersion = (
|
|
56
|
+
packageJsonPath,
|
|
57
|
+
dependencyName,
|
|
58
|
+
newVersion,
|
|
59
|
+
expectedVersion,
|
|
60
|
+
) => {
|
|
61
|
+
const packageJson = readJson(packageJsonPath);
|
|
62
|
+
const dependencies = packageJson.dependencies ?? {};
|
|
63
|
+
|
|
64
|
+
if (!dependencies[dependencyName]) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Missing dependency ${dependencyName} in ${packageJsonPath}`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const currentRange = dependencies[dependencyName];
|
|
71
|
+
const currentDependencyMin = semver.minVersion(currentRange);
|
|
72
|
+
if (!currentDependencyMin) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Unsupported dependency version for ${dependencyName} in ${packageJsonPath}: ${currentRange}`,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
const currentDependencyVersion = currentDependencyMin.version;
|
|
78
|
+
|
|
79
|
+
if (expectedVersion && currentDependencyVersion !== expectedVersion) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`paperlesspaper-api dependency is ${currentRange} (expected ${expectedVersion}). Update it before bumping.`,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const prefix = currentRange.startsWith("^")
|
|
86
|
+
? "^"
|
|
87
|
+
: currentRange.startsWith("~")
|
|
88
|
+
? "~"
|
|
89
|
+
: "";
|
|
90
|
+
|
|
91
|
+
dependencies[dependencyName] = `${prefix}${newVersion}`;
|
|
92
|
+
packageJson.dependencies = dependencies;
|
|
93
|
+
writeJson(packageJsonPath, packageJson);
|
|
94
|
+
|
|
95
|
+
return { previous: currentRange, next: dependencies[dependencyName] };
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const apiPackagePath = path.join(repoRoot, "package.json");
|
|
99
|
+
const apiPackage = readJson(apiPackagePath);
|
|
100
|
+
const currentVersion = apiPackage.version;
|
|
101
|
+
const cleanedCurrent = semver.valid(semver.clean(currentVersion));
|
|
102
|
+
if (!cleanedCurrent) {
|
|
103
|
+
throw new Error(`Unsupported version format: ${currentVersion}`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const nextVersion = resolveNextVersion(currentVersion, versionInput);
|
|
107
|
+
|
|
108
|
+
apiPackage.version = nextVersion;
|
|
109
|
+
writeJson(apiPackagePath, apiPackage);
|
|
110
|
+
|
|
111
|
+
if (shouldPublish) {
|
|
112
|
+
execSync("npm publish", { cwd: repoRoot, stdio: "inherit" });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const paperlesspaperRoot = resolvePaperlesspaperWebRoot();
|
|
116
|
+
const paperlessApiPath = path.join(
|
|
117
|
+
paperlesspaperRoot,
|
|
118
|
+
"packages/paperlesspaper-api/package.json",
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
if (!fs.existsSync(paperlessApiPath)) {
|
|
122
|
+
throw new Error(
|
|
123
|
+
"Could not find paperlesspaper-api package.json. Set PAPERLESSPAPER_WEB_PATH to the repo root.",
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const paperlessUpdate = updateDependencyVersion(
|
|
128
|
+
paperlessApiPath,
|
|
129
|
+
"@internetderdinge/api",
|
|
130
|
+
nextVersion,
|
|
131
|
+
cleanedCurrent,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
console.log(`Updated @internetderdinge/api to ${nextVersion}`);
|
|
135
|
+
console.log(
|
|
136
|
+
`paperlesspaper-api: ${paperlessUpdate.previous} -> ${paperlessUpdate.next}`,
|
|
137
|
+
);
|
|
@@ -22,7 +22,7 @@ export const createAccountSchema = {
|
|
|
22
22
|
organization: zObjectId.openapi({ description: "Organization ObjectId" }),
|
|
23
23
|
patient: zObjectId.openapi({ description: "Patient ObjectId" }),
|
|
24
24
|
meta: z
|
|
25
|
-
.record(z.any())
|
|
25
|
+
.record(z.string(), z.any())
|
|
26
26
|
.openapi({
|
|
27
27
|
example: { key: "value" },
|
|
28
28
|
description: "Additional metadata for the entry",
|
|
@@ -38,7 +38,8 @@ export const getAccountSchema = {
|
|
|
38
38
|
accountId: z
|
|
39
39
|
.string()
|
|
40
40
|
.openapi({
|
|
41
|
-
example:
|
|
41
|
+
example:
|
|
42
|
+
process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
|
|
42
43
|
description: "Auth Account ID",
|
|
43
44
|
}),
|
|
44
45
|
}),
|
|
@@ -49,7 +50,8 @@ export const updateAccountSchema = {
|
|
|
49
50
|
accountId: z
|
|
50
51
|
.string()
|
|
51
52
|
.openapi({
|
|
52
|
-
example:
|
|
53
|
+
example:
|
|
54
|
+
process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
|
|
53
55
|
description: "Auth Account ID",
|
|
54
56
|
}),
|
|
55
57
|
}),
|
|
@@ -80,7 +82,7 @@ export const updateAccountSchema = {
|
|
|
80
82
|
debug: z.boolean().optional(),
|
|
81
83
|
demo: z.boolean().optional(),
|
|
82
84
|
notification: z
|
|
83
|
-
.record(z.any())
|
|
85
|
+
.record(z.string(), z.any())
|
|
84
86
|
.optional()
|
|
85
87
|
.openapi({ description: "Notification settings object" }),
|
|
86
88
|
}),
|
|
@@ -91,7 +93,8 @@ export const deleteEntrySchema = {
|
|
|
91
93
|
accountId: z
|
|
92
94
|
.string()
|
|
93
95
|
.openapi({
|
|
94
|
-
example:
|
|
96
|
+
example:
|
|
97
|
+
process.env.SCHEMA_EXAMPLE_ACCOUNT_ID || "auth0|60452f4c0dc85b0062326",
|
|
95
98
|
description: "Auth Account ID",
|
|
96
99
|
}),
|
|
97
100
|
}),
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { AuthenticationClient, ManagementClient } from "auth0";
|
|
3
|
+
import type { ManagementClientOptions, User } from "auth0";
|
|
4
|
+
import { promises as fs, readFileSync } from "fs";
|
|
5
|
+
import { config } from "process";
|
|
5
6
|
|
|
6
7
|
interface TokenManagementClient {
|
|
7
8
|
clientId?: string;
|
|
@@ -21,12 +22,12 @@ let tokenManagementClient: TokenManagementClient = {
|
|
|
21
22
|
|
|
22
23
|
//if (config.env !== 'production') {
|
|
23
24
|
try {
|
|
24
|
-
console.warn(
|
|
25
|
-
const token = readFileSync(
|
|
26
|
-
console.warn(
|
|
25
|
+
console.warn("Auth0 client: use local token from cache try");
|
|
26
|
+
const token = readFileSync("./token.txt", "utf8");
|
|
27
|
+
console.warn("Auth0 client: use local token from cache");
|
|
27
28
|
tokenManagementClient = { token };
|
|
28
29
|
} catch (error) {
|
|
29
|
-
console.log(
|
|
30
|
+
console.log("Auth0 Client: use new token");
|
|
30
31
|
}
|
|
31
32
|
//}
|
|
32
33
|
|
|
@@ -56,14 +57,16 @@ let cachedManagementToken: string | null = null;
|
|
|
56
57
|
let managementTokenExpiresAt: number | null = null;
|
|
57
58
|
let pendingManagementTokenPromise: Promise<string> | null = null;
|
|
58
59
|
|
|
59
|
-
const TOKEN_FILE_PATH =
|
|
60
|
-
const MANAGEMENT_TOKEN_FILE_PATH =
|
|
60
|
+
const TOKEN_FILE_PATH = "./token.txt";
|
|
61
|
+
const MANAGEMENT_TOKEN_FILE_PATH = "./token.management.txt";
|
|
61
62
|
const TOKEN_BUFFER_SECONDS = 60; // refresh a minute before expiry
|
|
62
63
|
const TOKEN_FALLBACK_TTL_SECONDS = 3300; // ~55 minutes when no expiry metadata exists
|
|
63
64
|
|
|
64
|
-
const loadTokenFromFile = async (
|
|
65
|
+
const loadTokenFromFile = async (
|
|
66
|
+
filePath: string,
|
|
67
|
+
): Promise<CachedToken | null> => {
|
|
65
68
|
try {
|
|
66
|
-
const raw = await fs.readFile(filePath,
|
|
69
|
+
const raw = await fs.readFile(filePath, "utf8");
|
|
67
70
|
try {
|
|
68
71
|
const parsed = JSON.parse(raw);
|
|
69
72
|
if (parsed?.token && parsed?.expiresAt) {
|
|
@@ -80,22 +83,34 @@ const loadTokenFromFile = async (filePath: string): Promise<CachedToken | null>
|
|
|
80
83
|
return null;
|
|
81
84
|
};
|
|
82
85
|
|
|
83
|
-
const writeTokenFile = async (
|
|
86
|
+
const writeTokenFile = async (
|
|
87
|
+
filePath: string,
|
|
88
|
+
token: string,
|
|
89
|
+
expiresAt: number,
|
|
90
|
+
): Promise<void> => {
|
|
84
91
|
const payload = JSON.stringify({ token, expiresAt });
|
|
85
|
-
await fs.writeFile(filePath, payload,
|
|
92
|
+
await fs.writeFile(filePath, payload, "utf8");
|
|
86
93
|
};
|
|
87
94
|
|
|
88
|
-
const tokenIsValid = (
|
|
95
|
+
const tokenIsValid = (
|
|
96
|
+
token: string | null,
|
|
97
|
+
expiresAt: number | null,
|
|
98
|
+
now: number,
|
|
99
|
+
): boolean => {
|
|
89
100
|
if (!token || !expiresAt) return false;
|
|
90
101
|
return now < expiresAt - TOKEN_BUFFER_SECONDS;
|
|
91
102
|
};
|
|
92
103
|
|
|
93
104
|
export const getAuth0Token = async (): Promise<string> => {
|
|
94
|
-
const audience =
|
|
105
|
+
const audience =
|
|
106
|
+
process.env.AUTH0_AUDIENCE ||
|
|
107
|
+
process.env.AUTH0_MANAGEMENT_AUDIENCE ||
|
|
108
|
+
"localhost:3000/";
|
|
95
109
|
const grantOpts = { audience };
|
|
96
110
|
|
|
97
111
|
const now = Math.floor(Date.now() / 1000);
|
|
98
|
-
if (tokenIsValid(cachedToken, tokenExpiresAt, now))
|
|
112
|
+
if (tokenIsValid(cachedToken, tokenExpiresAt, now))
|
|
113
|
+
return cachedToken as string;
|
|
99
114
|
if (pendingTokenPromise) return pendingTokenPromise;
|
|
100
115
|
|
|
101
116
|
pendingTokenPromise = (async () => {
|
|
@@ -110,7 +125,8 @@ export const getAuth0Token = async (): Promise<string> => {
|
|
|
110
125
|
}
|
|
111
126
|
//}
|
|
112
127
|
|
|
113
|
-
const tokenResponse =
|
|
128
|
+
const tokenResponse =
|
|
129
|
+
await auth0AuthClient.oauth.clientCredentialsGrant(grantOpts);
|
|
114
130
|
const expiresIn = tokenResponse.data.expires_in || 3600;
|
|
115
131
|
cachedToken = tokenResponse.data.access_token;
|
|
116
132
|
tokenExpiresAt = now + expiresIn;
|
|
@@ -129,13 +145,16 @@ export const getAuth0Token = async (): Promise<string> => {
|
|
|
129
145
|
export const getAuth0ManagementToken = async (): Promise<string> => {
|
|
130
146
|
const audience = process.env.AUTH0_MANAGEMENT_AUDIENCE;
|
|
131
147
|
if (!audience) {
|
|
132
|
-
throw new Error(
|
|
148
|
+
throw new Error(
|
|
149
|
+
"Missing AUTH0_MANAGEMENT_AUDIENCE; cannot mint Management API token",
|
|
150
|
+
);
|
|
133
151
|
}
|
|
134
152
|
|
|
135
153
|
const grantOpts = { audience };
|
|
136
154
|
const now = Math.floor(Date.now() / 1000);
|
|
137
155
|
|
|
138
|
-
if (tokenIsValid(cachedManagementToken, managementTokenExpiresAt, now))
|
|
156
|
+
if (tokenIsValid(cachedManagementToken, managementTokenExpiresAt, now))
|
|
157
|
+
return cachedManagementToken as string;
|
|
139
158
|
if (pendingManagementTokenPromise) return pendingManagementTokenPromise;
|
|
140
159
|
|
|
141
160
|
pendingManagementTokenPromise = (async () => {
|
|
@@ -147,12 +166,17 @@ export const getAuth0ManagementToken = async (): Promise<string> => {
|
|
|
147
166
|
return cachedManagementToken;
|
|
148
167
|
}
|
|
149
168
|
|
|
150
|
-
const tokenResponse =
|
|
169
|
+
const tokenResponse =
|
|
170
|
+
await auth0AuthClient.oauth.clientCredentialsGrant(grantOpts);
|
|
151
171
|
const expiresIn = tokenResponse.data.expires_in || 3600;
|
|
152
172
|
cachedManagementToken = tokenResponse.data.access_token;
|
|
153
173
|
managementTokenExpiresAt = now + expiresIn;
|
|
154
174
|
|
|
155
|
-
await writeTokenFile(
|
|
175
|
+
await writeTokenFile(
|
|
176
|
+
MANAGEMENT_TOKEN_FILE_PATH,
|
|
177
|
+
cachedManagementToken,
|
|
178
|
+
managementTokenExpiresAt,
|
|
179
|
+
);
|
|
156
180
|
|
|
157
181
|
pendingManagementTokenPromise = null;
|
|
158
182
|
return cachedManagementToken;
|
|
@@ -172,8 +196,8 @@ export const getUserIdByEmail = async (email: string): Promise<User[]> => {
|
|
|
172
196
|
return auth0.usersByEmail.getByEmail({ email });
|
|
173
197
|
};
|
|
174
198
|
|
|
175
|
-
export const sendVerificationEmail = async (userID: string): Promise<
|
|
176
|
-
|
|
199
|
+
export const sendVerificationEmail = async (userID: string): Promise<any> => {
|
|
200
|
+
return auth0.jobs.verifyEmail({ user_id: userID });
|
|
177
201
|
};
|
|
178
202
|
|
|
179
203
|
export const getUserById = async (userId: string): Promise<User> => {
|
|
@@ -184,7 +208,10 @@ export const avatar = async (userId: string): Promise<User> => {
|
|
|
184
208
|
return auth0.users.get({ id: userId });
|
|
185
209
|
};
|
|
186
210
|
|
|
187
|
-
export const mfaEnrollAccount = async (
|
|
211
|
+
export const mfaEnrollAccount = async (
|
|
212
|
+
userId: string,
|
|
213
|
+
mfaToken: string,
|
|
214
|
+
): Promise<any> => {
|
|
188
215
|
const ticketResponse = await auth0.guardian.createEnrollmentTicket({
|
|
189
216
|
user_id: userId,
|
|
190
217
|
send_mail: false,
|
|
@@ -199,13 +226,13 @@ export const mfaDisableAccount = async (userId: string): Promise<any> => {
|
|
|
199
226
|
};
|
|
200
227
|
|
|
201
228
|
export const getUsersByIds = async (postIDs: string[]): Promise<User[]> => {
|
|
202
|
-
let q =
|
|
229
|
+
let q = "";
|
|
203
230
|
postIDs.forEach((e, i) => {
|
|
204
|
-
if (e) q = `${q} ${i >= 2 ?
|
|
231
|
+
if (e) q = `${q} ${i >= 2 ? " OR " : ""} user_id:"${e}"`;
|
|
205
232
|
});
|
|
206
233
|
|
|
207
234
|
const params = {
|
|
208
|
-
search_engine:
|
|
235
|
+
search_engine: "v3",
|
|
209
236
|
q,
|
|
210
237
|
per_page: 100,
|
|
211
238
|
page: 0,
|
package/src/config/config.ts
CHANGED
|
@@ -3,6 +3,12 @@ import dotenv from "dotenv";
|
|
|
3
3
|
// Load env from the current working directory
|
|
4
4
|
dotenv.config();
|
|
5
5
|
|
|
6
|
+
console.log("Current working directory:", process.cwd());
|
|
7
|
+
console.log("Loaded environment variables:", {
|
|
8
|
+
NODE_ENV: process.env.NODE_ENV,
|
|
9
|
+
PORT: process.env.PORT,
|
|
10
|
+
MONGODB_URL: process.env.MONGODB_URL,
|
|
11
|
+
});
|
|
6
12
|
import Joi from "joi";
|
|
7
13
|
|
|
8
14
|
const envVarsSchema = Joi.object()
|
package/src/config/logger.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import winston from "winston";
|
|
3
|
+
import type { Format } from "logform";
|
|
4
|
+
import config from "./config";
|
|
4
5
|
|
|
5
6
|
const enumerateErrorFormat: Format = winston.format((info) => {
|
|
6
7
|
if (info instanceof Error) {
|
|
@@ -10,22 +11,27 @@ const enumerateErrorFormat: Format = winston.format((info) => {
|
|
|
10
11
|
});
|
|
11
12
|
|
|
12
13
|
const logger = winston.createLogger({
|
|
13
|
-
level: config.env ===
|
|
14
|
+
level: config.env === "development" ? "debug" : "info",
|
|
14
15
|
format: winston.format.combine(
|
|
15
16
|
enumerateErrorFormat(),
|
|
16
|
-
config.env ===
|
|
17
|
+
config.env === "development"
|
|
18
|
+
? winston.format.colorize()
|
|
19
|
+
: winston.format.uncolorize(),
|
|
17
20
|
winston.format.splat(),
|
|
18
21
|
winston.format.printf((info) => {
|
|
19
|
-
const { level, message, stack, ...rest } = info as Record<
|
|
22
|
+
const { level, message, stack, ...rest } = info as Record<
|
|
23
|
+
string,
|
|
24
|
+
unknown
|
|
25
|
+
>;
|
|
20
26
|
const restKeys = Object.keys(rest);
|
|
21
|
-
const restText = restKeys.length ? ` ${JSON.stringify(rest)}` :
|
|
22
|
-
const stackText = stack ? `\n${stack}` :
|
|
27
|
+
const restText = restKeys.length ? ` ${JSON.stringify(rest)}` : "";
|
|
28
|
+
const stackText = stack ? `\n${stack}` : "";
|
|
23
29
|
return `${level}: ${message}${stackText}${restText}`;
|
|
24
30
|
}),
|
|
25
31
|
),
|
|
26
32
|
transports: [
|
|
27
33
|
new winston.transports.Console({
|
|
28
|
-
stderrLevels: [
|
|
34
|
+
stderrLevels: ["error"],
|
|
29
35
|
}),
|
|
30
36
|
],
|
|
31
37
|
});
|