@solidstarters/solid-core 1.2.122 → 1.2.123

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 (94) hide show
  1. package/dist/controllers/authentication.controller.d.ts +3 -1
  2. package/dist/controllers/authentication.controller.d.ts.map +1 -1
  3. package/dist/controllers/setting.controller.d.ts +6 -3
  4. package/dist/controllers/setting.controller.d.ts.map +1 -1
  5. package/dist/controllers/setting.controller.js +32 -5
  6. package/dist/controllers/setting.controller.js.map +1 -1
  7. package/dist/controllers/user-activity-history.controller.d.ts +43 -0
  8. package/dist/controllers/user-activity-history.controller.d.ts.map +1 -0
  9. package/dist/controllers/user-activity-history.controller.js +179 -0
  10. package/dist/controllers/user-activity-history.controller.js.map +1 -0
  11. package/dist/controllers/user.controller.d.ts +2 -0
  12. package/dist/controllers/user.controller.d.ts.map +1 -1
  13. package/dist/controllers/user.controller.js +19 -0
  14. package/dist/controllers/user.controller.js.map +1 -1
  15. package/dist/dtos/create-setting.dto.d.ts +3 -0
  16. package/dist/dtos/create-setting.dto.d.ts.map +1 -1
  17. package/dist/dtos/create-setting.dto.js +19 -1
  18. package/dist/dtos/create-setting.dto.js.map +1 -1
  19. package/dist/dtos/create-user-activity-history.dto.d.ts +8 -0
  20. package/dist/dtos/create-user-activity-history.dto.d.ts.map +1 -0
  21. package/dist/dtos/create-user-activity-history.dto.js +54 -0
  22. package/dist/dtos/create-user-activity-history.dto.js.map +1 -0
  23. package/dist/dtos/update-setting.dto.d.ts +3 -0
  24. package/dist/dtos/update-setting.dto.d.ts.map +1 -1
  25. package/dist/dtos/update-setting.dto.js +19 -1
  26. package/dist/dtos/update-setting.dto.js.map +1 -1
  27. package/dist/dtos/update-user-activity-history.dto.d.ts +9 -0
  28. package/dist/dtos/update-user-activity-history.dto.d.ts.map +1 -0
  29. package/dist/dtos/update-user-activity-history.dto.js +57 -0
  30. package/dist/dtos/update-user-activity-history.dto.js.map +1 -0
  31. package/dist/dtos/update-user-profile.dto.d.ts +7 -0
  32. package/dist/dtos/update-user-profile.dto.d.ts.map +1 -0
  33. package/dist/dtos/update-user-profile.dto.js +41 -0
  34. package/dist/dtos/update-user-profile.dto.js.map +1 -0
  35. package/dist/dtos/update-user.dto.d.ts.map +1 -1
  36. package/dist/dtos/update-user.dto.js +1 -16
  37. package/dist/dtos/update-user.dto.js.map +1 -1
  38. package/dist/entities/setting.entity.d.ts +3 -0
  39. package/dist/entities/setting.entity.d.ts.map +1 -1
  40. package/dist/entities/setting.entity.js +11 -1
  41. package/dist/entities/setting.entity.js.map +1 -1
  42. package/dist/entities/user-activity-history.entity.d.ts +9 -0
  43. package/dist/entities/user-activity-history.entity.d.ts.map +1 -0
  44. package/dist/entities/user-activity-history.entity.js +46 -0
  45. package/dist/entities/user-activity-history.entity.js.map +1 -0
  46. package/dist/guards/authentication.guard.d.ts +3 -1
  47. package/dist/guards/authentication.guard.d.ts.map +1 -1
  48. package/dist/guards/authentication.guard.js +11 -2
  49. package/dist/guards/authentication.guard.js.map +1 -1
  50. package/dist/index.d.ts +4 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +4 -0
  53. package/dist/index.js.map +1 -1
  54. package/dist/seeders/seed-data/solid-core-metadata.json +325 -0
  55. package/dist/services/authentication.service.d.ts +8 -2
  56. package/dist/services/authentication.service.d.ts.map +1 -1
  57. package/dist/services/authentication.service.js +26 -2
  58. package/dist/services/authentication.service.js.map +1 -1
  59. package/dist/services/request-context.service.d.ts +2 -0
  60. package/dist/services/request-context.service.d.ts.map +1 -1
  61. package/dist/services/request-context.service.js +6 -0
  62. package/dist/services/request-context.service.js.map +1 -1
  63. package/dist/services/setting.service.d.ts +11 -3
  64. package/dist/services/setting.service.d.ts.map +1 -1
  65. package/dist/services/setting.service.js +86 -60
  66. package/dist/services/setting.service.js.map +1 -1
  67. package/dist/services/user-activity-history.service.d.ts +26 -0
  68. package/dist/services/user-activity-history.service.d.ts.map +1 -0
  69. package/dist/services/user-activity-history.service.js +69 -0
  70. package/dist/services/user-activity-history.service.js.map +1 -0
  71. package/dist/solid-core.module.d.ts.map +1 -1
  72. package/dist/solid-core.module.js +8 -1
  73. package/dist/solid-core.module.js.map +1 -1
  74. package/dist/tsconfig.tsbuildinfo +1 -1
  75. package/package.json +1 -1
  76. package/src/controllers/setting.controller.ts +32 -4
  77. package/src/controllers/user-activity-history.controller.ts +93 -0
  78. package/src/controllers/user.controller.ts +12 -1
  79. package/src/dtos/create-setting.dto.ts +13 -1
  80. package/src/dtos/create-user-activity-history.dto.ts +30 -0
  81. package/src/dtos/update-setting.dto.ts +13 -1
  82. package/src/dtos/update-user-activity-history.dto.ts +32 -0
  83. package/src/dtos/update-user-profile.dto.ts +19 -0
  84. package/src/dtos/update-user.dto.ts +13 -13
  85. package/src/entities/setting.entity.ts +7 -1
  86. package/src/entities/user-activity-history.entity.ts +21 -0
  87. package/src/guards/authentication.guard.ts +12 -1
  88. package/src/index.ts +7 -0
  89. package/src/seeders/seed-data/solid-core-metadata.json +325 -0
  90. package/src/services/authentication.service.ts +45 -12
  91. package/src/services/request-context.service.ts +8 -0
  92. package/src/services/setting.service.ts +103 -71
  93. package/src/services/user-activity-history.service.ts +49 -0
  94. package/src/solid-core.module.ts +8 -1
