@hed-hog/core 0.0.139 → 0.0.141

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.
Files changed (59) hide show
  1. package/dist/auth/auth.service.js +3 -3
  2. package/dist/auth/auth.service.js.map +1 -1
  3. package/dist/menu/dto/update.dto.d.ts +1 -0
  4. package/dist/menu/dto/update.dto.d.ts.map +1 -1
  5. package/dist/menu/dto/update.dto.js +4 -0
  6. package/dist/menu/dto/update.dto.js.map +1 -1
  7. package/dist/menu/menu.controller.d.ts +4 -16
  8. package/dist/menu/menu.controller.d.ts.map +1 -1
  9. package/dist/menu/menu.controller.js +26 -47
  10. package/dist/menu/menu.controller.js.map +1 -1
  11. package/dist/menu/menu.service.d.ts +3 -3
  12. package/dist/menu/menu.service.d.ts.map +1 -1
  13. package/dist/menu/menu.service.js +54 -6
  14. package/dist/menu/menu.service.js.map +1 -1
  15. package/dist/role/guards/role.guard.d.ts.map +1 -1
  16. package/dist/role/guards/role.guard.js +4 -1
  17. package/dist/role/guards/role.guard.js.map +1 -1
  18. package/dist/role/role.controller.d.ts +2 -2
  19. package/dist/role/role.controller.d.ts.map +1 -1
  20. package/dist/role/role.controller.js +8 -6
  21. package/dist/role/role.controller.js.map +1 -1
  22. package/dist/role/role.service.d.ts +2 -2
  23. package/dist/role/role.service.d.ts.map +1 -1
  24. package/dist/role/role.service.js +22 -4
  25. package/dist/role/role.service.js.map +1 -1
  26. package/dist/route/route.controller.d.ts +4 -4
  27. package/dist/route/route.controller.d.ts.map +1 -1
  28. package/dist/route/route.controller.js +20 -16
  29. package/dist/route/route.controller.js.map +1 -1
  30. package/dist/route/route.service.d.ts +4 -4
  31. package/dist/route/route.service.d.ts.map +1 -1
  32. package/dist/route/route.service.js +37 -5
  33. package/dist/route/route.service.js.map +1 -1
  34. package/dist/session/session.controller.d.ts +1 -1
  35. package/dist/session/session.controller.d.ts.map +1 -1
  36. package/dist/session/session.controller.js +9 -3
  37. package/dist/session/session.controller.js.map +1 -1
  38. package/dist/session/session.service.d.ts +1 -1
  39. package/dist/session/session.service.d.ts.map +1 -1
  40. package/dist/session/session.service.js +8 -1
  41. package/dist/session/session.service.js.map +1 -1
  42. package/dist/token/token.service.d.ts +3 -1
  43. package/dist/token/token.service.d.ts.map +1 -1
  44. package/dist/token/token.service.js +18 -3
  45. package/dist/token/token.service.js.map +1 -1
  46. package/hedhog/data/route.yaml +8 -0
  47. package/package.json +3 -3
  48. package/src/auth/auth.service.ts +8 -8
  49. package/src/menu/dto/update.dto.ts +3 -0
  50. package/src/menu/menu.controller.ts +10 -28
  51. package/src/menu/menu.service.ts +48 -6
  52. package/src/role/guards/role.guard.ts +7 -1
  53. package/src/role/role.controller.ts +4 -3
  54. package/src/role/role.service.ts +28 -4
  55. package/src/route/route.controller.ts +12 -11
  56. package/src/route/route.service.ts +49 -6
  57. package/src/session/session.controller.ts +7 -1
  58. package/src/session/session.service.ts +11 -1
  59. package/src/token/token.service.ts +20 -1
