@fdm-monster/server 1.5.0-rc2 → 1.5.1
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/README.md +2 -1
- package/dist/constants/authorization.constants.js +12 -0
- package/dist/constants/authorization.constants.js.map +1 -1
- package/dist/container.js +2 -1
- package/dist/container.js.map +1 -1
- package/dist/container.tokens.js +3 -1
- package/dist/container.tokens.js.map +1 -1
- package/dist/controllers/auth.controller.js +9 -5
- package/dist/controllers/auth.controller.js.map +1 -1
- package/dist/controllers/first-time-setup.controller.js +1 -3
- package/dist/controllers/first-time-setup.controller.js.map +1 -1
- package/dist/controllers/user.controller.js +72 -9
- package/dist/controllers/user.controller.js.map +1 -1
- package/dist/controllers/validation/user-controller.validation.js +3 -2
- package/dist/controllers/validation/user-controller.validation.js.map +1 -1
- package/dist/exceptions/job.exceptions.js.map +1 -1
- package/dist/exceptions/runtime.exceptions.js +3 -10
- package/dist/exceptions/runtime.exceptions.js.map +1 -1
- package/dist/middleware/authenticate.js +7 -4
- package/dist/middleware/authenticate.js.map +1 -1
- package/dist/middleware/{exception.handler.js → exception.filter.js} +6 -11
- package/dist/middleware/exception.filter.js.map +1 -0
- package/dist/middleware/global.middleware.js +1 -1
- package/dist/middleware/global.middleware.js.map +1 -1
- package/dist/middleware/passport.js +45 -16
- package/dist/middleware/passport.js.map +1 -1
- package/dist/server.constants.js +8 -2
- package/dist/server.constants.js.map +1 -1
- package/dist/server.host.js +3 -3
- package/dist/server.host.js.map +1 -1
- package/dist/services/authentication/auth.service.js +26 -15
- package/dist/services/authentication/auth.service.js.map +1 -1
- package/dist/services/authentication/refresh-token.service.js +3 -2
- package/dist/services/authentication/refresh-token.service.js.map +1 -1
- package/dist/services/authentication/role.service.js +6 -0
- package/dist/services/authentication/role.service.js.map +1 -1
- package/dist/services/authentication/user.service.js +33 -12
- package/dist/services/authentication/user.service.js.map +1 -1
- package/dist/services/influxdb-v2/influx-db-v2-base.service.js +4 -8
- package/dist/services/influxdb-v2/influx-db-v2-base.service.js.map +1 -1
- package/dist/services/interfaces/refresh-token.dto.js +20 -0
- package/dist/services/interfaces/refresh-token.dto.js.map +1 -0
- package/dist/services/interfaces/role.dto.js +16 -0
- package/dist/services/interfaces/role.dto.js.map +1 -0
- package/dist/services/octoprint/octoprint-sockio.adapter.js +7 -11
- package/dist/services/octoprint/octoprint-sockio.adapter.js.map +1 -1
- package/dist/services/settings.service.js +2 -29
- package/dist/services/settings.service.js.map +1 -1
- package/dist/services/validators/printer-service.validation.js +1 -1
- package/dist/services/validators/printer-service.validation.js.map +1 -1
- package/dist/services/validators/user-service.validation.js +1 -1
- package/dist/services/validators/user-service.validation.js.map +1 -1
- package/dist/state/settings.store.js +1 -1
- package/dist/state/settings.store.js.map +1 -1
- package/dist/state/socket-io.gateway.js +30 -3
- package/dist/state/socket-io.gateway.js.map +1 -1
- package/dist/tasks/boot.task.js +3 -3
- package/dist/tasks/boot.task.js.map +1 -1
- package/package.json +36 -36
- package/dist/middleware/exception.handler.js.map +0 -1
- package/src/index.ts +0 -19
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
-
Object.defineProperty(exports, "
|
|
5
|
+
Object.defineProperty(exports, "exceptionFilter", {
|
|
6
6
|
enumerable: true,
|
|
7
7
|
get: function() {
|
|
8
|
-
return
|
|
8
|
+
return exceptionFilter;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _runtimeexceptions = require("../exceptions/runtime.exceptions");
|
|
12
12
|
const _serverconstants = require("../server.constants");
|
|
13
13
|
const _httpstatuscodesconstants = require("../constants/http-status-codes.constants");
|
|
14
|
-
function
|
|
14
|
+
function exceptionFilter(err, req, res, next) {
|
|
15
15
|
const isTest = process.env.NODE_ENV === _serverconstants.AppConstants.defaultTestEnv;
|
|
16
16
|
if (!isTest) {
|
|
17
17
|
console.error("[API Exception Handler]", err.stack || err?.response?.data);
|
|
@@ -27,7 +27,8 @@ function exceptionHandler(err, req, res, next) {
|
|
|
27
27
|
if (err instanceof _runtimeexceptions.AuthenticationError) {
|
|
28
28
|
const code = err.statusCode || 401;
|
|
29
29
|
return res.status(code).send({
|
|
30
|
-
error: err.message
|
|
30
|
+
error: err.message,
|
|
31
|
+
reasonCode: err.reasonCode
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
if (err instanceof _runtimeexceptions.AuthorizationError) {
|
|
@@ -49,12 +50,6 @@ function exceptionHandler(err, req, res, next) {
|
|
|
49
50
|
error: err.message
|
|
50
51
|
});
|
|
51
52
|
}
|
|
52
|
-
if (err instanceof _runtimeexceptions.PasswordChangeRequiredError) {
|
|
53
|
-
const code = err.statusCode || _httpstatuscodesconstants.HttpStatusCode.CONFLICT;
|
|
54
|
-
return res.status(code).send({
|
|
55
|
-
error: err.message
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
53
|
if (err instanceof _runtimeexceptions.NotFoundException) {
|
|
59
54
|
const code = err.statusCode || 404;
|
|
60
55
|
return res.status(code).send({
|
|
@@ -99,4 +94,4 @@ function exceptionHandler(err, req, res, next) {
|
|
|
99
94
|
next();
|
|
100
95
|
}
|
|
101
96
|
|
|
102
|
-
//# sourceMappingURL=exception.
|
|
97
|
+
//# sourceMappingURL=exception.filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/middleware/exception.filter.ts"],"names":["exceptionFilter","err","req","res","next","isTest","process","env","NODE_ENV","AppConstants","defaultTestEnv","console","error","stack","response","data","isAxiosError","code","status","send","type","AuthenticationError","statusCode","message","reasonCode","AuthorizationError","HttpStatusCode","FORBIDDEN","permissions","roles","reason","ForbiddenError","NotFoundException","BadRequestException","ValidationException","name","errors","InternalServerException","ExternalServiceError"],"mappings":"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"}
|
|
@@ -35,7 +35,7 @@ const validateWizardCompleted = (0, _awilixexpress.inject)(({ settingsStore, log
|
|
|
35
35
|
"/api/test",
|
|
36
36
|
"/api/auth/login-required"
|
|
37
37
|
];
|
|
38
|
-
if (allowedPaths.includes(req.path)) {
|
|
38
|
+
if (allowedPaths.includes(req.path) || !req.path.startsWith("/api")) {
|
|
39
39
|
next();
|
|
40
40
|
return;
|
|
41
41
|
} else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/middleware/global.middleware.ts"],"names":["interceptRoles","validateWhitelistedIp","validateWizardCompleted","inject","settingsStore","loggerFactory","req","res","next","logger","name","serverSettings","getSettings","getWizardSettings","wizardCompleted","allowedPaths","includes","path","error","ForbiddenError","join","getServerSettings","whitelistEnabled","whitelist","serverSettingsKey","whitelistedIpAddresses","ipAddress","socket","remoteAddress","length","subnextMatched","find","w","
|
|
1
|
+
{"version":3,"sources":["../../src/middleware/global.middleware.ts"],"names":["interceptRoles","validateWhitelistedIp","validateWizardCompleted","inject","settingsStore","loggerFactory","req","res","next","logger","name","serverSettings","getSettings","getWizardSettings","wizardCompleted","allowedPaths","includes","path","startsWith","error","ForbiddenError","join","getServerSettings","whitelistEnabled","whitelist","serverSettingsKey","whitelistedIpAddresses","ipAddress","socket","remoteAddress","length","subnextMatched","find","w","roleService","roles","user","roleName","getAppDefaultRole"],"mappings":";;;;;;;;;;;IA+DaA,cAAc;eAAdA;;IA9BAC,qBAAqB;eAArBA;;IA1BAC,uBAAuB;eAAvBA;;;+BAPU;yCACW;mCACH;AAKxB,MAAMA,0BAA0BC,IAAAA,qBAAM,EAC3C,CAAC,EAAEC,aAAa,EAAEC,aAAa,EAAmE,GAChG,OAAOC,KAAcC,KAAeC;QAClC,MAAMC,SAASJ,cAAcJ,sBAAsBS,IAAI;QACvD,MAAMC,iBAAiBP,cAAcQ,WAAW;QAChD,IAAI,CAAC,CAACR,cAAcS,iBAAiB,IAAIC,iBAAiB;YACxDN;YACA;QACF;QAEA,MAAMO,eAAe;YACnB;YACA;YACA;YACA;SACD;QACD,IAAIA,aAAaC,QAAQ,CAACV,IAAIW,IAAI,KAAK,CAACX,IAAIW,IAAI,CAACC,UAAU,CAAC,SAAS;YACnEV;YACA;QACF,OAAO;YACLC,OAAOU,KAAK,CAAC,wBAAwBb,IAAIW,IAAI;YAC7C,MAAM,IAAIG,iCAAc,CAAC,CAAC,6DAA6D,EAAEL,aAAaM,IAAI,CAAC,MAAM,CAAC;QACpH;IACF;AAGG,MAAMpB,wBAAwBE,IAAAA,qBAAM,EACzC,CAAC,EAAEC,aAAa,EAAEC,aAAa,EAAmE,GAChG,OAAOC,KAAcC,KAAeC;QAClC,MAAMC,SAASJ,cAAcJ,sBAAsBS,IAAI;QACvD,MAAMC,iBAAiBP,cAAcQ,WAAW;QAChD,IAAI,AAAC,CAACD,kBAAkB,CAACP,cAAckB,iBAAiB,MAAO,CAAClB,cAAckB,iBAAiB,IAAIC,kBAAkB;YACnHf;YACA;QACF;QAEA,MAAMgB,YAAYb,cAAc,CAACc,0CAAiB,CAAC,CAACC,sBAAsB;QAC1E,MAAMC,YAAYrB,IAAIsB,MAAM,CAACC,aAAa;QAC1C,iDAAiD;QACjD,uDAAuD;QACvD,IAAIL,WAAWM,UAAU,CAACN,UAAUR,QAAQ,CAACW,cAAcA,cAAc,oBAAoB;YAC3F,8DAA8D;YAC9D,MAAMI,iBAAiBP,UAAUQ,IAAI,CAAC,CAACC;gBACrC,OAAON,UAAUT,UAAU,CAACe;YAC9B;YAEA,IAAI,CAACF,gBAAgB;gBACnBtB,OAAOU,KAAK,CAAC,sCAAsCb,IAAIsB,MAAM,CAACC,aAAa;gBAC3E,MAAM,IAAIT,iCAAc,CAAC,aAAad,IAAIsB,MAAM,CAACC,aAAa;YAChE;QACF;QAEArB;IACF;AAGG,MAAMR,iBAAiBG,IAAAA,qBAAM,EAClC,CAAC,EAAEC,aAAa,EAAE8B,WAAW,EAAE,GAC7B,OAAO5B,KAAcC,KAAeC;QAClC,MAAMG,iBAAiB,MAAMP,cAAcQ,WAAW;QAEtDN,IAAI6B,KAAK,GAAG7B,IAAI8B,IAAI,EAAED;QAEtB,sEAAsE;QACtE,IAAIxB,kBAAkB,CAACL,IAAI8B,IAAI,EAAE;YAC/B,MAAMC,WAAW,MAAMH,YAAYI,iBAAiB;YACpDhC,IAAI6B,KAAK,GAAG;gBAACE;aAAS;QACxB;QAEA7B;IACF"}
|
|
@@ -2,22 +2,32 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
getPassportJwtOptions: function() {
|
|
13
|
+
return getPassportJwtOptions;
|
|
14
|
+
},
|
|
15
|
+
initializePassportStrategies: function() {
|
|
8
16
|
return initializePassportStrategies;
|
|
17
|
+
},
|
|
18
|
+
verifyUserCallback: function() {
|
|
19
|
+
return verifyUserCallback;
|
|
9
20
|
}
|
|
10
21
|
});
|
|
11
22
|
const _passportjwt = require("passport-jwt");
|
|
12
23
|
const _passportanonymous = require("passport-anonymous");
|
|
13
|
-
const _models = require("../models");
|
|
14
24
|
const _containertokens = require("../container.tokens");
|
|
15
25
|
const _serverconstants = require("../server.constants");
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
jwtFromRequest:
|
|
26
|
+
const _runtimeexceptions = require("../exceptions/runtime.exceptions");
|
|
27
|
+
const _authorizationconstants = require("../constants/authorization.constants");
|
|
28
|
+
function getPassportJwtOptions(settingsStore, configService, jwtFromRequest = _passportjwt.ExtractJwt.fromAuthHeaderAsBearerToken()) {
|
|
29
|
+
return {
|
|
30
|
+
jwtFromRequest: jwtFromRequest,
|
|
21
31
|
secretOrKeyProvider: async (req, token, done)=>{
|
|
22
32
|
const { jwtSecret } = await settingsStore.getCredentialSettings();
|
|
23
33
|
return done(null, jwtSecret);
|
|
@@ -25,17 +35,36 @@ function initializePassportStrategies(passport, container) {
|
|
|
25
35
|
audience: configService.get(_serverconstants.AppConstants.OVERRIDE_JWT_AUDIENCE, _serverconstants.AppConstants.DEFAULT_JWT_AUDIENCE),
|
|
26
36
|
issuer: configService.get(_serverconstants.AppConstants.OVERRIDE_JWT_ISSUER, _serverconstants.AppConstants.DEFAULT_JWT_ISSUER)
|
|
27
37
|
};
|
|
28
|
-
|
|
29
|
-
|
|
38
|
+
}
|
|
39
|
+
function verifyUserCallback(userService) {
|
|
40
|
+
return function(jwt_payload, done) {
|
|
41
|
+
userService.getUser(jwt_payload.userId).then((user)=>{
|
|
42
|
+
if (user && user.isVerified && !user.needsPasswordChange) {
|
|
43
|
+
return done(null, user);
|
|
44
|
+
}
|
|
45
|
+
if (user && user.needsPasswordChange) {
|
|
46
|
+
console.log("Needs password change");
|
|
47
|
+
return done(new _runtimeexceptions.AuthenticationError("Password change required", _authorizationconstants.AUTH_ERROR_REASON.PasswordChangeRequired), false);
|
|
48
|
+
}
|
|
49
|
+
if (user && !user?.isVerified) {
|
|
50
|
+
console.log("Needs password change");
|
|
51
|
+
return done(new _runtimeexceptions.AuthenticationError("User not verified", _authorizationconstants.AUTH_ERROR_REASON.AccountNotVerified), false);
|
|
52
|
+
}
|
|
53
|
+
return done(null, false);
|
|
54
|
+
}).catch((err)=>{
|
|
30
55
|
if (err) {
|
|
31
56
|
return done(err, false);
|
|
32
57
|
}
|
|
33
|
-
if (user) {
|
|
34
|
-
return done(null, user);
|
|
35
|
-
} else {
|
|
36
|
-
return done(null, false);
|
|
37
|
-
}
|
|
38
58
|
});
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function initializePassportStrategies(passport, container) {
|
|
62
|
+
const settingsStore = container.resolve(_containertokens.DITokens.settingsStore);
|
|
63
|
+
const configService = container.resolve(_containertokens.DITokens.configService);
|
|
64
|
+
const userService = container.resolve(_containertokens.DITokens.userService);
|
|
65
|
+
const opts = getPassportJwtOptions(settingsStore, configService, _passportjwt.ExtractJwt.fromAuthHeaderAsBearerToken());
|
|
66
|
+
passport.use(new _passportjwt.Strategy(opts, function(jwt_payload, done) {
|
|
67
|
+
verifyUserCallback(userService)(jwt_payload, done);
|
|
39
68
|
}));
|
|
40
69
|
passport.use(new _passportanonymous.Strategy());
|
|
41
70
|
return passport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/middleware/passport.ts"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../src/middleware/passport.ts"],"names":["getPassportJwtOptions","initializePassportStrategies","verifyUserCallback","settingsStore","configService","jwtFromRequest","ExtractJwt","fromAuthHeaderAsBearerToken","secretOrKeyProvider","req","token","done","jwtSecret","getCredentialSettings","audience","get","AppConstants","OVERRIDE_JWT_AUDIENCE","DEFAULT_JWT_AUDIENCE","issuer","OVERRIDE_JWT_ISSUER","DEFAULT_JWT_ISSUER","userService","jwt_payload","getUser","userId","then","user","isVerified","needsPasswordChange","console","log","AuthenticationError","AUTH_ERROR_REASON","PasswordChangeRequired","AccountNotVerified","catch","err","passport","container","resolve","DITokens","opts","use","JwtStrategy","AnonymousStrategy"],"mappings":";;;;;;;;;;;IAkBgBA,qBAAqB;eAArBA;;IA2CAC,4BAA4B;eAA5BA;;IA3BAC,kBAAkB;eAAlBA;;;6BAlC+F;mCACjE;iCACrB;iCACI;mCAQO;wCACF;AAM3B,SAASF,sBACdG,aAA4B,EAC5BC,aAA4B,EAC5BC,iBAAiEC,uBAAU,CAACC,2BAA2B,EAAE;IAEzG,OAAO;QACLF,gBAAgBA;QAChBG,qBAAqB,OAAOC,KAAKC,OAAeC;YAC9C,MAAM,EAAEC,SAAS,EAAE,GAAG,MAAMT,cAAcU,qBAAqB;YAC/D,OAAOF,KAAK,MAAMC;QACpB;QACAE,UAAUV,cAAcW,GAAG,CAACC,6BAAY,CAACC,qBAAqB,EAAED,6BAAY,CAACE,oBAAoB;QACjGC,QAAQf,cAAcW,GAAG,CAACC,6BAAY,CAACI,mBAAmB,EAAEJ,6BAAY,CAACK,kBAAkB;IAC7F;AACF;AAEO,SAASnB,mBAAmBoB,WAAyB;IAC1D,OAAO,SAAUC,WAAgB,EAAEZ,IAAsB;QACvDW,YACGE,OAAO,CAACD,YAAYE,MAAM,EAC1BC,IAAI,CAAC,CAACC;YACL,IAAIA,QAAQA,KAAKC,UAAU,IAAI,CAACD,KAAKE,mBAAmB,EAAE;gBACxD,OAAOlB,KAAK,MAAMgB;YACpB;YACA,IAAIA,QAAQA,KAAKE,mBAAmB,EAAE;gBACpCC,QAAQC,GAAG,CAAC;gBACZ,OAAOpB,KAAK,IAAIqB,sCAAmB,CAAC,4BAA4BC,yCAAiB,CAACC,sBAAsB,GAAG;YAC7G;YACA,IAAIP,QAAQ,CAACA,MAAMC,YAAY;gBAC7BE,QAAQC,GAAG,CAAC;gBACZ,OAAOpB,KAAK,IAAIqB,sCAAmB,CAAC,qBAAqBC,yCAAiB,CAACE,kBAAkB,GAAG;YAClG;YAEA,OAAOxB,KAAK,MAAM;QACpB,GACCyB,KAAK,CAAC,CAACC;YACN,IAAIA,KAAK;gBACP,OAAO1B,KAAK0B,KAAK;YACnB;QACF;IACJ;AACF;AAEO,SAASpC,6BAA6BqC,QAAwB,EAAEC,SAA+B;IACpG,MAAMpC,gBAAgBoC,UAAUC,OAAO,CAAgBC,yBAAQ,CAACtC,aAAa;IAC7E,MAAMC,gBAAgBmC,UAAUC,OAAO,CAAgBC,yBAAQ,CAACrC,aAAa;IAC7E,MAAMkB,cAAciB,UAAUC,OAAO,CAAeC,yBAAQ,CAACnB,WAAW;IAExE,MAAMoB,OAAO1C,sBAAsBG,eAAeC,eAAeE,uBAAU,CAACC,2BAA2B;IAEvG+B,SAASK,GAAG,CACV,IAAIC,qBAAW,CAACF,MAAM,SAAUnB,WAAW,EAAEZ,IAAI;QAC/CT,mBAAmBoB,aAAaC,aAAaZ;IAC/C;IAEF2B,SAASK,GAAG,CAAC,IAAIE,2BAAiB;IAClC,OAAOP;AACT"}
|
package/dist/server.constants.js
CHANGED
|
@@ -14,6 +14,8 @@ const AppConstants = {
|
|
|
14
14
|
VERSION_KEY: "npm_package_version",
|
|
15
15
|
SERVER_PORT_KEY: "SERVER_PORT",
|
|
16
16
|
MONGO_KEY: "MONGO",
|
|
17
|
+
DATABASE_PATH: "DATABASE_PATH",
|
|
18
|
+
DATABASE_FILE: "DATABASE_FILE",
|
|
17
19
|
pm2ServiceName: "FDM",
|
|
18
20
|
logAppName: "fdm-monster",
|
|
19
21
|
// @Deprecated: old storage path
|
|
@@ -34,6 +36,8 @@ const AppConstants = {
|
|
|
34
36
|
// Boolean string (true/false), persisted always
|
|
35
37
|
OVERRIDE_REGISTRATION_ENABLED: "OVERRIDE_REGISTRATION_ENABLED",
|
|
36
38
|
// Number
|
|
39
|
+
DEFAULT_USERNAME_MINLEN: 3,
|
|
40
|
+
// Number
|
|
37
41
|
DEFAULT_PASSWORD_MINLEN: 8,
|
|
38
42
|
// String, persisted always
|
|
39
43
|
OVERRIDE_JWT_SECRET: "OVERRIDE_JWT_SECRET",
|
|
@@ -73,7 +77,7 @@ const AppConstants = {
|
|
|
73
77
|
orgName: "fdm-monster",
|
|
74
78
|
// Wizard version changes will trigger a re-run of the wizard
|
|
75
79
|
currentWizardVersion: 1,
|
|
76
|
-
defaultClientMinimum: "1.
|
|
80
|
+
defaultClientMinimum: "1.4.0",
|
|
77
81
|
influxUrl: "INFLUX_URL",
|
|
78
82
|
influxToken: "INFLUX_TOKEN",
|
|
79
83
|
influxOrg: "INFLUX_ORG",
|
|
@@ -96,7 +100,9 @@ const AppConstants = {
|
|
|
96
100
|
// Sentry
|
|
97
101
|
sentryCustomDsnToken: "SENTRY_CUSTOM_DSN",
|
|
98
102
|
sentryCustomDsnDefault: "https://164b8028a8a745bba3dbcab991b84ae7@o4503975545733120.ingest.sentry.io/4505101598261248",
|
|
99
|
-
debugRoutesKey: "DEBUG_ROUTES"
|
|
103
|
+
debugRoutesKey: "DEBUG_ROUTES",
|
|
104
|
+
enableExperimentalTypeormKey: "ENABLE_EXPERIMENTAL_TYPEORM",
|
|
105
|
+
enableExperimentalTypeormDefault: "false"
|
|
100
106
|
};
|
|
101
107
|
|
|
102
108
|
//# sourceMappingURL=server.constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.constants.ts"],"names":["AppConstants","NON_NPM_MODE_KEY","NODE_ENV_KEY","VERSION_KEY","SERVER_PORT_KEY","MONGO_KEY","pm2ServiceName","logAppName","defaultFileStorageFolder","defaultLogsFolder","defaultLogZipsFolder","defaultClientBundleStorage","defaultClientBundleZipsStorage","defaultServerPort","defaultMongoStringUnauthenticated","apiRoute","enableClientDistAutoUpdateKey","ENABLE_EXPERIMENTAL_WHITELIST_SETTINGS","OVERRIDE_LOGIN_REQUIRED","OVERRIDE_REGISTRATION_ENABLED","DEFAULT_PASSWORD_MINLEN","OVERRIDE_JWT_SECRET","OVERRIDE_JWT_EXPIRES_IN","DEFAULT_JWT_EXPIRES_IN","DEFAULT_REFRESH_TOKEN_ATTEMPTS","DEFAULT_REFRESH_TOKEN_EXPIRY","OVERRIDE_JWT_ISSUER","DEFAULT_JWT_ISSUER","OVERRIDE_JWT_AUDIENCE","DEFAULT_JWT_AUDIENCE","OVERRIDE_IS_DEMO_MODE","OVERRIDE_DEMO_USERNAME","DEFAULT_DEMO_USERNAME","OVERRIDE_DEMO_PASSWORD","DEFAULT_DEMO_PASSWORD","OVERRIDE_DEMO_ROLE","DEFAULT_DEMO_ROLE","defaultDevelopmentEnv","defaultTestEnv","defaultProductionEnv","knownEnvNames","GITHUB_PAT","serverPackageName","clientPackageName","clientRepoName","serverRepoName","orgName","currentWizardVersion","defaultClientMinimum","influxUrl","influxToken","influxOrg","influxBucket","defaultWebsocketHandshakeTimeout","defaultSocketThrottleRate","debugSocketStatesKey","defaultDebugSocketStates","enableMqttAutoDiscoveryToken","enableMqttAutoDiscoveryDefault","mqttUrlToken","mqttPortToken","mqttPortDefault","mqttUsernameToken","mqttPasswordToken","monsterPiFilePath","sentryCustomDsnToken","sentryCustomDsnDefault","debugRoutesKey"],"mappings":";;;;+BAAaA;;;eAAAA;;;AAAN,MAAMA,eAAe;IAC1BC,kBAAkB;IAClBC,cAAc;IACdC,aAAa;IACbC,iBAAiB;IACjBC,WAAW;
|
|
1
|
+
{"version":3,"sources":["../src/server.constants.ts"],"names":["AppConstants","NON_NPM_MODE_KEY","NODE_ENV_KEY","VERSION_KEY","SERVER_PORT_KEY","MONGO_KEY","DATABASE_PATH","DATABASE_FILE","pm2ServiceName","logAppName","defaultFileStorageFolder","defaultLogsFolder","defaultLogZipsFolder","defaultClientBundleStorage","defaultClientBundleZipsStorage","defaultServerPort","defaultMongoStringUnauthenticated","apiRoute","enableClientDistAutoUpdateKey","ENABLE_EXPERIMENTAL_WHITELIST_SETTINGS","OVERRIDE_LOGIN_REQUIRED","OVERRIDE_REGISTRATION_ENABLED","DEFAULT_USERNAME_MINLEN","DEFAULT_PASSWORD_MINLEN","OVERRIDE_JWT_SECRET","OVERRIDE_JWT_EXPIRES_IN","DEFAULT_JWT_EXPIRES_IN","DEFAULT_REFRESH_TOKEN_ATTEMPTS","DEFAULT_REFRESH_TOKEN_EXPIRY","OVERRIDE_JWT_ISSUER","DEFAULT_JWT_ISSUER","OVERRIDE_JWT_AUDIENCE","DEFAULT_JWT_AUDIENCE","OVERRIDE_IS_DEMO_MODE","OVERRIDE_DEMO_USERNAME","DEFAULT_DEMO_USERNAME","OVERRIDE_DEMO_PASSWORD","DEFAULT_DEMO_PASSWORD","OVERRIDE_DEMO_ROLE","DEFAULT_DEMO_ROLE","defaultDevelopmentEnv","defaultTestEnv","defaultProductionEnv","knownEnvNames","GITHUB_PAT","serverPackageName","clientPackageName","clientRepoName","serverRepoName","orgName","currentWizardVersion","defaultClientMinimum","influxUrl","influxToken","influxOrg","influxBucket","defaultWebsocketHandshakeTimeout","defaultSocketThrottleRate","debugSocketStatesKey","defaultDebugSocketStates","enableMqttAutoDiscoveryToken","enableMqttAutoDiscoveryDefault","mqttUrlToken","mqttPortToken","mqttPortDefault","mqttUsernameToken","mqttPasswordToken","monsterPiFilePath","sentryCustomDsnToken","sentryCustomDsnDefault","debugRoutesKey","enableExperimentalTypeormKey","enableExperimentalTypeormDefault"],"mappings":";;;;+BAAaA;;;eAAAA;;;AAAN,MAAMA,eAAe;IAC1BC,kBAAkB;IAClBC,cAAc;IACdC,aAAa;IACbC,iBAAiB;IACjBC,WAAW;IACXC,eAAe;IACfC,eAAe;IAEfC,gBAAgB;IAChBC,YAAY;IAEZ,gCAAgC;IAChCC,0BAA0B;IAC1BC,mBAAmB;IACnBC,sBAAsB;IACtB,yCAAyC;IACzCC,4BAA4B;IAC5BC,gCAAgC;IAChCC,mBAAmB;IACnBC,mCAAmC;IACnCC,UAAU;IACVC,+BAA+B;IAE/B,qFAAqF;IACrFC,wCAAwC;IACxC,gDAAgD;IAChDC,yBAAyB;IACzB,gDAAgD;IAChDC,+BAA+B;IAC/B,SAAS;IACTC,yBAAyB;IACzB,SAAS;IACTC,yBAAyB;IACzB,2BAA2B;IAC3BC,qBAAqB;IACrB,oCAAoC;IACpCC,yBAAyB;IACzBC,wBAAwB,KAAK;IAC7B,SAAS;IACTC,gCAAgC,CAAC;IACjC,wBAAwB;IACxBC,8BAA8B,KAAK,KAAK,KAAK;IAC7C,wBAAwB;IACxBC,qBAAqB;IACrBC,oBAAoB;IACpB,wBAAwB;IACxBC,uBAAuB;IACvBC,sBAAsB;IAEtBC,uBAAuB;IACvBC,wBAAwB;IACxBC,uBAAuB;IACvBC,wBAAwB;IACxBC,uBAAuB;IACvBC,oBAAoB;IACpBC,mBAAmB;IAEnBC,uBAAuB;IACvBC,gBAAgB;IAChBC,sBAAsB;IACtBC,eAAe;QAAC;QAAe;QAAc;KAAO;IACpDC,YAAY;IACZC,mBAAmB;IACnBC,mBAAmB;IACnBC,gBAAgB;IAChBC,gBAAgB;IAChBC,SAAS;IACT,6DAA6D;IAC7DC,sBAAsB;IACtBC,sBAAsB;IAEtBC,WAAW;IACXC,aAAa;IACbC,WAAW;IACXC,cAAc;IAEd,mBAAmB;IACnBC,kCAAkC;IAClCC,2BAA2B;IAC3BC,sBAAsB;IACtBC,0BAA0B;IAE1B,8BAA8B;IAC9BC,8BAA8B;IAC9BC,gCAAgC;IAChCC,cAAc;IACdC,eAAe;IACfC,iBAAiB;IACjBC,mBAAmB;IACnBC,mBAAmB;IAEnB,YAAY;IACZC,mBAAmB;IAEnB,SAAS;IACTC,sBAAsB;IACtBC,wBAAwB;IAExBC,gBAAgB;IAEhBC,8BAA8B;IAC9BC,kCAAkC;AACpC"}
|
package/dist/server.host.js
CHANGED
|
@@ -13,7 +13,7 @@ const _mongoose = /*#__PURE__*/ _interop_require_default(require("mongoose"));
|
|
|
13
13
|
const _connecthistoryapifallback = /*#__PURE__*/ _interop_require_default(require("connect-history-api-fallback"));
|
|
14
14
|
const _awilixexpress = require("awilix-express");
|
|
15
15
|
const _path = require("path");
|
|
16
|
-
const
|
|
16
|
+
const _exceptionfilter = require("./middleware/exception.filter");
|
|
17
17
|
const _serverenv = require("./server.env");
|
|
18
18
|
const _runtimeexceptions = require("./exceptions/runtime.exceptions");
|
|
19
19
|
const _serverconstants = require("./server.constants");
|
|
@@ -63,7 +63,7 @@ class ServerHost {
|
|
|
63
63
|
}).use((0, _awilixexpress.loadControllers)(`${routePath}/*.controller.*`, {
|
|
64
64
|
cwd: __dirname,
|
|
65
65
|
ignore: "**/*.map"
|
|
66
|
-
})).use(
|
|
66
|
+
})).use(_exceptionfilter.exceptionFilter);
|
|
67
67
|
// Serve the files for our frontend - do this later than the controllers
|
|
68
68
|
const bundleDistPath = (0, _path.join)((0, _fsutils.superRootPath)(), _serverconstants.AppConstants.defaultClientBundleStorage, "dist");
|
|
69
69
|
app.use(_express.default.static(bundleDistPath));
|
|
@@ -82,7 +82,7 @@ class ServerHost {
|
|
|
82
82
|
if (!path.startsWith("/socket.io")) {
|
|
83
83
|
throw new _runtimeexceptions.NotFoundException(`${resource} resource was not found`, path);
|
|
84
84
|
}
|
|
85
|
-
}).use(
|
|
85
|
+
}).use(_exceptionfilter.exceptionFilter);
|
|
86
86
|
}
|
|
87
87
|
async httpListen() {
|
|
88
88
|
const port = (0, _serverenv.fetchServerPort)();
|
package/dist/server.host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.host.ts"],"names":["ServerHost","bootTask","taskManagerService","socketIoGateway","appInstance","configService","logger","constructor","loggerFactory","name","boot","app","quick_boot","listenRequests","mongoose","set","serveControllerRoutes","runOnce","httpListen","hasConnected","connections","readyState","routePath","use","req","res","next","originalUrl","startsWith","history","loadControllers","cwd","__dirname","ignore","
|
|
1
|
+
{"version":3,"sources":["../src/server.host.ts"],"names":["ServerHost","bootTask","taskManagerService","socketIoGateway","appInstance","configService","logger","constructor","loggerFactory","name","boot","app","quick_boot","listenRequests","mongoose","set","serveControllerRoutes","runOnce","httpListen","hasConnected","connections","readyState","routePath","use","req","res","next","originalUrl","startsWith","history","loadControllers","cwd","__dirname","ignore","exceptionFilter","bundleDistPath","join","superRootPath","AppConstants","defaultClientBundleStorage","express","static","backupClientPath","clientPackageName","get","path","resource","endsWith","error","NotFoundException","port","fetchServerPort","isProductionEnvironment","debugRoutesKey","expressListRoutes","require","prefix","Number","isNaN","parseInt","Error","hostOrFqdn","server","listen","log","attachServer"],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "AuthService", {
|
|
|
10
10
|
});
|
|
11
11
|
const _runtimeexceptions = require("../../exceptions/runtime.exceptions");
|
|
12
12
|
const _cryptoutils = require("../../utils/crypto.utils");
|
|
13
|
+
const _authorizationconstants = require("../../constants/authorization.constants");
|
|
13
14
|
class AuthService {
|
|
14
15
|
logger;
|
|
15
16
|
userService;
|
|
@@ -43,16 +44,16 @@ class AuthService {
|
|
|
43
44
|
async loginUser(username, password) {
|
|
44
45
|
const userDoc = await this.userService.findRawByUsername(username);
|
|
45
46
|
if (!userDoc) {
|
|
46
|
-
throw new _runtimeexceptions.AuthenticationError("Login incorrect");
|
|
47
|
+
throw new _runtimeexceptions.AuthenticationError("Login incorrect", _authorizationconstants.AUTH_ERROR_REASON.IncorrectCredentials);
|
|
47
48
|
}
|
|
48
49
|
const result = (0, _cryptoutils.comparePasswordHash)(password, userDoc.passwordHash);
|
|
49
50
|
if (!result) {
|
|
50
|
-
throw new _runtimeexceptions.AuthenticationError("Login incorrect");
|
|
51
|
+
throw new _runtimeexceptions.AuthenticationError("Login incorrect", _authorizationconstants.AUTH_ERROR_REASON.IncorrectCredentials);
|
|
51
52
|
}
|
|
52
53
|
const userId = userDoc.id.toString();
|
|
53
54
|
const token = await this.signJwtToken(userId);
|
|
54
55
|
await this.refreshTokenService.purgeOutdatedRefreshTokensByUserId(userId);
|
|
55
|
-
await this.
|
|
56
|
+
await this.purgeOutdatedBlacklistedJwtCache();
|
|
56
57
|
const refreshToken = await this.refreshTokenService.createRefreshTokenForUserId(userId);
|
|
57
58
|
return {
|
|
58
59
|
token,
|
|
@@ -66,10 +67,10 @@ class AuthService {
|
|
|
66
67
|
userId,
|
|
67
68
|
createdAt: Date.now()
|
|
68
69
|
};
|
|
69
|
-
await this.
|
|
70
|
+
await this.purgeOutdatedBlacklistedJwtCache();
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
async
|
|
73
|
+
async purgeOutdatedBlacklistedJwtCache() {
|
|
73
74
|
try {
|
|
74
75
|
const { jwtExpiresIn } = await this.settingsStore.getCredentialSettings();
|
|
75
76
|
const now = Date.now();
|
|
@@ -91,9 +92,15 @@ class AuthService {
|
|
|
91
92
|
async renewLoginByRefreshToken(refreshToken) {
|
|
92
93
|
const userRefreshToken = await this.getValidRefreshToken(refreshToken, false);
|
|
93
94
|
if (!userRefreshToken) {
|
|
94
|
-
throw new _runtimeexceptions.AuthenticationError("The refresh token was invalid or expired, could not refresh user token");
|
|
95
|
+
throw new _runtimeexceptions.AuthenticationError("The refresh token was invalid or expired, could not refresh user token", _authorizationconstants.AUTH_ERROR_REASON.InvalidOrExpiredRefreshToken);
|
|
95
96
|
}
|
|
96
97
|
const userId = userRefreshToken.userId.toString();
|
|
98
|
+
const user = await this.userService.getUser(userId, false);
|
|
99
|
+
if (!user) {
|
|
100
|
+
await this.refreshTokenService.deleteRefreshToken(refreshToken);
|
|
101
|
+
throw new _runtimeexceptions.AuthenticationError("User not found", _authorizationconstants.AUTH_ERROR_REASON.InvalidOrExpiredRefreshToken);
|
|
102
|
+
}
|
|
103
|
+
// If the user is not found at this point, then the user was deleted
|
|
97
104
|
const token = await this.signJwtToken(userId);
|
|
98
105
|
await this.increaseRefreshTokenAttemptsUsed(userRefreshToken.refreshToken);
|
|
99
106
|
return token;
|
|
@@ -108,29 +115,33 @@ class AuthService {
|
|
|
108
115
|
}
|
|
109
116
|
if (Date.now() > userRefreshToken.expiresAt) {
|
|
110
117
|
await this.refreshTokenService.deleteRefreshTokenByUserId(userRefreshToken.userId.toString());
|
|
111
|
-
throw new _runtimeexceptions.AuthenticationError("Refresh token expired, login required");
|
|
118
|
+
throw new _runtimeexceptions.AuthenticationError("Refresh token expired, login required", _authorizationconstants.AUTH_ERROR_REASON.InvalidOrExpiredRefreshToken);
|
|
112
119
|
}
|
|
113
120
|
return userRefreshToken;
|
|
114
121
|
}
|
|
115
122
|
async increaseRefreshTokenAttemptsUsed(refreshToken) {
|
|
116
123
|
const { refreshTokenAttempts } = await this.settingsStore.getCredentialSettings();
|
|
117
124
|
const userRefreshToken = await this.getValidRefreshToken(refreshToken);
|
|
118
|
-
// If no attempts are set, then we don't care about attempts
|
|
119
|
-
if (refreshTokenAttempts < 0) return;
|
|
120
125
|
const attemptsUsed = userRefreshToken.refreshAttemptsUsed;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
// If no attempts are set, then we don't care about attempts
|
|
127
|
+
if (refreshTokenAttempts !== -1) {
|
|
128
|
+
if (attemptsUsed >= refreshTokenAttempts) {
|
|
129
|
+
await this.refreshTokenService.deleteRefreshTokenByUserId(userRefreshToken.userId.toString());
|
|
130
|
+
throw new _runtimeexceptions.AuthenticationError("Refresh token attempts exceeded, login required", _authorizationconstants.AUTH_ERROR_REASON.InvalidOrExpiredRefreshToken);
|
|
131
|
+
}
|
|
124
132
|
}
|
|
125
133
|
await this.refreshTokenService.updateRefreshTokenAttempts(refreshToken, attemptsUsed + 1);
|
|
126
134
|
}
|
|
127
135
|
async signJwtToken(userId) {
|
|
128
|
-
const user = await this.userService.getUser(userId);
|
|
136
|
+
const user = await this.userService.getUser(userId, false);
|
|
137
|
+
if (!user) {
|
|
138
|
+
throw new _runtimeexceptions.AuthenticationError("User not found", _authorizationconstants.AUTH_ERROR_REASON.InvalidOrExpiredRefreshToken);
|
|
139
|
+
}
|
|
129
140
|
if (user.needsPasswordChange) {
|
|
130
|
-
throw new _runtimeexceptions.
|
|
141
|
+
throw new _runtimeexceptions.AuthenticationError("Password change required", _authorizationconstants.AUTH_ERROR_REASON.PasswordChangeRequired);
|
|
131
142
|
}
|
|
132
143
|
if (!user.isVerified) {
|
|
133
|
-
throw new _runtimeexceptions.AuthenticationError("User is not verified yet");
|
|
144
|
+
throw new _runtimeexceptions.AuthenticationError("User is not verified yet", _authorizationconstants.AUTH_ERROR_REASON.AccountNotVerified);
|
|
134
145
|
}
|
|
135
146
|
return this.jwtService.signJwtToken(userId, user.username);
|
|
136
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/authentication/auth.service.ts"],"names":["AuthService","logger","userService","jwtService","settingsStore","refreshTokenService","blacklistedJwtCache","constructor","loggerFactory","name","loginUser","username","password","userDoc","findRawByUsername","AuthenticationError","result","comparePasswordHash","passwordHash","userId","id","toString","token","signJwtToken","purgeOutdatedRefreshTokensByUserId","
|
|
1
|
+
{"version":3,"sources":["../../../src/services/authentication/auth.service.ts"],"names":["AuthService","logger","userService","jwtService","settingsStore","refreshTokenService","blacklistedJwtCache","constructor","loggerFactory","name","loginUser","username","password","userDoc","findRawByUsername","AuthenticationError","AUTH_ERROR_REASON","IncorrectCredentials","result","comparePasswordHash","passwordHash","userId","id","toString","token","signJwtToken","purgeOutdatedRefreshTokensByUserId","purgeOutdatedBlacklistedJwtCache","refreshToken","createRefreshTokenForUserId","logoutUserId","jwtToken","deleteRefreshTokenByUserId","length","createdAt","Date","now","jwtExpiresIn","getCredentialSettings","keys","Object","key","err","error","logoutUserRefreshToken","userRefreshToken","getValidRefreshToken","renewLoginByRefreshToken","InvalidOrExpiredRefreshToken","user","getUser","deleteRefreshToken","increaseRefreshTokenAttemptsUsed","isJwtTokenBlacklisted","throwNotFoundError","getRefreshToken","expiresAt","refreshTokenAttempts","attemptsUsed","refreshAttemptsUsed","updateRefreshTokenAttempts","needsPasswordChange","PasswordChangeRequired","isVerified","AccountNotVerified"],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ const _models = require("../../models");
|
|
|
12
12
|
const _uuid = require("uuid");
|
|
13
13
|
const _serverconstants = require("../../server.constants");
|
|
14
14
|
const _runtimeexceptions = require("../../exceptions/runtime.exceptions");
|
|
15
|
+
const _authorizationconstants = require("../../constants/authorization.constants");
|
|
15
16
|
class RefreshTokenService {
|
|
16
17
|
settingsStore;
|
|
17
18
|
logger;
|
|
@@ -25,7 +26,7 @@ class RefreshTokenService {
|
|
|
25
26
|
});
|
|
26
27
|
if (!userRefreshToken) {
|
|
27
28
|
if (throwNotFoundError) {
|
|
28
|
-
throw new _runtimeexceptions.AuthenticationError("The refresh token was not found");
|
|
29
|
+
throw new _runtimeexceptions.AuthenticationError("The refresh token was not found", _authorizationconstants.AUTH_ERROR_REASON.InvalidOrExpiredRefreshToken);
|
|
29
30
|
}
|
|
30
31
|
return null;
|
|
31
32
|
}
|
|
@@ -47,7 +48,7 @@ class RefreshTokenService {
|
|
|
47
48
|
return refreshToken;
|
|
48
49
|
}
|
|
49
50
|
async updateRefreshTokenAttempts(refreshToken, refreshAttemptsUsed) {
|
|
50
|
-
await this.getRefreshToken(refreshToken);
|
|
51
|
+
await this.getRefreshToken(refreshToken, true);
|
|
51
52
|
await _models.RefreshToken.updateOne({
|
|
52
53
|
refreshToken
|
|
53
54
|
}, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/authentication/refresh-token.service.ts"],"names":["RefreshTokenService","settingsStore","logger","constructor","loggerFactory","name","getRefreshToken","refreshToken","throwNotFoundError","userRefreshToken","RefreshToken","findOne","AuthenticationError","createRefreshTokenForUserId","userId","refreshTokenExpiry","getCredentialSettings","uuidv4","timespan","AppConstants","DEFAULT_REFRESH_TOKEN_EXPIRY","warn","create","expiresAt","Date","now","refreshAttemptsUsed","updateRefreshTokenAttempts","updateOne","new","purgeOutdatedRefreshTokensByUserId","result","deleteMany","$lt","deletedCount","debug","purgeAllOutdatedRefreshTokens","deleteRefreshTokenByUserId","deleteRefreshToken","deleteOne"],"mappings":";;;;+
|
|
1
|
+
{"version":3,"sources":["../../../src/services/authentication/refresh-token.service.ts"],"names":["RefreshTokenService","settingsStore","logger","constructor","loggerFactory","name","getRefreshToken","refreshToken","throwNotFoundError","userRefreshToken","RefreshToken","findOne","AuthenticationError","AUTH_ERROR_REASON","InvalidOrExpiredRefreshToken","createRefreshTokenForUserId","userId","refreshTokenExpiry","getCredentialSettings","uuidv4","timespan","AppConstants","DEFAULT_REFRESH_TOKEN_EXPIRY","warn","create","expiresAt","Date","now","refreshAttemptsUsed","updateRefreshTokenAttempts","updateOne","new","purgeOutdatedRefreshTokensByUserId","result","deleteMany","$lt","deletedCount","debug","purgeAllOutdatedRefreshTokens","deleteRefreshTokenByUserId","deleteRefreshToken","deleteOne"],"mappings":";;;;+BAYaA;;;eAAAA;;;wBAVgB;sBACA;iCACA;mCAIO;wCAEF;AAE3B,MAAMA;IACHC,cAA6B;IAC7BC,OAAsB;IAE9BC,YAAY,EAAEC,aAAa,EAAEH,aAAa,EAAmE,CAAE;QAC7G,IAAI,CAACC,MAAM,GAAGE,cAAcJ,oBAAoBK,IAAI;QACpD,IAAI,CAACJ,aAAa,GAAGA;IACvB;IAEA,MAAMK,gBAAgBC,YAAoB,EAAEC,qBAAqB,IAAI,EAAiC;QACpG,MAAMC,mBAAmB,MAAMC,oBAAY,CAACC,OAAO,CAAC;YAClDJ;QACF;QACA,IAAI,CAACE,kBAAkB;YACrB,IAAID,oBAAoB;gBACtB,MAAM,IAAII,sCAAmB,CAAC,mCAAmCC,yCAAiB,CAACC,4BAA4B;YACjH;YACA,OAAO;QACT;QACA,OAAOL;IACT;IAEA,MAAMM,4BAA4BC,MAAmB,EAAmB;QACtE,MAAM,EAAEC,kBAAkB,EAAE,GAAG,MAAM,IAAI,CAAChB,aAAa,CAACiB,qBAAqB;QAC7E,MAAMX,eAAeY,IAAAA,QAAM;QAE3B,MAAMC,WAAWH,sBAAsBI,6BAAY,CAACC,4BAA4B;QAChF,IAAI,CAACL,oBAAoB;YACvB,IAAI,CAACf,MAAM,CAACqB,IAAI,CAAC,CAAC,oEAAoE,EAAEH,SAAS,SAAS,CAAC;QAC7G;QAEA,MAAMV,oBAAY,CAACc,MAAM,CAAC;YACxBR;YACAS,WAAWC,KAAKC,GAAG,KAAKP,WAAW;YACnCb;YACAqB,qBAAqB;QACvB;QAEA,OAAOrB;IACT;IAEA,MAAMsB,2BAA2BtB,YAAoB,EAAEqB,mBAA2B,EAAE;QAClF,MAAM,IAAI,CAACtB,eAAe,CAACC,cAAc;QAEzC,MAAMG,oBAAY,CAACoB,SAAS,CAC1B;YACEvB;QACF,GACA;YACEqB;QACF,GACA;YACEG,KAAK;QACP;IAEJ;IAEA,MAAMC,mCAAmChB,MAAmB,EAAE;QAC5D,MAAMiB,SAAS,MAAMvB,oBAAY,CAACwB,UAAU,CAAC;YAC3ClB;YACAS,WAAW;gBACTU,KAAKT,KAAKC,GAAG;YACf;QACF;QAEA,IAAIM,OAAOG,YAAY,EAAE;YACvB,IAAI,CAAClC,MAAM,CAACmC,KAAK,CAAC,CAAC,QAAQ,EAAEJ,OAAOG,YAAY,CAAC,wCAAwC,EAAEpB,OAAO,CAAC;QACrG;IACF;IAEA,MAAMsB,gCAAgC;QACpC,MAAML,SAAS,MAAMvB,oBAAY,CAACwB,UAAU,CAAC;YAC3CT,WAAW;gBACTU,KAAKT,KAAKC,GAAG;YACf;QACF;QAEA,IAAIM,OAAOG,YAAY,EAAE;YACvB,IAAI,CAAClC,MAAM,CAACmC,KAAK,CAAC,CAAC,QAAQ,EAAEJ,OAAOG,YAAY,CAAC,8BAA8B,CAAC;QAClF;IACF;IAEA,MAAMG,2BAA2BvB,MAAmB,EAAiB;QACnE,MAAMiB,SAAS,MAAMvB,oBAAY,CAACwB,UAAU,CAAC;YAC3ClB;QACF;QAEA,IAAIiB,OAAOG,YAAY,EAAE;YACvB,IAAI,CAAClC,MAAM,CAACmC,KAAK,CAAC,CAAC,QAAQ,EAAEJ,OAAOG,YAAY,CAAC,qBAAqB,CAAC;QACzE;IACF;IAEA,MAAMI,mBAAmBjC,YAAoB,EAAiB;QAC5D,MAAM0B,SAAS,MAAMvB,oBAAY,CAAC+B,SAAS,CAAC;YAC1ClC;QACF;QAEA,oBAAoB;QACpB,IAAI0B,OAAOG,YAAY,EAAE;YACvB,IAAI,CAAClC,MAAM,CAACmC,KAAK,CAAC,CAAC,QAAQ,EAAEJ,OAAOG,YAAY,CAAC,qBAAqB,CAAC;QACzE;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/authentication/role.service.ts"],"names":["RoleService","logger","settingsStore","appDefaultRole","appDefaultRoleNoLogin","constructor","loggerFactory","name","_roles","roles","getAppDefaultRole","getLoginRequired","getRolesPermissions","permissions","length","
|
|
1
|
+
{"version":3,"sources":["../../../src/services/authentication/role.service.ts"],"names":["RoleService","logger","settingsStore","appDefaultRole","appDefaultRoleNoLogin","constructor","loggerFactory","name","_roles","toDto","role","id","roles","getAppDefaultRole","getLoginRequired","getRolesPermissions","permissions","length","normalizedRole","normalizeRoleIdOrName","rolePermissions","getRolePermissions","union","ROLE_PERMS","getAppDefaultRoleIds","syncRoles","guestRole","getRoleByName","getSynchronizedRoleByName","roleName","authorizeRole","requiredRole","assignedRoles","find","ar","authorizeRoles","requiredRoles","subset","isAuthorized","forEach","rr","result","r","NotFoundException","getManyRoles","roleIds","map","roleId","getRole","Object","values","ROLES","storedRole","Role","findOne","newRole","create","push","assignedRole","roleInstance","console","warn"],"mappings":"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"}
|
|
@@ -34,7 +34,7 @@ class UserService {
|
|
|
34
34
|
async listUsers(limit = 10) {
|
|
35
35
|
return _models.User.find().limit(limit);
|
|
36
36
|
}
|
|
37
|
-
async
|
|
37
|
+
async findUsersByRoleId(roleId) {
|
|
38
38
|
return _models.User.find({
|
|
39
39
|
roles: {
|
|
40
40
|
$in: [
|
|
@@ -43,6 +43,19 @@ class UserService {
|
|
|
43
43
|
}
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
+
async findVerifiedUsers() {
|
|
47
|
+
return _models.User.find({
|
|
48
|
+
isVerified: true
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async isUserRootUser(userId) {
|
|
52
|
+
return (await _models.User.findById(userId))?.isRootUser;
|
|
53
|
+
}
|
|
54
|
+
async findRootUsers() {
|
|
55
|
+
return _models.User.find({
|
|
56
|
+
isRootUser: true
|
|
57
|
+
});
|
|
58
|
+
}
|
|
46
59
|
async getDemoUserId() {
|
|
47
60
|
return (await _models.User.findOne({
|
|
48
61
|
isDemoUser: true
|
|
@@ -53,12 +66,12 @@ class UserService {
|
|
|
53
66
|
username
|
|
54
67
|
});
|
|
55
68
|
}
|
|
56
|
-
async getUser(userId) {
|
|
69
|
+
async getUser(userId, throwNotFoundError = true) {
|
|
57
70
|
const user = await _models.User.findById(userId);
|
|
58
|
-
if (!user) throw new _runtimeexceptions.NotFoundException("User not found");
|
|
71
|
+
if (!user && throwNotFoundError) throw new _runtimeexceptions.NotFoundException("User not found");
|
|
59
72
|
return user;
|
|
60
73
|
}
|
|
61
|
-
async
|
|
74
|
+
async getUserRoleIds(userId) {
|
|
62
75
|
const user = await this.getUser(userId);
|
|
63
76
|
return user.roles?.map((r)=>r.toString());
|
|
64
77
|
}
|
|
@@ -73,10 +86,13 @@ class UserService {
|
|
|
73
86
|
async deleteUser(userId) {
|
|
74
87
|
// Validate
|
|
75
88
|
const user = await this.getUser(userId);
|
|
89
|
+
if (user.isRootUser) {
|
|
90
|
+
throw new _runtimeexceptions.InternalServerException("Cannot delete a root user.");
|
|
91
|
+
}
|
|
76
92
|
// Check if the user is the last admin
|
|
77
93
|
const role = this.roleService.getRoleByName(_authorizationconstants.ROLES.ADMIN);
|
|
78
94
|
if (user.roles.includes(role.id)) {
|
|
79
|
-
const administrators = await this.
|
|
95
|
+
const administrators = await this.findUsersByRoleId(role.id);
|
|
80
96
|
if (administrators?.length === 1) {
|
|
81
97
|
throw new _runtimeexceptions.InternalServerException("Cannot delete the last user with ADMIN role.");
|
|
82
98
|
}
|
|
@@ -102,7 +118,7 @@ class UserService {
|
|
|
102
118
|
user.needsPasswordChange = false;
|
|
103
119
|
return await user.save();
|
|
104
120
|
}
|
|
105
|
-
async
|
|
121
|
+
async updatePasswordUnsafeByUsername(username, newPassword) {
|
|
106
122
|
const { password } = await (0, _validators.validateInput)({
|
|
107
123
|
password: newPassword
|
|
108
124
|
}, _userservicevalidation.newPasswordRules);
|
|
@@ -117,9 +133,10 @@ class UserService {
|
|
|
117
133
|
const user = await _models.User.findById(userId);
|
|
118
134
|
if (!user) throw new _runtimeexceptions.NotFoundException("User not found");
|
|
119
135
|
if (!isRootUser) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
136
|
+
// Ensure at least one user is root user
|
|
137
|
+
const rootUsers = await this.findRootUsers();
|
|
138
|
+
if (rootUsers.length === 1) {
|
|
139
|
+
throw new _runtimeexceptions.InternalServerException("Cannot set the last root user to non-root user.");
|
|
123
140
|
}
|
|
124
141
|
}
|
|
125
142
|
user.isRootUser = isRootUser;
|
|
@@ -129,9 +146,13 @@ class UserService {
|
|
|
129
146
|
const user = await _models.User.findById(userId);
|
|
130
147
|
if (!user) throw new _runtimeexceptions.NotFoundException("User not found");
|
|
131
148
|
if (!isVerified) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
149
|
+
if (user.isRootUser) {
|
|
150
|
+
throw new _runtimeexceptions.InternalServerException("Cannot set a owner (root user) to unverified.");
|
|
151
|
+
}
|
|
152
|
+
// Ensure at least one user is verified
|
|
153
|
+
const verifiedUsers = await this.findVerifiedUsers();
|
|
154
|
+
if (verifiedUsers.length === 1) {
|
|
155
|
+
throw new _runtimeexceptions.InternalServerException("Cannot set the last user to unverified.");
|
|
135
156
|
}
|
|
136
157
|
}
|
|
137
158
|
user.isVerified = isVerified;
|