@@ -1750,6 +1750,18 @@
1750
1750
  "encrypt": false,
1751
1751
  "isSystem": true
1752
1752
  },
1753
+ {
1754
+ "name": "profilePicture",
1755
+ "displayName": "Profile Picture",
1756
+ "type": "mediaSingle",
1757
+ "required": false,
1758
+ "unique": true,
1759
+ "index": false,
1760
+ "private": false,
1761
+ "encrypt": false,
1762
+ "isSystem": true,
1763
+ "mediaStorageProviderUserKey": "default-filesystem"
1764
+ },
1753
1765
  {
1754
1766
  "name": "lastLoginProvider",
1755
1767
  "displayName": "Last Login Provider",
@@ -2074,6 +2086,86 @@
2074
2086
  }
2075
2087
  ]
2076
2088
  },
2089
+ {
2090
+ "singularName": "userActivityHistory",
2091
+ "tableName": "ss_user_activity_history",
2092
+ "pluralName": "userActivityHistories",
2093
+ "displayName": "User Activity History",
2094
+ "description": "Model to capture Users Activity",
2095
+ "dataSource": "default",
2096
+ "dataSourceType": "postgres",
2097
+ "userKeyFieldUserKey": "",
2098
+ "isSystem": true,
2099
+ "fields": [
2100
+ {
2101
+ "name": "user",
2102
+ "displayName": "User",
2103
+ "description": null,
2104
+ "type": "relation",
2105
+ "ormType": "integer",
2106
+ "isSystem": false,
2107
+ "relationType": "many-to-one",
2108
+ "relationCoModelFieldName": null,
2109
+ "relationCreateInverse": false,
2110
+ "relationCoModelSingularName": "user",
2111
+ "relationCoModelColumnName": "",
2112
+ "relationModelModuleName": "solid-core",
2113
+ "relationCascade": "cascade",
2114
+ "required": false,
2115
+ "unique": false,
2116
+ "index": false,
2117
+ "private": false,
2118
+ "encrypt": false,
2119
+ "encryptionType": null,
2120
+ "decryptWhen": null,
2121
+ "columnName": null,
2122
+ "relationJoinTableName": "",
2123
+ "isRelationManyToManyOwner": null
2124
+ },
2125
+ {
2126
+ "name": "event",
2127
+ "displayName": "Event",
2128
+ "type": "selectionStatic",
2129
+ "ormType": "varchar",
2130
+ "length": 256,
2131
+ "required": false,
2132
+ "index": true,
2133
+ "isSystem": true,
2134
+ "selectionValueType": "string",
2135
+ "selectionStaticValues": [
2136
+ "login:login",
2137
+ "logout:logout",
2138
+ "tokenRefreshed:tokenRefreshed"
2139
+ ]
2140
+ },
2141
+ {
2142
+ "name": "ipAddress",
2143
+ "displayName": "IP Address",
2144
+ "type": "shortText",
2145
+ "ormType": "varchar",
2146
+ "length": 512,
2147
+ "required": false,
2148
+ "unique": false,
2149
+ "index": true,
2150
+ "private": false,
2151
+ "encrypt": false,
2152
+ "isSystem": true
2153
+ },
2154
+ {
2155
+ "name": "userAgent",
2156
+ "displayName": "User Agent",
2157
+ "type": "shortText",
2158
+ "ormType": "varchar",
2159
+ "length": 512,
2160
+ "required": false,
2161
+ "unique": false,
2162
+ "index": true,
2163
+ "private": false,
2164
+ "encrypt": false,
2165
+ "isSystem": true
2166
+ }
2167
+ ]
2168
+ },
2077
2169
  {
2078
2170
  "singularName": "permissionMetadata",
2079
2171
  "pluralName": "permissionMetadatas",
@@ -2455,6 +2547,47 @@
2455
2547
  "private": false,
2456
2548
  "encrypt": false,
2457
2549
  "isSystem": true
2550
+ },
2551
+ {
2552
+ "name": "type",
2553
+ "displayName": "Type",
2554
+ "type": "selectionStatic",
2555
+ "ormType": "varchar",
2556
+ "length": 256,
2557
+ "required": false,
2558
+ "index": false,
2559
+ "isSystem": true,
2560
+ "columnName": "type",
2561
+ "selectionValueType": "string",
2562
+ "selectionStaticValues": [
2563
+ "system:System",
2564
+ "user:User"
2565
+ ]
2566
+ },
2567
+ {
2568
+ "name": "user",
2569
+ "displayName": "User",
2570
+ "description": "This is the user id field",
2571
+ "type": "relation",
2572
+ "ormType": "integer",
2573
+ "isSystem": false,
2574
+ "relationType": "many-to-one",
2575
+ "relationCoModelFieldName": null,
2576
+ "relationCreateInverse": false,
2577
+ "relationCoModelSingularName": "user",
2578
+ "relationCoModelColumnName": null,
2579
+ "relationModelModuleName": "solid-core",
2580
+ "relationCascade": "cascade",
2581
+ "required": false,
2582
+ "unique": false,
2583
+ "index": false,
2584
+ "private": false,
2585
+ "encrypt": false,
2586
+ "encryptionType": null,
2587
+ "decryptWhen": null,
2588
+ "columnName": null,
2589
+ "relationJoinTableName": null,
2590
+ "isRelationManyToManyOwner": null
2458
2591
  }