@@ -1 +1 @@
1
- {"version":3,"file":"token.service.d.ts","sourceRoot":"","sources":["../../src/token/token.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,qBACa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAEpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAEzB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAJP,GAAG,EAAE,UAAU,EAEf,QAAQ,EAAE,eAAe,EAEzB,OAAO,EAAE,cAAc;IAGpC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAgBpC,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAM9C,iBAAiB,CAAC,IAAI,SAAK;YAInB,eAAe;IAgBvB,wBAAwB,CAAC,GAAG,KAAA,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5C,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAA,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB1F,uBAAuB,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAOxG,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAgBxH,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CAUtD"}
1
+ {"version":3,"file":"token.service.d.ts","sourceRoot":"","sources":["../../src/token/token.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,qBACa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAEpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAEzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBANN,GAAG,EAAE,UAAU,EAEf,QAAQ,EAAE,eAAe,EAEzB,OAAO,EAAE,cAAc,EAEvB,MAAM,EAAE,aAAa;IAGlC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAgCpC,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAM9C,iBAAiB,CAAC,IAAI,SAAK;YAInB,eAAe;IAgBvB,wBAAwB,CAAC,GAAG,KAAA,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5C,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAA,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB1F,uBAAuB,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAOxG,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAgBxH,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CAUtD"}
@@ -14,21 +14,34 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.TokenService = void 0;
16
16
  const api_locale_1 = require("@hed-hog/api-locale");
17
+ const api_prisma_1 = require("@hed-hog/api-prisma");
17
18
  const common_1 = require("@nestjs/common");
18
19
  const jwt_1 = require("@nestjs/jwt");
19
20
  const security_service_1 = require("../security/security.service");
20
21
  const setting_service_1 = require("../setting/setting.service");
21
22
  let TokenService = class TokenService {
22
- constructor(jwt, security, setting) {
23
+ constructor(jwt, security, setting, prisma) {
23
24
  this.jwt = jwt;
24
25
  this.security = security;
25
26
  this.setting = setting;
27
+ this.prisma = prisma;
26
28
  }
27
29
  async verify(locale, token) {
28
30
  try {
29
- return this.jwt.verifyAsync(token, {
31
+ const payload = await this.jwt.verifyAsync(token, {
30
32
  secret: this.security.getJwtSecret(),
31
33
  });
34
+ // Verify session is not revoked
35
+ if (payload.sessionId) {
36
+ const session = await this.prisma.session.findUnique({
37
+ where: { id: payload.sessionId },
38
+ select: { revoked_at: true }
39
+ });
40
+ if (!session || session.revoked_at !== null) {
41
+ throw new common_1.UnauthorizedException((0, api_locale_1.getLocaleText)('sessionRevoked', locale, 'Session has been revoked.'));
42
+ }
43
+ }
44
+ return payload;
32
45
  }
33
46
  catch (error) {
34
47
  console.log('JWT ERROR', error);
@@ -126,8 +139,10 @@ exports.TokenService = TokenService = __decorate([
126
139
  __param(0, (0, common_1.Inject)((0, common_1.forwardRef)(() => jwt_1.JwtService))),
127
140
  __param(1, (0, common_1.Inject)((0, common_1.forwardRef)(() => security_service_1.SecurityService))),
128
141
  __param(2, (0, common_1.Inject)((0, common_1.forwardRef)(() => setting_service_1.SettingService))),
142
+ __param(3, (0, common_1.Inject)((0, common_1.forwardRef)(() => api_prisma_1.PrismaService))),
129
143
  __metadata("design:paramtypes", [jwt_1.JwtService,
130
144
  security_service_1.SecurityService,
131
- setting_service_1.SettingService])
145
+ setting_service_1.SettingService,
146
+ api_prisma_1.PrismaService])
132
147
  ], TokenService);
133
148
  //# sourceMappingURL=token.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"token.service.js","sourceRoot":"","sources":["../../src/token/token.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"token.service.js","sourceRoot":"","sources":["../../src/token/token.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,oDAAoD;AACpD,oDAAoD;AACpD,2CAA2G;AAC3G,qCAAyC;AACzC,mEAA+D;AAC/D,gEAA4D;AAGrD,IAAM,YAAY,GAAlB,MAAM,YAAY;IAEvB,YAEmB,GAAe,EAEf,QAAyB,EAEzB,OAAuB,EAEvB,MAAqB;QANrB,QAAG,GAAH,GAAG,CAAY;QAEf,aAAQ,GAAR,QAAQ,CAAiB;QAEzB,YAAO,GAAP,OAAO,CAAgB;QAEvB,WAAM,GAAN,MAAM,CAAe;IACpC,CAAC;IAEL,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,KAAa;QACxC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE;gBAChD,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE;aACrC,CAAC,CAAC;YAEH,gCAAgC;YAChC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;oBACnD,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,SAAS,EAAE;oBAChC,MAAM,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE;iBAC7B,CAAC,CAAC;gBAEH,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC5C,MAAM,IAAI,8BAAqB,CAC7B,IAAA,0BAAa,EAAC,gBAAgB,EAAE,MAAM,EAAE,2BAA2B,CAAC,CACrE,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAEf,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAEhC,qDAAqD;YACrD,MAAM,IAAI,8BAAqB,CAC5B,KAAa,CAAC,OAAO,IAAI,IAAA,0BAAa,EAAC,cAAc,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAClF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,OAA4B;QAClD,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE;YACjC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE;SACrC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,IAAI,GAAG,EAAE;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAEO,KAAK,CAAC,eAAe;QAE3B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC;YACnD,KAAK;SACN,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC3C,CAAC;YAAC,WAAM,CAAC;gBACP,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;YACnC,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,GAAG;QAEhC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5C,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,MAAM,KAAK,WAAW,CAAC;QACtD,MAAM,aAAa,GAAQ;YACzB,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;SACzC,CAAC;QACF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC;YAC5B,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;QAChC,CAAC;QACD,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,MAAc,EAAE,GAAG,EAAE,KAAa,EAAE,UAAgB;QAC9E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5C,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,MAAM,KAAK,WAAW,CAAC;QACtD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACjD,MAAM,aAAa,GAAQ;YACzB,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;YACxC,MAAM;SACP,CAAC;QACF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC;YAC5B,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;QAChC,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IAEzC,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,OAAgF;QAC5G,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE;YACjC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE;YACpC,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,KAAa;QACzC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE;gBAChD,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE;aACrC,CAAC,CAAC;YACH,OAAO;gBACL,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,2BAAkB,CAAC,8BAA8B,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,KAAa;QACpC,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE;gBACvC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE;gBACpC,gBAAgB,EAAE,IAAI;aACvB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,8BAAqB,CAAC,eAAe,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;CACF,CAAA;AAxIY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;IAIR,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,gBAAU,CAAC,CAAC,CAAA;IAEpC,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,kCAAe,CAAC,CAAC,CAAA;IAEzC,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,gCAAc,CAAC,CAAC,CAAA;IAExC,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,0BAAa,CAAC,CAAC,CAAA;qCALlB,gBAAU;QAEL,kCAAe;QAEhB,gCAAc;QAEf,0BAAa;GAV7B,YAAY,CAwIxB"}
@@ -36,6 +36,14 @@
36
36
  slug: admin
37
37
  - where:
38
38
  slug: admin-access
39
+ - url: /sessions/revoke-all-other
40
+ method: DELETE
41
+ relations:
42
+ role:
43
+ - where:
44
+ slug: admin
45
+ - where:
46
+ slug: admin-access
39
47
  - url: /sessions/:sessionId/revoke
40
48
  method: DELETE
41
49
  relations:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hed-hog/core",
3
- "version": "0.0.139",
3
+ "version": "0.0.141",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "dependencies": {
@@ -30,10 +30,10 @@
30
30
  "speakeasy": "^2.0.0",
31
31
  "uuid": "^11.1.0",
32
32
  "@hed-hog/api-locale": "0.0.11",
33
- "@hed-hog/api-mail": "0.0.7",
34
33
  "@hed-hog/api-prisma": "0.0.4",
35
- "@hed-hog/types": "0.0.1",
34
+ "@hed-hog/api-mail": "0.0.7",
36
35
  "@hed-hog/api-pagination": "0.0.5",
36
+ "@hed-hog/types": "0.0.1",
37
37
  "@hed-hog/api": "0.0.3"
38
38
  },
39
39
  "exports": {
@@ -2,11 +2,11 @@ import { getLocaleText } from '@hed-hog/api-locale';
2
2
  import { PrismaService } from '@hed-hog/api-prisma';
3
3
  import { User } from '@hed-hog/types';
4
4
  import {
5
- BadRequestException,
6
- forwardRef,
7
- Inject,
8
- Injectable,
9
- NotFoundException,
5
+ BadRequestException,
6
+ forwardRef,
7
+ Inject,
8
+ Injectable,
9
+ NotFoundException,
10
10
  } from '@nestjs/common';
11
11
  import { ChallengeService } from '../challenge/challenge.service';
12
12
  import { MailService as MailManagerService } from '../mail/mail.service';
@@ -42,9 +42,9 @@ export class AuthService {
42
42
 
43
43
  async getAuthenticationPayload(locale: string, userId: number, ipAddress: string,
44
44
  userAgent: string) {
45
- const payload = { sub: userId };
46
- const accessToken = await this.token.createAccessToken(payload);
47
45
  const { token: refreshToken, session } = await this.session.create(locale, userId, ipAddress, userAgent);
46
+ const payload = { sub: userId, sessionId: session.id };
47
+ const accessToken = await this.token.createAccessToken(payload);
48
48
 
49
49
  return {
50
50
  accessToken,
@@ -453,7 +453,7 @@ export class AuthService {
453
453
  );
454
454
 
455
455
  const user = await this.user.findUserById(locale, session.user_id);
456
- const payload = { sub: user.id };
456
+ const payload = { sub: user.id, sessionId: session.id };
457
457
  const accessToken = await this.token.createAccessToken(payload);
458
458
 
459
459
  return { accessToken, refreshToken: token, session };
@@ -17,4 +17,7 @@ export class UpdateDTO {
17
17
  @IsString({ message: (args) => getLocaleText('validation.iconMustBeString', args.value) })
18
18
  @IsOptional()
19
19
  icon?: string;
20
+
21
+ @IsOptional()
22
+ locale?: Record<string, string>;
20
23
  }
@@ -47,15 +47,6 @@ export class MenuController {
47
47
  return this.menuService.listRoles(locale, menuId, paginationParams);
48
48
  }
49
49
 
50
- @Get(':menuId/screen')
51
- async listScreens(
52
- @Param('menuId', ParseIntPipe) menuId: number,
53
- @Pagination() paginationParams,
54
- @Locale() locale,
55
- ) {
56
- return this.menuService.listScreens(locale, menuId, paginationParams);
57
- }
58
-
59
50
  @Patch(':menuId/role')
60
51
  async updateRoles(
61
52
  @Param('menuId', ParseIntPipe) menuId: number,
@@ -65,30 +56,26 @@ export class MenuController {
65
56
  return this.menuService.updateRoles(locale, menuId, data);
66
57
  }
67
58
 
68
- @Patch(':menuId/screen')
69
- async updateScreens(
70
- @Param('menuId', ParseIntPipe) menuId: number,
71
- @Body() data: UpdateIdsDTO,
72
- @Locale() locale,
73
- ) {
74
- return this.menuService.updateScreens(locale, menuId, data);
75
- }
76
-
77
59
  @Get(':menuId')
78
60
  async show(@Locale() locale,@Param('menuId', ParseIntPipe) menuId: number) {
79
61
  return this.menuService.get(locale, menuId);
80
62
  }
81
63
 
82
64
  @Post()
83
- async create(@Body() data: CreateDTO) {
84
- return this.menuService.create(data);
65
+ async create(@Locale() locale, @Body() data: CreateDTO) {
66
+ return this.menuService.create(locale,data);
67
+ }
68
+
69
+ @Patch('order')
70
+ async updateOrder(@Locale() locale, @Body() data: OrderDTO): Promise<void> {
71
+ return this.menuService.updateOrder(locale, data);
85
72
  }
86
73
 
87
74
  @Patch(':menuId')
88
75
  async update(
76
+ @Locale() locale,
89
77
  @Param('menuId', ParseIntPipe) menuId: number,
90
78
  @Body() data: UpdateDTO,
91
- @Locale() locale,
92
79
  ) {
93
80
  return this.menuService.update(locale,{
94
81
  id: menuId,
@@ -97,12 +84,7 @@ export class MenuController {
97
84
  }
98
85
 
99
86
  @Delete()
100
- async delete(@Body() data: DeleteDTO) {
101
- return this.menuService.delete(data);
102
- }
103
-
104
- @Patch('order')
105
- async updateOrder(@Body() data: OrderDTO): Promise<void> {
106
- return this.menuService.updateOrder(data);
87
+ async delete(@Locale() locale, @Body() data: DeleteDTO) {
88
+ return this.menuService.delete(locale, data);
107
89
  }
108
90
  }
@@ -6,6 +6,7 @@ import {
6
6
  BadRequestException,
7
7
  Inject,
8
8
  Injectable,
9
+ NotFoundException,
9
10
  forwardRef,
10
11
  } from '@nestjs/common';
11
12
  import { DeleteDTO } from '../dto/delete.dto';
@@ -276,7 +277,7 @@ export class MenuService {
276
277
  });
277
278
 
278
279
  if (!user) {
279
- throw new BadRequestException(
280
+ throw new NotFoundException(
280
281
  getLocaleText('menuNotFound', locale, 'Menu not found.'),
281
282
  );
282
283
  }
@@ -284,7 +285,7 @@ export class MenuService {
284
285
  return user;
285
286
  }
286
287
 
287
- async create({ slug, url, icon, order, menuId }: CreateDTO) {
288
+ async create(_locale:string, { slug, url, icon, order, menuId }: CreateDTO) {
288
289
  return this.prismaService.menu.create({
289
290
  data: { slug, url, icon, order, menu_id: menuId },
290
291
  });
@@ -304,13 +305,54 @@ export class MenuService {
304
305
  );
305
306
  }
306
307
 
307
- return this.prismaService.menu.update({
308
+ const { locale: localeData, ...menuData } = data;
309
+
310
+ // Update menu data
311
+ const result = await this.prismaService.menu.update({
308
312
  where: { id },
309
- data,
313
+ data: menuData,
310
314
  });
315
+
316
+ // Update locale translations if provided
317
+ if (localeData) {
318
+ for (const [localeCode, translation] of Object.entries(localeData)) {
319
+ const localeRecord = await this.prismaService.locale.findUnique({
320
+ where: { code: localeCode },
321
+ });
322
+
323
+ if (localeRecord) {
324
+ // Check if translation exists
325
+ const existingTranslation = await this.prismaService.menu_locale.findFirst({
326
+ where: {
327
+ menu_id: id,
328
+ locale_id: localeRecord.id,
329
+ },
330
+ });
331
+
332
+ if (existingTranslation) {
333
+ // Update existing translation
334
+ await this.prismaService.menu_locale.update({
335
+ where: { id: existingTranslation.id },
336
+ data: { name: translation },
337
+ });
338
+ } else {
339
+ // Create new translation
340
+ await this.prismaService.menu_locale.create({
341
+ data: {
342
+ menu_id: id,
343
+ locale_id: localeRecord.id,
344
+ name: translation,
345
+ },
346
+ });
347
+ }
348
+ }
349
+ }
350
+ }
351
+
352
+ return result;
311
353
  }
312
354
 
313
- async delete({ ids }: DeleteDTO, locale: string = 'en'): Promise<{count:number}> {
355
+ async delete(locale: string, { ids }: DeleteDTO): Promise<{count:number}> {
314
356
  if (ids == undefined || ids == null) {
315
357
  throw new BadRequestException(
316
358
  getLocaleText('deleteItemsRequired', locale, 'You must select at least one menu to delete.'),
@@ -340,7 +382,7 @@ export class MenuService {
340
382
  });
341
383
  }
342
384
 
343
- async updateOrder({ ids }: OrderDTO, locale: string = 'en'): Promise<void> {
385
+ async updateOrder(locale: string, { ids }: OrderDTO): Promise<void> {
344
386
  const count = await this.prismaService.menu.count({
345
387
  where: {
346
388
  id: {
@@ -111,7 +111,13 @@ export class RoleGuard implements CanActivate {
111
111
  },
112
112
  });
113
113
 
114
- return route === 1;
114
+ if (route !== 1) {
115
+ throw new UnauthorizedException(
116
+ `Access denied. User does not have permission to access ${httpMethod} ${fullPath}`
117
+ );
118
+ }
119
+
120
+ return true;
115
121
  }
116
122
 
117
123
  private extractTokenFromHeader(request: Request): string | undefined {
@@ -116,12 +116,13 @@ export class RoleController {
116
116
  async update(
117
117
  @Param('roleId', ParseIntPipe) roleId: number,
118
118
  @Body() data: UpdateDTO,
119
+ @Locale() locale,
119
120
  ) {
120
- return this.roleService.update(roleId, data);
121
+ return this.roleService.update(roleId, data, locale);
121
122
  }
122
123
 
123
124
  @Delete()
124
- async delete(@Body() data: DeleteDTO) {
125
- return this.roleService.delete(data);
125
+ async delete(@Body() data: DeleteDTO, @Locale() locale) {
126
+ return this.roleService.delete(data, locale);
126
127
  }
127
128
  }
@@ -5,6 +5,7 @@ import {
5
5
  BadRequestException,
6
6
  Inject,
7
7
  Injectable,
8
+ NotFoundException,
8
9
  forwardRef,
9
10
  } from '@nestjs/common';
10
11
  import { DeleteDTO } from '../dto/delete.dto';
@@ -378,7 +379,7 @@ export class RoleService {
378
379
  });
379
380
 
380
381
  if (!role) {
381
- return null;
382
+ throw new NotFoundException(`Role with ID ${roleId} not found`);
382
383
  }
383
384
 
384
385
  const localeData = role.role_locale.reduce((acc, item) => {
@@ -423,7 +424,16 @@ export class RoleService {
423
424
  return this.get(role.id);
424
425
  }
425
426
 
426
- async update(id: number, body: UpdateDTO) {
427
+ async update(id: number, body: UpdateDTO, localeRequest:string) {
428
+
429
+ const roleExists = await this.prismaService.role.findUnique({
430
+ where: { id },
431
+ });
432
+
433
+ if (!roleExists) {
434
+ throw new NotFoundException(getLocaleText('itemNotFound', localeRequest, `Role with ID ${id} not found`).replace('{{item}}', 'Role'));
435
+ }
436
+
427
437
  const { locale } = body;
428
438
 
429
439
  if (locale) {
@@ -463,13 +473,27 @@ export class RoleService {
463
473
  return this.get(id);
464
474
  }
465
475
 
466
- async delete({ ids }: DeleteDTO, locale: string = 'en'):Promise<{count:number}> {
476
+ async delete({ ids }: DeleteDTO, localeRequest: string = 'en'):Promise<{count:number}> {
467
477
  if (ids == undefined || ids == null) {
468
478
  throw new BadRequestException(
469
- getLocaleText('deleteItemsRequired', locale, 'You must select at least one permission to delete.'),
479
+ getLocaleText('deleteItemsRequired', localeRequest, 'You must select at least one permission to delete.'),
470
480
  );
471
481
  }
472
482
 
483
+ const existingRoles = await this.prismaService.role.findMany({
484
+ where: {
485
+ id: {
486
+ in: ids,
487
+ },
488
+ },
489
+ });
490
+
491
+ if (existingRoles.length !== ids.length) {
492
+ const existingIds = existingRoles.map((role) => role.id);
493
+ const missingIds = ids.filter((id) => !existingIds.includes(id));
494
+ throw new NotFoundException(getLocaleText('itemsNotFound', localeRequest, `Roles with IDs ${missingIds.join(', ')} not found`).replace('{{items}}', 'Roles'));
495
+ }
496
+
473
497
  return this.prismaService.role.deleteMany({
474
498
  where: {
475
499
  id: {
@@ -1,3 +1,5 @@
1
+ import { Role } from '@hed-hog/api';
2
+ import { Locale } from '@hed-hog/api-locale';
1
3
  import { Pagination, PaginationDTO } from '@hed-hog/api-pagination';
2
4
  import {
3
5
  Body,
@@ -13,8 +15,6 @@ import {
13
15
  } from '@nestjs/common';
14
16
  import { DeleteDTO } from '../dto/delete.dto';
15
17
  import { UpdateIdsDTO } from '../dto/update-ids.dto';
16
- import { Locale } from '@hed-hog/api-locale';
17
- import { Role } from '@hed-hog/api';
18
18
  import { CreateDTO } from './dto/create.dto';
19
19
  import { UpdateDTO } from './dto/update.dto';
20
20
  import { RouteService } from './route.service';
@@ -33,26 +33,27 @@ export class RouteController {
33
33
  }
34
34
 
35
35
  @Get(':routeId')
36
- async get(@Param('routeId', ParseIntPipe) routeId: number) {
37
- return this.routeService.get(routeId);
36
+ async get(@Param('routeId', ParseIntPipe) routeId: number, @Locale() locale) {
37
+ return this.routeService.get(routeId, locale);
38
38
  }
39
39
 
40
40
  @Post()
41
- async create(@Body() { url, method }: CreateDTO) {
42
- return this.routeService.create({ url, method });
41
+ async create(@Body() { url, method }: CreateDTO, @Locale() locale) {
42
+ return this.routeService.create({ url, method }, locale);
43
43
  }
44
44
 
45
45
  @Patch(':routeId')
46
46
  async update(
47
47
  @Param('routeId', ParseIntPipe) routeId: number,
48
48
  @Body() data: UpdateDTO,
49
+ @Locale() locale
49
50
  ) {
50
- return this.routeService.update({ id: routeId, data });
51
+ return this.routeService.update({ id: routeId, data }, locale);
51
52
  }
52
53
 
53
54
  @Delete()
54
- async delete(@Body() data: DeleteDTO) {
55
- return this.routeService.delete(data);
55
+ async delete(@Body() data: DeleteDTO, @Locale() locale) {
56
+ return this.routeService.delete(data, locale);
56
57
  }
57
58
 
58
59
  @Get(':routeId/role')
@@ -72,7 +73,7 @@ export class RouteController {
72
73
  return this.routeService.updateRoles(routeId, data);
73
74
  }
74
75
 
75
- @Get(':routeId/screens')
76
+ @Get(':routeId/screen')
76
77
  async listScreens(
77
78
  @Param('routeId', ParseIntPipe) routeId: number,
78
79
  @Pagination() paginationParams: PaginationDTO,
@@ -81,7 +82,7 @@ export class RouteController {
81
82
  return this.routeService.listScreens(locale, routeId, paginationParams);
82
83
  }
83
84
 
84
- @Patch(':routeId/screens')
85
+ @Patch(':routeId/screen')
85
86
  async updateScreens(
86
87
  @Param('routeId', ParseIntPipe) routeId: number,
87
88
  @Body() data: UpdateIdsDTO,
@@ -1,6 +1,7 @@
1
+ import { getLocaleText } from '@hed-hog/api-locale';
1
2
  import { PaginationDTO, PaginationService } from '@hed-hog/api-pagination';
2
3
  import { PrismaService } from '@hed-hog/api-prisma';
3
- import { forwardRef, Inject, Injectable } from '@nestjs/common';
4
+ import { BadRequestException, forwardRef, Inject, Injectable, NotFoundException } from '@nestjs/common';
4
5
  import { DeleteDTO } from '../dto/delete.dto';
5
6
  import { UpdateIdsDTO } from '../dto/update-ids.dto';
6
7
  import { CreateDTO } from './dto/create.dto';
@@ -34,22 +35,64 @@ export class RouteService {
34
35
  );
35
36
  }
36
37
 
37
- async get(routeId: number): Promise<any> {
38
- return this.prismaService.route.findUnique({ where: { id: routeId } });
38
+ async get(routeId: number, locale: string): Promise<any> {
39
+ const route = await this.prismaService.route.findUnique({ where: { id: routeId } });
40
+
41
+ if (!route) {
42
+ throw new NotFoundException(getLocaleText('itemNotFound', locale, `Route with ID ${routeId} not found`).replace('{{item}}', 'Route'));
43
+ }
44
+
45
+ return route;
39
46
  }
40
47
 
41
- async create({ url, method }: CreateDTO): Promise<any> {
48
+ async create({ url, method }: CreateDTO, locale: string): Promise<any> {
49
+
50
+ const existingRoute = await this.prismaService.route.findFirst({
51
+ where: {
52
+ url,
53
+ method,
54
+ },
55
+ });
56
+
57
+ if (existingRoute) {
58
+ throw new BadRequestException(getLocaleText('itemAlreadyExists', locale, `Route with URL ${url} and method ${method} already exists`).replace('{{item}}', 'Route'));
59
+ }
60
+
42
61
  return this.prismaService.route.create({ data: { url, method } });
43
62
  }
44
63
 
45
- async update({ id, data }: { id: number; data: UpdateDTO }): Promise<any> {
64
+ async update({ id, data }: { id: number; data: UpdateDTO }, locale: string): Promise<any> {
65
+
66
+ const routeExists = await this.prismaService.route.findUnique({
67
+ where: { id },
68
+ });
69
+
70
+ if (!routeExists) {
71
+ throw new NotFoundException(getLocaleText('itemNotFound', locale, `Route with ID ${id} not found`).replace('{{item}}', 'Route'));
72
+ }
73
+
46
74
  return this.prismaService.route.update({
47
75
  where: { id },
48
76
  data,
49
77
  });
50
78
  }
51
79
 
52
- async delete({ ids }: DeleteDTO):Promise<{count:number}> {
80
+ async delete({ ids }: DeleteDTO, locale: string):Promise<{count:number}> {
81
+
82
+ const existingRoutes = await this.prismaService.route.findMany({
83
+ where: {
84
+ id: {
85
+ in: ids,
86
+ },
87
+ },
88
+ });
89
+
90
+ if (existingRoutes.length !== ids.length) {
91
+ const existingIds = existingRoutes.map((route) => route.id);
92
+ const missingIds = ids.filter((id) => !existingIds.includes(id));
93
+ throw new NotFoundException(getLocaleText('itemsNotFound', locale, `Routes with IDs ${missingIds.join(', ')} not found`).replace('{{items}}', 'Routes'));
94
+ }
95
+
53
96
  return this.prismaService.route.deleteMany({
54
97
  where: {
55
98
  id: {
@@ -1,4 +1,5 @@
1
1
  import { Role, User } from '@hed-hog/api';
2
+ import { Locale } from '@hed-hog/api-locale';
2
3
  import { Pagination, PaginationDTO } from '@hed-hog/api-pagination';
3
4
  import { Controller, Delete, Get, Param } from '@nestjs/common';
4
5
  import { SessionService } from './session.service';
@@ -9,24 +10,29 @@ export class SessionController {
9
10
  private readonly sessionService: SessionService
10
11
  ) {}
11
12
 
13
+ @Role()
12
14
  @Get('user')
13
15
  async getUserSessions(
14
16
  @Pagination() paginationParams: PaginationDTO,
15
17
  @User() { id },
18
+ @Locale() locale: string
16
19
  ) {
17
- return this.sessionService.getUserSessions(paginationParams, id)
20
+ return this.sessionService.getUserSessions(paginationParams, id,locale)
18
21
  }
19
22
 
23
+ @Role()
20
24
  @Delete('revoke-all-other')
21
25
  async revokeAllOtherSessions(@User() { id }){
22
26
  return this.sessionService.revokeAllOtherSessions(id)
23
27
  }
24
28
 
29
+ @Role()
25
30
  @Delete('revoke-all')
26
31
  async revokeAllSessions(@User() { id }){
27
32
  return this.sessionService.revokeAllSessions(id)
28
33
  }
29
34
 
35
+ @Role()
30
36
  @Delete(':sessionId/revoke')
31
37
  async revokeSession(@User() { id: userId }, @Param('sessionId') sessionId: number){
32
38
  return this.sessionService.revokeUserSession(userId, sessionId)
@@ -115,7 +115,17 @@ export class SessionService {
115
115
  });
116
116
  }
117
117
 
118
- async getUserSessions(paginationParams: PaginationDTO, userId: number) {
118
+ async getUserSessions(paginationParams: PaginationDTO, userId: number, locale: string) {
119
+
120
+ const userExists = await this.prisma.user.findUnique({
121
+ where: { id: userId },
122
+ select: { id: true },
123
+ });
124
+
125
+ if (!userExists) {
126
+ throw new BadRequestException(getLocaleText('session.userNotFound', locale, 'User not found.'));
127
+ }
128
+
119
129
  try {
120
130
  const paginate = await this.paginationService.paginatePrismaModel(this.prisma.user_session, {
121
131
  ...paginationParams,
@@ -1,4 +1,5 @@
1
1
  import { getLocaleText } from "@hed-hog/api-locale";
2
+ import { PrismaService } from "@hed-hog/api-prisma";
2
3
  import { ForbiddenException, forwardRef, Inject, Injectable, UnauthorizedException } from "@nestjs/common";
3
4
  import { JwtService } from "@nestjs/jwt";
4
5
  import { SecurityService } from "../security/security.service";
@@ -14,13 +15,31 @@ export class TokenService {
14
15
  private readonly security: SecurityService,
15
16
  @Inject(forwardRef(() => SettingService))
16
17
  private readonly setting: SettingService,
18
+ @Inject(forwardRef(() => PrismaService))
19
+ private readonly prisma: PrismaService,
17
20
  ) { }
18
21
 
19
22
  async verify(locale: string, token: string) {
20
23
  try {
21
- return this.jwt.verifyAsync(token, {
24
+ const payload = await this.jwt.verifyAsync(token, {
22
25
  secret: this.security.getJwtSecret(),
23
26
  });
27
+
28
+ // Verify session is not revoked
29
+ if (payload.sessionId) {
30
+ const session = await this.prisma.session.findUnique({
31
+ where: { id: payload.sessionId },
32
+ select: { revoked_at: true }
33
+ });
34
+
35
+ if (!session || session.revoked_at !== null) {
36
+ throw new UnauthorizedException(
37
+ getLocaleText('sessionRevoked', locale, 'Session has been revoked.')
38
+ );
39
+ }
40
+ }
41
+
42
+ return payload;
24
43
  } catch (error) {
25
44
 
26
45
  console.log('JWT ERROR', error);