2459
2592
  ]
2460
2593
  },
@@ -4238,6 +4371,58 @@
4238
4371
  "viewUserKey": "locale-list-view",
4239
4372
  "moduleUserKey": "solid-core",
4240
4373
  "modelUserKey": "locale"
4374
+ },
4375
+ {
4376
+ "displayName": "User Activity History List View",
4377
+ "name": "userActivityHistory-list-view",
4378
+ "type": "solid",
4379
+ "domain": "",
4380
+ "context": "",
4381
+ "customComponent": "/admin/address-master/userActivityHistory/all",
4382
+ "customIsModal": true,
4383
+ "serverEndpoint": "",
4384
+ "viewUserKey": "userActivityHistory-list-view",
4385
+ "moduleUserKey": "solid-core",
4386
+ "modelUserKey": "userActivityHistory"
4387
+ },
4388
+ {
4389
+ "displayName": "App Settings",
4390
+ "name": "app-settings-action",
4391
+ "type": "custom",
4392
+ "domain": "",
4393
+ "context": "",
4394
+ "customComponent": "/admin/core/solid-core/settings/app-settings",
4395
+ "customIsModal": true,
4396
+ "serverEndpoint": "",
4397
+ "viewUserKey": "",
4398
+ "moduleUserKey": "solid-core",
4399
+ "modelUserKey": "setting"
4400
+ },
4401
+ {
4402
+ "displayName": "Authentication Settings",
4403
+ "name": "authentication-settings-action",
4404
+ "type": "custom",
4405
+ "domain": "",
4406
+ "context": "",
4407
+ "customComponent": "/admin/core/solid-core/settings/authentication-settings",
4408
+ "customIsModal": true,
4409
+ "serverEndpoint": "",
4410
+ "viewUserKey": "",
4411
+ "moduleUserKey": "solid-core",
4412
+ "modelUserKey": "setting"
4413
+ },
4414
+ {
4415
+ "displayName": "Misc",
4416
+ "name": "misc-settings-action",
4417
+ "type": "custom",
4418
+ "domain": "",
4419
+ "context": "",
4420
+ "customComponent": "/admin/core/solid-core/settings/misc-settings",
4421
+ "customIsModal": true,
4422
+ "serverEndpoint": "",
4423
+ "viewUserKey": "",
4424
+ "moduleUserKey": "solid-core",
4425
+ "modelUserKey": "setting"
4241
4426
  }
4242
4427
  ],
4243
4428
  "menus": [
@@ -4488,6 +4673,46 @@
4488
4673
  "actionUserKey": "locale-list-action",
4489
4674
  "moduleUserKey": "solid-core",
4490
4675
  "parentMenuItemUserKey": "other-menu-item"
4676
+ },
4677
+ {
4678
+ "displayName": "User Activity History",
4679
+ "name": "userActivityHistory-menu-item",
4680
+ "sequenceNumber": 1,
4681
+ "actionUserKey": "userActivityHistory-list-view",
4682
+ "moduleUserKey": "solid-core",
4683
+ "parentMenuItemUserKey": "other-menu-item"
4684
+ },
4685
+ {
4686
+ "displayName": "Settings",
4687
+ "name": "settings-menu-item",
4688
+ "sequenceNumber": 3,
4689
+ "actionUserKey": "settings-root",
4690
+ "moduleUserKey": "solid-core",
4691
+ "parentMenuItemUserKey": ""
4692
+ },
4693
+ {
4694
+ "displayName": "App Settings",
4695
+ "name": "app-settings-menu-item",
4696
+ "sequenceNumber": 1,
4697
+ "actionUserKey": "app-settings-action",
4698
+ "moduleUserKey": "solid-core",
4699
+ "parentMenuItemUserKey": "settings-menu-item"
4700
+ },
4701
+ {
4702
+ "displayName": "Authentication Settings",
4703
+ "name": "authentication-settings-menu-item",
4704
+ "sequenceNumber": 2,
4705
+ "actionUserKey": "authentication-settings-action",
4706
+ "moduleUserKey": "solid-core",
4707
+ "parentMenuItemUserKey": "settings-menu-item"
4708
+ },
4709
+ {
4710
+ "displayName": "Misc",
4711
+ "name": "misc-settings-menu-item",
4712
+ "sequenceNumber": 3,
4713
+ "actionUserKey": "misc-settings-action",
4714
+ "moduleUserKey": "solid-core",
4715
+ "parentMenuItemUserKey": "settings-menu-item"
4491
4716
  }
4492
4717
  ],
4493
4718
  "views": [
@@ -9360,6 +9585,106 @@
9360
9585
  }
9361
9586
  ]
9362
9587
  }
9588
+ },
9589
+ {
9590
+ "name": "userActivityHistory-list-view",
9591
+ "displayName": "User Activity History",
9592
+ "type": "list",
9593
+ "context": "{}",
9594
+ "moduleUserKey": "solid-core",
9595
+ "modelUserKey": "userActivityHistory",
9596
+ "layout": {
9597
+ "type": "list",
9598
+ "attrs": {
9599
+ "pagination": true,
9600
+ "pageSizeOptions": [
9601
+ 10,
9602
+ 25,
9603
+ 50
9604
+ ],
9605
+ "enableGlobalSearch": true,
9606
+ "create": true,
9607
+ "edit": true,
9608
+ "delete": true
9609
+ },
9610
+ "children": [
9611
+ {
9612
+ "type": "field",
9613
+ "attrs": {
9614
+ "name": "id",
9615
+ "sortable": true,
9616
+ "filterable": true
9617
+ }
9618
+ },
9619
+ {
9620
+ "type": "field",
9621
+ "attrs": {
9622
+ "name": "user",
9623
+ "sortable": true,
9624
+ "filterable": true
9625
+ }
9626
+ }
9627
+ ]
9628
+ }
9629
+ },
9630
+ {
9631
+ "name": "userActivityHistory-form-view",
9632
+ "displayName": "User Activity History",
9633
+ "type": "form",
9634
+ "context": "{}",
9635
+ "moduleUserKey": "solid-core",
9636
+ "modelUserKey": "userActivityHistory",
9637
+ "layout": {
9638
+ "type": "form",
9639
+ "attrs": {
9640
+ "name": "form-1",
9641
+ "label": "User Activity History",
9642
+ "className": "grid"
9643
+ },
9644
+ "children": [
9645
+ {
9646
+ "type": "sheet",
9647
+ "attrs": {
9648
+ "name": "sheet-1"
9649
+ },
9650
+ "children": [
9651
+ {
9652
+ "type": "row",
9653
+ "attrs": {
9654
+ "name": "sheet-1"
9655
+ },
9656
+ "children": [
9657
+ {
9658
+ "type": "column",
9659
+ "attrs": {
9660
+ "name": "group-1",
9661
+ "label": "",
9662
+ "className": "col-6"
9663
+ },
9664
+ "children": [
9665
+ {
9666
+ "type": "field",
9667
+ "attrs": {
9668
+ "name": "user"
9669
+ }
9670
+ }
9671
+ ]
9672
+ },
9673
+ {
9674
+ "type": "column",
9675
+ "attrs": {
9676
+ "name": "group-2",
9677
+ "label": "",
9678
+ "className": "col-6"
9679
+ },
9680
+ "children": []
9681
+ }
9682
+ ]
9683
+ }
9684
+ ]
9685
+ }
9686
+ ]
9687
+ }
9363
9688
  }
9364
9689
  ],
9365
9690
  "emailTemplates": [
@@ -4,6 +4,7 @@ import {
4
4
  ConflictException,
5
5
  Inject,
6
6
  Injectable,
7
+ InternalServerErrorException,
7
8
  Logger,
8
9
  NotFoundException,
9
10
  UnauthorizedException,
@@ -43,6 +44,8 @@ import { SettingService } from './setting.service';
43
44
  import { CreateUserDto } from 'src/dtos/create-user.dto';
44
45
  import { RoleMetadataService } from './role-metadata.service';
45
46
  import commonConfig from 'src/config/common.config';
47
+ import { UserActivityHistoryService } from './user-activity-history.service';
48
+ import { RequestContextService } from './request-context.service';
46
49
 
47
50
 
48
51
  enum LoginProvider {
@@ -79,13 +82,14 @@ export class AuthenticationService {
79
82
  private readonly roleMetadataService: RoleMetadataService,
80
83
  @Inject(commonConfig.KEY)
81
84
  private readonly commonConfiguration: ConfigType<typeof commonConfig>,
82
-
85
+ private readonly userActivityHistoryService: UserActivityHistoryService,
86
+ private readonly requestContextService: RequestContextService,
83
87
  ) { }
84
88
 
85
- private async getConfig( key: string): Promise<any> {
89
+ private async getConfig(key: string): Promise<any> {
86
90
  return this.settingService.getConfigValue(key);
87
91
  }
88
-
92
+
89
93
  private async getCompanyLogo(): Promise<string> {
90
94
  return await this.settingService.getConfigValue('companylogo');
91
95
  }
@@ -122,7 +126,7 @@ export class AuthenticationService {
122
126
 
123
127
  return user;
124
128
  }
125
-
129
+
126
130
  async signUp(signUpDto: SignUpDto, activeUser: ActiveUserData = null): Promise<User> {
127
131
  // If public registrations are disabled and no activeUser is present when invoking signUp then we throw an exception.
128
132
  if (!(await this.settingService.getConfigValue('allowPublicRegistration')) && !activeUser) {
@@ -131,7 +135,7 @@ export class AuthenticationService {
131
135
 
132
136
  try {
133
137
  const onForcePasswordChange = await this.getConfig('forceChangePasswordOnFirstLogin');
134
- var { user, pwd, autoGeneratedPwd } = await this.populateForSignup(new User(), signUpDto, this.iamConfiguration.activateUserOnRegistration,onForcePasswordChange);
138
+ var { user, pwd, autoGeneratedPwd } = await this.populateForSignup(new User(), signUpDto, this.iamConfiguration.activateUserOnRegistration, onForcePasswordChange);
135
139
  const savedUser = await this.userRepository.save(user);
136
140
  // Also assign a default role to the newly created user.
137
141
  const userRoles = signUpDto.roles ?? [];
@@ -145,7 +149,7 @@ export class AuthenticationService {
145
149
  return savedUser;
146
150
  } catch (err) {
147
151
  const pgUniqueViolationErrorCode = '23505';
148
- if (err.code === pgUniqueViolationErrorCode) {
152
+ if (err.code === pgUniqueViolationErrorCode) {
149
153
  throw new ConflictException();
150
154
  }
151
155
  throw err;
@@ -158,7 +162,7 @@ export class AuthenticationService {
158
162
  // Merge the extended signUpDto attributes into the user entity
159
163
  //@ts-ignore
160
164
  const extensionUser = extensionUserRepo.merge(extensionUserRepo.create() as T, extensionUserDto);
161
- var { user, pwd, autoGeneratedPwd } = await this.populateForSignup<T>(extensionUser, signUpDto,onForcePasswordChange);
165
+ var { user, pwd, autoGeneratedPwd } = await this.populateForSignup<T>(extensionUser, signUpDto, onForcePasswordChange);
162
166
  const savedUser = await extensionUserRepo.save(user);
163
167
 
164
168
  await this.handlePostSignup(savedUser, signUpDto.roles, pwd, autoGeneratedPwd);
@@ -175,7 +179,7 @@ export class AuthenticationService {
175
179
  }
176
180
 
177
181
 
178
- private async populateForSignup<T extends User>(user: T, signUpDto: SignUpDto, isUserActive: boolean = true,onForcePasswordChange?:boolean) {
182
+ private async populateForSignup<T extends User>(user: T, signUpDto: SignUpDto, isUserActive: boolean = true, onForcePasswordChange?: boolean) {
179
183
  // const user = new User();
180
184
 
181
185
  if (signUpDto.roles && signUpDto.roles.length > 0) {
@@ -191,7 +195,7 @@ export class AuthenticationService {
191
195
  if (signUpDto.mobile) {
192
196
  user.mobile = signUpDto.mobile;
193
197
  }
194
- this.logger.debug("user",user);
198
+ this.logger.debug("user", user);
195
199
  // If password has been specified by the user, then we simply create & activate the user based on the configuration parameter "activateUserOnRegistration".
196
200
  let pwd = '';
197
201
  let autoGeneratedPwd = '';
@@ -490,6 +494,9 @@ export class AuthenticationService {
490
494
 
491
495
  // TODO: Unset the password etc...
492
496
  const tokens = await this.generateTokens(user);
497
+
498
+ await this.userActivityHistoryService.logEvent('login', user);
499
+
493
500
  return {
494
501
  user: {
495
502
  email: user.email,
@@ -957,6 +964,8 @@ export class AuthenticationService {
957
964
 
958
965
  const currentRefreshToken = await this.refreshTokenIdsStorage.validateAndRotate(user, refreshTokenDto.refreshToken);
959
966
 
967
+ await this.userActivityHistoryService.logEvent('tokenRefreshed', user);
968
+
960
969
  return {
961
970
  accessToken: await this.generateAccessToken(user),
962
971
  refreshToken: currentRefreshToken,
@@ -1040,13 +1049,37 @@ export class AuthenticationService {
1040
1049
  }
1041
1050
 
1042
1051
  //FIXME - Pending implementation
1052
+ // async logout() {
1053
+ // // const user = this.request.user; //TODO: // Access the user from the execution context
1054
+
1055
+ // // Invalidate the refresh token
1056
+ // // await this.refreshTokenIdsStorage.invalidate(user.id);
1057
+ // }
1043
1058
  async logout() {
1044
- // const user = this.request.user; //TODO: // Access the user from the execution context
1059
+ try {
1060
+ const activeUser = this.requestContextService.getActiveUser();
1061
+ const userId = activeUser?.sub;
1062
+ const user = await this.userRepository.findOne({
1063
+ where: {
1064
+ id: userId,
1065
+ }
1066
+ })
1067
+ // Invalidate refresh token if you store them
1068
+ await this.refreshTokenIdsStorage.invalidate(userId); // ← Your existing logic
1069
+
1070
+ // Log logout event
1071
+ await this.userActivityHistoryService.logEvent('logout', user);
1045
1072
 
1046
- // Invalidate the refresh token
1047
- // await this.refreshTokenIdsStorage.invalidate(user.id);
1073
+
1074
+ return { message: 'Logged out successfully' };
1075
+ } catch (err) {
1076
+ throw err instanceof UnauthorizedException || err instanceof InternalServerErrorException
1077
+ ? err
1078
+ : new InternalServerErrorException('Logout failed due to an unexpected error.');
1079
+ }
1048
1080
  }
1049
1081
 
1082
+
1050
1083
  async activateUser(userId: number) {
1051
1084
  const user = await this.userService.findOne(userId, {});
1052
1085
  if (!user) {
@@ -12,4 +12,12 @@ export class RequestContextService {
12
12
  return this.cls.get(REQUEST_USER_KEY);
13
13
  }
14
14
 
15
+ getIp(): string | undefined {
16
+ return this.cls.get('ipAddress');
17
+ }
18
+
19
+ getUserAgent(): string | undefined {
20
+ return this.cls.get('userAgent');
21
+ }
22
+
15
23
  }