@bravobit/bb-foundation 0.21.4 → 0.22.0

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 (268) hide show
  1. package/auth/lib/auth.interceptor.d.ts +1 -1
  2. package/auth/lib/auth.module.d.ts +4 -5
  3. package/auth/lib/auth.service.d.ts +4 -7
  4. package/auth/lib/directives/abstract.directive.d.ts +12 -0
  5. package/auth/lib/directives/authenticated.directive.d.ts +7 -4
  6. package/auth/lib/directives/permission.directive.d.ts +11 -11
  7. package/auth/lib/guards/anonymous.guard.d.ts +8 -5
  8. package/auth/lib/guards/authenticated.guard.d.ts +8 -5
  9. package/auth/lib/guards/permission.guard.d.ts +15 -0
  10. package/auth/lib/interfaces/config.interface.d.ts +14 -8
  11. package/auth/lib/interfaces/permission.interface.d.ts +6 -0
  12. package/auth/lib/interfaces/provider.interface.d.ts +10 -3
  13. package/auth/lib/permissions/permissions.handler.d.ts +9 -0
  14. package/auth/lib/permissions/permissions.service.d.ts +16 -0
  15. package/auth/lib/providers/email.provider.d.ts +2 -8
  16. package/auth/lib/providers/verify.provider.d.ts +2 -6
  17. package/auth/public_api.d.ts +4 -4
  18. package/controls/lib/checkbox/checkbox/checkbox.component.d.ts +5 -1
  19. package/controls/lib/control-error/control-error/control-error.animation.d.ts +1 -0
  20. package/controls/lib/control-error/control-error/control-error.component.d.ts +17 -0
  21. package/controls/lib/control-error/control-error-submit.directive.d.ts +15 -0
  22. package/controls/lib/control-error/control-error.defaults.d.ts +2 -0
  23. package/controls/lib/control-error/control-error.interface.d.ts +12 -0
  24. package/controls/lib/control-error/control-error.module.d.ts +9 -0
  25. package/controls/lib/controls.interfaces.d.ts +4 -0
  26. package/controls/lib/controls.module.d.ts +7 -2
  27. package/controls/lib/form-control/form-control/form-control.component.d.ts +31 -0
  28. package/controls/lib/form-control/form-control-addon/form-control-addon.component.d.ts +6 -0
  29. package/controls/lib/form-control/form-control-input.directive.d.ts +35 -0
  30. package/controls/lib/form-control/form-control.module.d.ts +11 -0
  31. package/controls/public_api.d.ts +9 -0
  32. package/dashboard/lib/dashboard/dashboard.component.d.ts +2 -1
  33. package/dialog/lib/dialog-confirm/dialog-confirm.component.d.ts +10 -5
  34. package/dialog/lib/dialog-container/dialog-container.animations.d.ts +1 -0
  35. package/dialog/lib/dialog-container/dialog-container.component.d.ts +5 -7
  36. package/dialog/lib/dialog-header/dialog-header.component.d.ts +1 -3
  37. package/dialog/lib/dialog-modal/dialog-modal.component.d.ts +7 -3
  38. package/dialog/lib/dialog-overlay/dialog-overlay.animations.d.ts +1 -0
  39. package/dialog/lib/dialog-overlay/dialog-overlay.component.d.ts +5 -7
  40. package/dialog/lib/dialog.service.d.ts +4 -3
  41. package/elements/lib/directives/focus-trap.directive.d.ts +1 -1
  42. package/elements/lib/directives/focus.directive.d.ts +1 -3
  43. package/elements/lib/directives/form-submitter.directive.d.ts +9 -0
  44. package/elements/lib/elements.module.d.ts +25 -24
  45. package/elements/lib/form-error/form-error.component.d.ts +9 -5
  46. package/elements/lib/pipes/file-image.pipe.d.ts +2 -1
  47. package/elements/public_api.d.ts +1 -0
  48. package/esm2020/auth/lib/auth.interceptor.mjs +9 -12
  49. package/esm2020/auth/lib/auth.module.mjs +7 -17
  50. package/esm2020/auth/lib/auth.service.mjs +29 -55
  51. package/esm2020/auth/lib/directives/abstract.directive.mjs +40 -0
  52. package/esm2020/auth/lib/directives/authenticated.directive.mjs +25 -14
  53. package/esm2020/auth/lib/directives/permission.directive.mjs +24 -46
  54. package/esm2020/auth/lib/guards/anonymous.guard.mjs +28 -19
  55. package/esm2020/auth/lib/guards/authenticated.guard.mjs +31 -20
  56. package/esm2020/auth/lib/guards/permission.guard.mjs +53 -0
  57. package/esm2020/auth/lib/helpers/jwt.helper.mjs +7 -7
  58. package/esm2020/auth/lib/interfaces/config.interface.mjs +1 -1
  59. package/esm2020/auth/lib/interfaces/permission.interface.mjs +2 -0
  60. package/esm2020/auth/lib/interfaces/provider.interface.mjs +1 -1
  61. package/esm2020/auth/lib/permissions/permissions.handler.mjs +33 -0
  62. package/esm2020/auth/lib/permissions/permissions.service.mjs +64 -0
  63. package/esm2020/auth/lib/providers/email.provider.mjs +8 -9
  64. package/esm2020/auth/lib/providers/verify.provider.mjs +8 -5
  65. package/esm2020/auth/public_api.mjs +5 -5
  66. package/esm2020/collections/lib/collections.module.mjs +4 -4
  67. package/esm2020/collections/lib/components/collections-pager/collections-pager.component.mjs +3 -3
  68. package/esm2020/collections/lib/components/collections-viewer/collections-viewer.component.mjs +3 -3
  69. package/esm2020/collections/lib/components/collections.directive.mjs +12 -12
  70. package/esm2020/controls/lib/checkbox/checkbox/checkbox.component.mjs +19 -6
  71. package/esm2020/controls/lib/checkbox/checkbox-group/checkbox-group.component.mjs +4 -4
  72. package/esm2020/controls/lib/checkbox/checkbox.module.mjs +4 -4
  73. package/esm2020/controls/lib/control-error/control-error/control-error.animation.mjs +14 -0
  74. package/esm2020/controls/lib/control-error/control-error/control-error.component.mjs +63 -0
  75. package/esm2020/controls/lib/control-error/control-error-submit.directive.mjs +47 -0
  76. package/esm2020/controls/lib/control-error/control-error.defaults.mjs +26 -0
  77. package/esm2020/controls/lib/control-error/control-error.interface.mjs +3 -0
  78. package/esm2020/controls/lib/control-error/control-error.module.mjs +19 -0
  79. package/esm2020/controls/lib/controls.interfaces.mjs +2 -0
  80. package/esm2020/controls/lib/controls.module.mjs +45 -8
  81. package/esm2020/controls/lib/form-control/form-control/form-control.component.mjs +94 -0
  82. package/esm2020/controls/lib/form-control/form-control-addon/form-control-addon.component.mjs +22 -0
  83. package/esm2020/controls/lib/form-control/form-control-input.directive.mjs +124 -0
  84. package/esm2020/controls/lib/form-control/form-control.module.mjs +33 -0
  85. package/esm2020/controls/public_api.mjs +10 -1
  86. package/esm2020/dashboard/lib/dashboard/dashboard.component.mjs +7 -6
  87. package/esm2020/dashboard/lib/dashboard-header/dashboard-header.component.mjs +3 -3
  88. package/esm2020/dashboard/lib/dashboard-menu/dashboard-menu.component.mjs +3 -3
  89. package/esm2020/dashboard/lib/dashboard-menu-item/dashboard-menu-item.component.mjs +3 -3
  90. package/esm2020/dashboard/lib/dashboard-sidebar/dashboard-sidebar.component.mjs +3 -3
  91. package/esm2020/dashboard/lib/dashboard-sidebar-group/dashboard-sidebar-group.component.mjs +3 -3
  92. package/esm2020/dashboard/lib/dashboard-sidebar-item/dashboard-sidebar-item.component.mjs +3 -3
  93. package/esm2020/dashboard/lib/dashboard.module.mjs +4 -4
  94. package/esm2020/dialog/lib/dialog-actions/dialog-actions.component.mjs +3 -3
  95. package/esm2020/dialog/lib/dialog-confirm/dialog-confirm.component.mjs +17 -11
  96. package/esm2020/dialog/lib/dialog-container/dialog-container.animations.mjs +29 -0
  97. package/esm2020/dialog/lib/dialog-container/dialog-container.component.mjs +28 -104
  98. package/esm2020/dialog/lib/dialog-header/dialog-header.component.mjs +7 -14
  99. package/esm2020/dialog/lib/dialog-link/dialog-link.component.mjs +4 -4
  100. package/esm2020/dialog/lib/dialog-modal/dialog-modal.component.mjs +29 -8
  101. package/esm2020/dialog/lib/dialog-overlay/dialog-overlay.animations.mjs +26 -0
  102. package/esm2020/dialog/lib/dialog-overlay/dialog-overlay.component.mjs +29 -84
  103. package/esm2020/dialog/lib/dialog.insertion.mjs +3 -3
  104. package/esm2020/dialog/lib/dialog.module.mjs +4 -4
  105. package/esm2020/dialog/lib/dialog.service.mjs +8 -7
  106. package/esm2020/elements/lib/avatar/avatar.component.mjs +8 -6
  107. package/esm2020/elements/lib/button/button.component.mjs +6 -6
  108. package/esm2020/elements/lib/checkbox/checkbox.component.mjs +3 -3
  109. package/esm2020/elements/lib/date-picker/date-picker.component.mjs +3 -3
  110. package/esm2020/elements/lib/directives/addon.directive.mjs +6 -6
  111. package/esm2020/elements/lib/directives/autosize.directive.mjs +3 -3
  112. package/esm2020/elements/lib/directives/focus-trap.directive.mjs +5 -5
  113. package/esm2020/elements/lib/directives/focus.directive.mjs +7 -9
  114. package/esm2020/elements/lib/directives/form-submit.directive.mjs +3 -3
  115. package/esm2020/elements/lib/directives/form-submitter.directive.mjs +25 -0
  116. package/esm2020/elements/lib/directives/input.directive.mjs +6 -6
  117. package/esm2020/elements/lib/directives/template.directive.mjs +3 -3
  118. package/esm2020/elements/lib/dropdown/dropdown.component.mjs +6 -6
  119. package/esm2020/elements/lib/elements.module.mjs +9 -5
  120. package/esm2020/elements/lib/file-picker/file-picker.component.mjs +3 -3
  121. package/esm2020/elements/lib/form-control/form-control.component.mjs +3 -3
  122. package/esm2020/elements/lib/form-error/form-error.component.mjs +22 -7
  123. package/esm2020/elements/lib/form-group/form-group.component.mjs +3 -3
  124. package/esm2020/elements/lib/icon/icon.component.mjs +3 -3
  125. package/esm2020/elements/lib/image-picker/image-picker.component.mjs +3 -3
  126. package/esm2020/elements/lib/pipes/file-image.pipe.mjs +8 -7
  127. package/esm2020/elements/lib/pipes/file-size.pipe.mjs +3 -3
  128. package/esm2020/elements/lib/pipes/relative-time.pipe.mjs +3 -3
  129. package/esm2020/elements/lib/spinner/spinner.component.mjs +3 -3
  130. package/esm2020/elements/lib/tag/tag.component.mjs +3 -3
  131. package/esm2020/elements/public_api.mjs +2 -1
  132. package/esm2020/http/lib/http.module.mjs +4 -4
  133. package/esm2020/http/lib/interceptors/base-url.interceptor.mjs +3 -3
  134. package/esm2020/http/lib/interceptors/error.interceptor.mjs +3 -3
  135. package/esm2020/lib/core/services/clipboard.service.mjs +5 -5
  136. package/esm2020/lib/core/services/exif.service.mjs +5 -5
  137. package/esm2020/lib/core/services/file-loader.service.mjs +3 -3
  138. package/esm2020/lib/core/services/image-converter.service.mjs +5 -5
  139. package/esm2020/lib/core/services/languages.service.mjs +3 -3
  140. package/esm2020/lib/core/services/network.service.mjs +7 -7
  141. package/esm2020/lib/core/services/patch.service.mjs +7 -7
  142. package/esm2020/localize/lib/localize.module.mjs +4 -4
  143. package/esm2020/localize/lib/localize.pipe.mjs +3 -3
  144. package/esm2020/localize/lib/localize.service.mjs +5 -5
  145. package/esm2020/localize/lib/views/localize-string/localize-string.component.mjs +3 -3
  146. package/esm2020/localize/lib/views/localize-template-or-string.directive.mjs +3 -3
  147. package/esm2020/localize/lib/views/localize-template.directive.mjs +3 -3
  148. package/esm2020/masking/lib/directives/currency-mask.directive.mjs +3 -3
  149. package/esm2020/masking/lib/directives/date-mask.directive.mjs +3 -3
  150. package/esm2020/masking/lib/directives/input-mask.directive.mjs +7 -7
  151. package/esm2020/masking/lib/masking.module.mjs +4 -4
  152. package/esm2020/masking/lib/masking.service.mjs +3 -3
  153. package/esm2020/notifications/lib/notifications-item/notifications-item.component.mjs +5 -5
  154. package/esm2020/notifications/lib/notifications-list/notifications-list.component.mjs +7 -7
  155. package/esm2020/notifications/lib/notifications.module.mjs +4 -4
  156. package/esm2020/notifications/lib/notifications.service.mjs +5 -5
  157. package/esm2020/public_api.mjs +1 -2
  158. package/esm2020/recaptcha/lib/recaptcha/recaptcha.component.mjs +3 -3
  159. package/esm2020/recaptcha/lib/recaptcha-loader.service.mjs +10 -10
  160. package/esm2020/recaptcha/lib/recaptcha.module.mjs +4 -4
  161. package/esm2020/storage/lib/storage.service.mjs +5 -5
  162. package/esm2020/table/lib/components/table/table.component.mjs +9 -9
  163. package/esm2020/table/lib/components/table-cell/table-cell.component.mjs +3 -3
  164. package/esm2020/table/lib/components/table-header-cell/table-header-cell.component.mjs +3 -3
  165. package/esm2020/table/lib/components/table-pager/table-pager.component.mjs +3 -3
  166. package/esm2020/table/lib/table.module.mjs +4 -4
  167. package/esm2020/theming/lib/themes/checkbox-group.theme.mjs +17 -2
  168. package/esm2020/theming/lib/themes/checkbox.theme.mjs +35 -2
  169. package/esm2020/theming/lib/themes/control-error.theme.mjs +11 -0
  170. package/esm2020/theming/lib/themes/form-control-addon.theme.mjs +6 -0
  171. package/esm2020/theming/lib/themes/form-control.theme.mjs +45 -0
  172. package/esm2020/theming/lib/theming.data.mjs +82 -0
  173. package/esm2020/theming/lib/theming.directive.mjs +38 -0
  174. package/esm2020/theming/lib/theming.interface.mjs +2 -3
  175. package/esm2020/theming/lib/theming.module.mjs +12 -34
  176. package/esm2020/theming/lib/utils/theming.variable.mjs +41 -0
  177. package/esm2020/theming/public_api.mjs +6 -3
  178. package/fesm2015/bravobit-bb-foundation-auth.mjs +326 -284
  179. package/fesm2015/bravobit-bb-foundation-auth.mjs.map +1 -1
  180. package/fesm2015/bravobit-bb-foundation-collections.mjs +22 -22
  181. package/fesm2015/bravobit-bb-foundation-controls.mjs +493 -24
  182. package/fesm2015/bravobit-bb-foundation-controls.mjs.map +1 -1
  183. package/fesm2015/bravobit-bb-foundation-dashboard.mjs +29 -28
  184. package/fesm2015/bravobit-bb-foundation-dashboard.mjs.map +1 -1
  185. package/fesm2015/bravobit-bb-foundation-dialog.mjs +185 -233
  186. package/fesm2015/bravobit-bb-foundation-dialog.mjs.map +1 -1
  187. package/fesm2015/bravobit-bb-foundation-elements.mjs +140 -99
  188. package/fesm2015/bravobit-bb-foundation-elements.mjs.map +1 -1
  189. package/fesm2015/bravobit-bb-foundation-http.mjs +10 -10
  190. package/fesm2015/bravobit-bb-foundation-localize.mjs +20 -20
  191. package/fesm2015/bravobit-bb-foundation-localize.mjs.map +1 -1
  192. package/fesm2015/bravobit-bb-foundation-masking.mjs +20 -19
  193. package/fesm2015/bravobit-bb-foundation-masking.mjs.map +1 -1
  194. package/fesm2015/bravobit-bb-foundation-notifications.mjs +18 -17
  195. package/fesm2015/bravobit-bb-foundation-notifications.mjs.map +1 -1
  196. package/fesm2015/bravobit-bb-foundation-recaptcha.mjs +16 -16
  197. package/fesm2015/bravobit-bb-foundation-recaptcha.mjs.map +1 -1
  198. package/fesm2015/bravobit-bb-foundation-storage.mjs +4 -4
  199. package/fesm2015/bravobit-bb-foundation-storage.mjs.map +1 -1
  200. package/fesm2015/bravobit-bb-foundation-table.mjs +22 -22
  201. package/fesm2015/bravobit-bb-foundation-theming.mjs +251 -128
  202. package/fesm2015/bravobit-bb-foundation-theming.mjs.map +1 -1
  203. package/fesm2015/bravobit-bb-foundation.mjs +33 -73
  204. package/fesm2015/bravobit-bb-foundation.mjs.map +1 -1
  205. package/fesm2020/bravobit-bb-foundation-auth.mjs +306 -277
  206. package/fesm2020/bravobit-bb-foundation-auth.mjs.map +1 -1
  207. package/fesm2020/bravobit-bb-foundation-collections.mjs +22 -22
  208. package/fesm2020/bravobit-bb-foundation-controls.mjs +477 -24
  209. package/fesm2020/bravobit-bb-foundation-controls.mjs.map +1 -1
  210. package/fesm2020/bravobit-bb-foundation-dashboard.mjs +29 -28
  211. package/fesm2020/bravobit-bb-foundation-dashboard.mjs.map +1 -1
  212. package/fesm2020/bravobit-bb-foundation-dialog.mjs +175 -233
  213. package/fesm2020/bravobit-bb-foundation-dialog.mjs.map +1 -1
  214. package/fesm2020/bravobit-bb-foundation-elements.mjs +140 -99
  215. package/fesm2020/bravobit-bb-foundation-elements.mjs.map +1 -1
  216. package/fesm2020/bravobit-bb-foundation-http.mjs +10 -10
  217. package/fesm2020/bravobit-bb-foundation-localize.mjs +20 -20
  218. package/fesm2020/bravobit-bb-foundation-localize.mjs.map +1 -1
  219. package/fesm2020/bravobit-bb-foundation-masking.mjs +19 -19
  220. package/fesm2020/bravobit-bb-foundation-masking.mjs.map +1 -1
  221. package/fesm2020/bravobit-bb-foundation-notifications.mjs +17 -17
  222. package/fesm2020/bravobit-bb-foundation-notifications.mjs.map +1 -1
  223. package/fesm2020/bravobit-bb-foundation-recaptcha.mjs +16 -16
  224. package/fesm2020/bravobit-bb-foundation-recaptcha.mjs.map +1 -1
  225. package/fesm2020/bravobit-bb-foundation-storage.mjs +4 -4
  226. package/fesm2020/bravobit-bb-foundation-storage.mjs.map +1 -1
  227. package/fesm2020/bravobit-bb-foundation-table.mjs +22 -22
  228. package/fesm2020/bravobit-bb-foundation-theming.mjs +252 -120
  229. package/fesm2020/bravobit-bb-foundation-theming.mjs.map +1 -1
  230. package/fesm2020/bravobit-bb-foundation.mjs +32 -70
  231. package/fesm2020/bravobit-bb-foundation.mjs.map +1 -1
  232. package/lib/core/services/clipboard.service.d.ts +2 -2
  233. package/lib/core/services/exif.service.d.ts +1 -1
  234. package/lib/core/services/image-converter.service.d.ts +1 -1
  235. package/lib/core/services/network.service.d.ts +4 -4
  236. package/lib/core/services/patch.service.d.ts +4 -4
  237. package/localize/lib/localize.service.d.ts +1 -1
  238. package/notifications/lib/notifications-item/notifications-item.component.d.ts +1 -1
  239. package/notifications/lib/notifications.service.d.ts +1 -1
  240. package/package.json +4 -4
  241. package/public_api.d.ts +0 -1
  242. package/recaptcha/lib/recaptcha-loader.service.d.ts +3 -3
  243. package/storage/lib/storage.service.d.ts +1 -1
  244. package/theming/lib/themes/checkbox-group.theme.d.ts +14 -3
  245. package/theming/lib/themes/checkbox.theme.d.ts +30 -17
  246. package/theming/lib/themes/control-error.theme.d.ts +9 -0
  247. package/theming/lib/themes/form-control-addon.theme.d.ts +5 -0
  248. package/theming/lib/themes/form-control.theme.d.ts +32 -0
  249. package/theming/lib/theming.data.d.ts +17 -0
  250. package/theming/lib/theming.directive.d.ts +13 -0
  251. package/theming/lib/theming.interface.d.ts +19 -8
  252. package/theming/lib/theming.module.d.ts +3 -9
  253. package/theming/lib/utils/theming.variable.d.ts +16 -0
  254. package/theming/public_api.d.ts +5 -2
  255. package/auth/lib/directives/role.directive.d.ts +0 -16
  256. package/auth/lib/helpers/mapper.helper.d.ts +0 -23
  257. package/auth/lib/interfaces/mapper.interface.d.ts +0 -19
  258. package/auth/lib/permissions.service.d.ts +0 -14
  259. package/esm2020/auth/lib/directives/role.directive.mjs +0 -37
  260. package/esm2020/auth/lib/helpers/mapper.helper.mjs +0 -35
  261. package/esm2020/auth/lib/interfaces/mapper.interface.mjs +0 -2
  262. package/esm2020/auth/lib/permissions.service.mjs +0 -56
  263. package/esm2020/lib/core/services/platform.service.mjs +0 -42
  264. package/esm2020/theming/lib/themes/theme.mjs +0 -34
  265. package/esm2020/theming/lib/theming.service.mjs +0 -77
  266. package/lib/core/services/platform.service.d.ts +0 -18
  267. package/theming/lib/themes/theme.d.ts +0 -12
  268. package/theming/lib/theming.service.d.ts +0 -22
@@ -1,15 +1,16 @@
1
- import * as i4 from '@angular/common/http';
1
+ import * as i3 from '@angular/common/http';
2
2
  import { HttpContextToken, HttpContext, HttpErrorResponse, HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Injectable, Optional, Directive, Input, APP_INITIALIZER, NgModule } from '@angular/core';
5
- import { shareReplay, map, tap, distinctUntilChanged, switchMap, catchError, filter, take, finalize } from 'rxjs/operators';
6
- import * as i6 from '@angular/platform-browser';
5
+ import { shareReplay, tap, map, distinctUntilChanged, switchMap, catchError, filter, take, finalize } from 'rxjs/operators';
6
+ import { firstValueFrom, BehaviorSubject, of, Subscription, combineLatest, first, throwError } from 'rxjs';
7
+ import * as i5 from '@angular/platform-browser';
7
8
  import { makeStateKey } from '@angular/platform-browser';
8
- import { firstValueFrom, BehaviorSubject, of, throwError } from 'rxjs';
9
+ import * as i2$1 from '@angular/router';
9
10
  import { Router } from '@angular/router';
10
11
  import * as i1 from '@bravobit/bb-foundation/storage';
11
- import * as i3 from '@bravobit/bb-foundation';
12
- import * as i7 from '@bravobit/bb-foundation/http';
12
+ import * as i2 from '@angular/cdk/platform';
13
+ import * as i6 from '@bravobit/bb-foundation/http';
13
14
  import { HttpError } from '@bravobit/bb-foundation/http';
14
15
 
15
16
  class AuthConfig {
@@ -30,12 +31,12 @@ class JwtHelper {
30
31
  };
31
32
  this.parse = (data) => {
32
33
  return {
33
- id: data['iss'] || null,
34
- type: data['typ'] || null,
35
- audience: data['aud'] || null,
36
- issuer: data['iss'] || null,
37
- subject: data['sub'] || null,
38
- role: data['role'] || null,
34
+ id: data['iss'] ?? null,
35
+ type: data['typ'] ?? null,
36
+ audience: data['aud'] ?? null,
37
+ issuer: data['iss'] ?? null,
38
+ subject: data['sub'] ?? null,
39
+ role: data['role'] ?? null,
39
40
  notValidBefore: this.parseDate(data['nbf']),
40
41
  expiresAt: this.parseDate(data['exp']),
41
42
  issuedAt: this.parseDate(data['iat'])
@@ -86,38 +87,45 @@ class JwtHelper {
86
87
  }
87
88
  }
88
89
 
89
- class AuthMapper {
90
- constructor() {
91
- // Routes.
92
- this.me = 'auth/me';
93
- this.register = 'auth/register';
94
- this.resendCode = 'auth/resend';
95
- this.logout = 'auth/logout';
96
- this.refresh = 'auth/refresh';
97
- this.requestPassword = 'auth/reset';
98
- this.resetPassword = 'auth/reset-password';
99
- }
100
- role(data) {
101
- return (data && data.role) || null;
102
- }
103
- toRegister(data) {
104
- // Retrieve the params.
105
- const { token, refresh_token, user } = data;
106
- // Map the data to the correct format.
107
- return { accessToken: token, refreshToken: refresh_token, user: user };
108
- }
109
- toRefresh(data) {
110
- // Retrieve the params.
111
- const { token, refresh_token } = data;
112
- // Map the data to the correct format.
113
- return { accessToken: token, refreshToken: refresh_token };
90
+ class AbstractAuthDirective {
91
+ constructor(templateRef, viewContainerRef) {
92
+ this.templateRef = templateRef;
93
+ this.viewContainerRef = viewContainerRef;
94
+ // Data.
95
+ this.valid = false;
96
+ // Templates.
97
+ this.elseTemplateRef = null;
98
+ // View refs.
99
+ this.thenViewRef = null;
100
+ this.elseViewRef = null;
101
+ }
102
+ updateView() {
103
+ if (this.valid) {
104
+ if (!this.thenViewRef) {
105
+ this.viewContainerRef.clear();
106
+ this.elseViewRef = null;
107
+ if (this.templateRef) {
108
+ this.thenViewRef = this.viewContainerRef.createEmbeddedView(this.templateRef);
109
+ }
110
+ }
111
+ }
112
+ else {
113
+ if (!this.elseViewRef) {
114
+ this.viewContainerRef.clear();
115
+ this.thenViewRef = null;
116
+ if (this.elseTemplateRef) {
117
+ this.elseViewRef = this.viewContainerRef.createEmbeddedView(this.elseTemplateRef);
118
+ }
119
+ }
120
+ }
121
+ }
122
+ assertTemplate(property, templateRef) {
123
+ const isTemplateRefOrNull = !!(!templateRef || templateRef.createEmbeddedView);
124
+ if (!isTemplateRefOrNull) {
125
+ throw new Error(`${property} must be a TemplateRef.`);
126
+ }
114
127
  }
115
128
  }
116
- AuthMapper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: AuthMapper, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
117
- AuthMapper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: AuthMapper });
118
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: AuthMapper, decorators: [{
119
- type: Injectable
120
- }] });
121
129
 
122
130
  class AuthVerifyProvider {
123
131
  constructor(_code, _verifyToken, _endpoint) {
@@ -127,13 +135,16 @@ class AuthVerifyProvider {
127
135
  }
128
136
  async authenticate(httpClient) {
129
137
  // Execute API call.
130
- const data$ = await httpClient.post(this._endpoint, {
138
+ const data$ = httpClient.post(this._endpoint, {
131
139
  token: this._code,
132
140
  verify_token: this._verifyToken
133
141
  });
134
- const { token, refresh_token, user } = await firstValueFrom(data$);
135
- // Map the data to the correct format.
136
- return { accessToken: token, refreshToken: refresh_token, user: user };
142
+ const data = await firstValueFrom(data$);
143
+ return {
144
+ accessToken: data?.token,
145
+ refreshToken: data?.refresh_token,
146
+ user: data?.user
147
+ };
137
148
  }
138
149
  }
139
150
 
@@ -145,18 +156,17 @@ class AuthEmailProvider {
145
156
  }
146
157
  async authenticate(httpClient) {
147
158
  // Execute API call.
148
- const data$ = await httpClient.post(this._endpoint, {
159
+ const data$ = httpClient.post(this._endpoint, {
149
160
  email: this._email,
150
161
  password: this._password
151
162
  });
152
- const { token, refresh_token, user, provider, verify_token } = await firstValueFrom(data$);
153
- // Map the data to the correct format.
163
+ const data = await firstValueFrom(data$);
154
164
  return {
155
- accessToken: token,
156
- refreshToken: refresh_token,
157
- user: user,
158
- provider: provider,
159
- verifyToken: verify_token
165
+ accessToken: data?.token,
166
+ refreshToken: data?.refresh_token,
167
+ user: data?.user,
168
+ provider: data?.provider,
169
+ verifyToken: data?.verify_token
160
170
  };
161
171
  }
162
172
  }
@@ -290,9 +300,8 @@ class AuthSession {
290
300
  }
291
301
 
292
302
  class Auth {
293
- constructor(_storage, _mapper, _injector, _platform, _httpClient, _config, _state, _httpConfig) {
303
+ constructor(_storage, _injector, _platform, _httpClient, _config, _state, _httpConfig) {
294
304
  this._storage = _storage;
295
- this._mapper = _mapper;
296
305
  this._injector = _injector;
297
306
  this._platform = _platform;
298
307
  this._httpClient = _httpClient;
@@ -350,14 +359,15 @@ class Auth {
350
359
  async signIn(provider, as) {
351
360
  const { accessToken, refreshToken, user, ...result } = await provider.authenticate(this._httpClient);
352
361
  // Check if the role matches.
353
- if (as && !as.includes(this._mapper.role(user))) {
362
+ const role = this._config?.permissions?.getRole?.(user) ?? user?.role ?? null;
363
+ if (as && !as.includes(role)) {
354
364
  throw new Error('Invalid role.');
355
365
  }
356
366
  // Validate if the provider is one of the available
357
367
  // providers then return the user object and the provider.
358
368
  const apiProvider = result?.provider ?? null;
359
369
  const apiVerifyToken = result?.verifyToken ?? null;
360
- const availableProviders = ['email', 'sms', 'totp'];
370
+ const availableProviders = this._config?.providers ?? ['email', 'sms', 'totp'];
361
371
  if (availableProviders.includes(apiProvider)) {
362
372
  return { user, provider: apiProvider, verifyToken: apiVerifyToken };
363
373
  }
@@ -388,11 +398,10 @@ class Auth {
388
398
  const url = this.getUrl('auth/register');
389
399
  const result$ = this._httpClient.post(url, data, options);
390
400
  const result = await firstValueFrom(result$);
391
- // Map to the correct response.
392
- const { accessToken, refreshToken, user } = this._mapper.toRegister(result);
393
401
  // Set the tokens in storage.
394
- this.setTokens(accessToken, refreshToken);
402
+ this.setTokens(result?.token, result?.refresh_token);
395
403
  // Set the user in storage.
404
+ const user = result?.user;
396
405
  this.session.setUser(user);
397
406
  // Return the user.
398
407
  return user;
@@ -409,10 +418,11 @@ class Auth {
409
418
  // invalidate it in the backend.
410
419
  try {
411
420
  const url = this.getUrl('auth/logout');
421
+ const headerName = this._config?.http?.header ?? 'Authorization';
412
422
  const observable$ = this._httpClient.get(url, {
413
- headers: { Authorization: refreshToken }
423
+ headers: { [headerName]: refreshToken }
414
424
  });
415
- firstValueFrom(observable$).then(_ => _);
425
+ firstValueFrom(observable$).then(_ => _).catch(_ => _);
416
426
  }
417
427
  catch {
418
428
  // Do nothing because the tokens will be deleted anyways from the session.
@@ -428,14 +438,14 @@ class Auth {
428
438
  return of(null);
429
439
  }
430
440
  // Perform the refresh call.
431
- const scheme = this._config?.scheme ?? 'Bearer';
441
+ const headerName = this._config?.http?.header ?? 'Authorization';
442
+ const scheme = this._config?.http?.scheme ?? 'Bearer';
432
443
  const url = this.getUrl('auth/refresh');
433
- const context = new HttpContext()
434
- .set(USE_AUTHORIZATION, false);
444
+ const context = new HttpContext().set(USE_AUTHORIZATION, false);
435
445
  return this._httpClient.get(url, {
436
- headers: { Authorization: `${scheme} ${refreshToken}` },
446
+ headers: { [headerName]: `${scheme} ${refreshToken}` },
437
447
  context: context
438
- }).pipe(map(data => this._mapper.toRefresh(data)), tap(({ accessToken, refreshToken }) => this.setTokens(accessToken, refreshToken)), map(({ accessToken }) => accessToken));
448
+ }).pipe(tap(({ token, refresh_token }) => this.setTokens(token, refresh_token)), map(({ token }) => token));
439
449
  }
440
450
  async requestPassword(email, extraParams = {}) {
441
451
  const url = this.getUrl('auth/reset');
@@ -447,40 +457,15 @@ class Auth {
447
457
  const observable$ = this._httpClient.post(url, { ...extraParams, token, password: newPassword });
448
458
  return firstValueFrom(observable$);
449
459
  }
450
- guard(type, redirectUrl) {
451
- let newUrl = null;
452
- // Get the correct new url.
453
- switch (type) {
454
- case 'authenticated':
455
- newUrl = this._config?.loggedInUrl ?? null;
456
- break;
457
- case 'unauthenticated':
458
- newUrl = this._config?.redirectUrl ?? null;
459
- break;
460
- }
461
- // Append a redirect url if the user is deemed
462
- // unauthenticated.
463
- if (type === 'unauthenticated') {
464
- const setRedirectOnFailedAuth = this._config?.setRedirectOnFailedAuth ?? true;
465
- if (setRedirectOnFailedAuth && redirectUrl && newUrl) {
466
- newUrl += `?redirectUrl=${redirectUrl}`;
467
- }
468
- }
469
- // Parse the url if it exists.
470
- if (this.router && newUrl) {
471
- return this.router.parseUrl(newUrl);
472
- }
473
- // Return false if the user is not allowed.
474
- return false;
475
- }
476
460
  clearAndRedirect() {
477
461
  // 1. Delete the tokens from the session.
478
462
  this.session.clear();
479
463
  // 2. Compose the route url.
480
- const redirectUrl = this._config?.redirectUrl ?? null;
464
+ const redirectUrl = this._config?.redirects.unauthenticated ?? null;
481
465
  // 3. Route back if the user provided a redirect url.
482
466
  if (this.router && redirectUrl) {
483
- this.router.navigate([redirectUrl]).then(_ => _);
467
+ const commands = Array.isArray(redirectUrl) ? redirectUrl : [redirectUrl];
468
+ this.router.navigate(commands).then(_ => _);
484
469
  }
485
470
  }
486
471
  setTokens(accessToken, refreshToken) {
@@ -540,75 +525,51 @@ class Auth {
540
525
  .join('/');
541
526
  }
542
527
  }
543
- Auth.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: Auth, deps: [{ token: i1.Storage }, { token: AuthMapper }, { token: i0.Injector }, { token: i3.Platform }, { token: i4.HttpClient }, { token: AuthConfig, optional: true }, { token: i6.TransferState, optional: true }, { token: i7.HttpConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
544
- Auth.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: Auth });
545
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: Auth, decorators: [{
528
+ Auth.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: Auth, deps: [{ token: i1.Storage }, { token: i0.Injector }, { token: i2.Platform }, { token: i3.HttpClient }, { token: AuthConfig, optional: true }, { token: i5.TransferState, optional: true }, { token: i6.HttpConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
529
+ Auth.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: Auth });
530
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: Auth, decorators: [{
546
531
  type: Injectable
547
- }], ctorParameters: function () { return [{ type: i1.Storage }, { type: AuthMapper }, { type: i0.Injector }, { type: i3.Platform }, { type: i4.HttpClient }, { type: AuthConfig, decorators: [{
532
+ }], ctorParameters: function () { return [{ type: i1.Storage }, { type: i0.Injector }, { type: i2.Platform }, { type: i3.HttpClient }, { type: AuthConfig, decorators: [{
548
533
  type: Optional
549
- }] }, { type: i6.TransferState, decorators: [{
534
+ }] }, { type: i5.TransferState, decorators: [{
550
535
  type: Optional
551
- }] }, { type: i7.HttpConfig, decorators: [{
536
+ }] }, { type: i6.HttpConfig, decorators: [{
552
537
  type: Optional
553
538
  }] }]; } });
554
539
 
555
- class BbAuthenticated {
556
- constructor(_auth, _template, _viewContainerRef) {
540
+ class BbAuthenticated extends AbstractAuthDirective {
541
+ constructor(_auth, _templateRef, _viewContainerRef) {
542
+ super(_templateRef, _viewContainerRef);
557
543
  this._auth = _auth;
558
- this._template = _template;
544
+ this._templateRef = _templateRef;
559
545
  this._viewContainerRef = _viewContainerRef;
546
+ // Subscriptions.
547
+ this._subscription = new Subscription();
560
548
  }
561
- ngOnInit() {
562
- this._subscription = this._auth.user.pipe(map(user => !!user), distinctUntilChanged()).subscribe(isAuthenticated => {
563
- if (!isAuthenticated) {
564
- return this._viewContainerRef.clear();
565
- }
566
- this._viewContainerRef.createEmbeddedView(this._template);
567
- });
568
- }
569
- ngOnDestroy() {
570
- this._subscription?.unsubscribe();
571
- }
572
- }
573
- BbAuthenticated.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbAuthenticated, deps: [{ token: Auth }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
574
- BbAuthenticated.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.4", type: BbAuthenticated, selector: "[bbAuthenticated]", ngImport: i0 });
575
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbAuthenticated, decorators: [{
576
- type: Directive,
577
- args: [{
578
- selector: '[bbAuthenticated]'
579
- }]
580
- }], ctorParameters: function () { return [{ type: Auth }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; } });
581
-
582
- class BbRole {
583
- constructor(_auth, _template, _viewContainerRef) {
584
- this._auth = _auth;
585
- this._template = _template;
586
- this._viewContainerRef = _viewContainerRef;
587
- this.getAllowedRoles = (value) => {
588
- return Array.isArray(value) ? value : [value];
589
- };
549
+ set bbAuthenticatedElse(templateRef) {
550
+ this.assertTemplate('bbAuthenticatedElse', templateRef);
551
+ this.elseTemplateRef = templateRef;
552
+ this.updateView();
590
553
  }
591
554
  ngOnInit() {
592
- this._subscription = this._auth.user.pipe(map(user => user?.role ?? null), distinctUntilChanged()).subscribe(role => {
593
- const allowedRoles = this.getAllowedRoles(this.bbRole);
594
- if (!allowedRoles.includes(role)) {
595
- return this._viewContainerRef.clear();
596
- }
597
- this._viewContainerRef.createEmbeddedView(this._template);
555
+ const subscription = this._auth.user.pipe(map(user => !!user), distinctUntilChanged()).subscribe(valid => {
556
+ this.valid = valid;
557
+ this.updateView();
598
558
  });
559
+ this._subscription.add(subscription);
599
560
  }
600
561
  ngOnDestroy() {
601
562
  this._subscription?.unsubscribe();
602
563
  }
603
564
  }
604
- BbRole.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbRole, deps: [{ token: Auth }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
605
- BbRole.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.4", type: BbRole, selector: "[bbRole]", inputs: { bbRole: "bbRole" }, ngImport: i0 });
606
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbRole, decorators: [{
565
+ BbAuthenticated.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbAuthenticated, deps: [{ token: Auth }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
566
+ BbAuthenticated.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.1", type: BbAuthenticated, selector: "[bbAuthenticated]", inputs: { bbAuthenticatedElse: "bbAuthenticatedElse" }, usesInheritance: true, ngImport: i0 });
567
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbAuthenticated, decorators: [{
607
568
  type: Directive,
608
569
  args: [{
609
- selector: '[bbRole]'
570
+ selector: '[bbAuthenticated]'
610
571
  }]
611
- }], ctorParameters: function () { return [{ type: Auth }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; }, propDecorators: { bbRole: [{
572
+ }], ctorParameters: function () { return [{ type: Auth }, { type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; }, propDecorators: { bbAuthenticatedElse: [{
612
573
  type: Input
613
574
  }] } });
614
575
 
@@ -617,117 +578,99 @@ class Permissions {
617
578
  this._auth = _auth;
618
579
  this._config = _config;
619
580
  // Data.
620
- this._permissions = this._config?.permissions ?? {};
621
- this._role$ = this._auth.user.pipe(map(user => user?.role ?? null), distinctUntilChanged());
581
+ this._permissionHandler = this._config?.permissions ?? null;
622
582
  }
623
- has(value) {
624
- const requiredPermissions = Array.isArray(value)
625
- ? value
626
- : [value];
627
- return this._role$.pipe(map(role => {
628
- if (role === null || role === undefined) {
583
+ has(value, options) {
584
+ const requiredPermissions = this.getRequiredPermissions(value);
585
+ if (requiredPermissions?.length <= 0) {
586
+ return of(false);
587
+ }
588
+ return this._auth.user.pipe(map(user => {
589
+ if (user === null || user === undefined || !this._permissionHandler) {
629
590
  return false;
630
591
  }
631
- for (const requiredPermission of requiredPermissions) {
632
- const result = this.validatePermission(requiredPermission, role);
633
- if (!result) {
634
- return false;
635
- }
592
+ const mode = options?.mode ?? 'and';
593
+ switch (mode) {
594
+ case 'or':
595
+ return this.verifyModeOr(requiredPermissions, user);
596
+ case 'and':
597
+ default:
598
+ return this.verifyModeAnd(requiredPermissions, user);
636
599
  }
637
- return true;
638
- }));
600
+ }), distinctUntilChanged());
639
601
  }
640
- validatePermission(type, role) {
641
- const permission = this._permissions?.[type] ?? null;
642
- if (!permission) {
643
- console?.warn?.(`Permissions: Invalid permission requested "${type}".`);
644
- return false;
645
- }
646
- if (permission?.length <= 0) {
647
- console?.warn?.(`Permissions: No roles were set, please add some roles to this permission.`);
648
- return false;
602
+ verifyModeAnd(permissions, user) {
603
+ for (const permission of permissions) {
604
+ const verified = this._permissionHandler.verifyForUser(permission, user);
605
+ if (!verified) {
606
+ return false;
607
+ }
649
608
  }
650
- // If the permission includes a "*" we allow everyone.
651
- if (permission.includes('*')) {
652
- return true;
609
+ return true;
610
+ }
611
+ verifyModeOr(permissions, user) {
612
+ for (const permission of permissions) {
613
+ const verified = this._permissionHandler.verifyForUser(permission, user);
614
+ if (verified) {
615
+ return true;
616
+ }
653
617
  }
654
- // Validate the role against the permissions.
655
- return permission?.includes(role) ?? false;
618
+ return false;
619
+ }
620
+ getRequiredPermissions(value) {
621
+ return Array.isArray(value)
622
+ ? value
623
+ : [value];
656
624
  }
657
625
  }
658
- Permissions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: Permissions, deps: [{ token: Auth }, { token: AuthConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
659
- Permissions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: Permissions });
660
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: Permissions, decorators: [{
626
+ Permissions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: Permissions, deps: [{ token: Auth }, { token: AuthConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
627
+ Permissions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: Permissions });
628
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: Permissions, decorators: [{
661
629
  type: Injectable
662
630
  }], ctorParameters: function () { return [{ type: Auth }, { type: AuthConfig, decorators: [{
663
631
  type: Optional
664
632
  }] }]; } });
665
633
 
666
- class BbPermission {
634
+ class BbPermission extends AbstractAuthDirective {
667
635
  constructor(_permissions, _templateRef, _viewContainerRef) {
636
+ super(_templateRef, _viewContainerRef);
668
637
  this._permissions = _permissions;
669
638
  this._templateRef = _templateRef;
670
639
  this._viewContainerRef = _viewContainerRef;
671
640
  // Data.
672
641
  this._permission$ = new BehaviorSubject([]);
673
- this._valid = false;
674
- this._elseTemplateRef = null;
675
- this._thenViewRef = null;
676
- this._elseViewRef = null;
677
- this.getAllowedPermissions = (value) => {
678
- return Array.isArray(value) ? value : [value];
679
- };
680
- this.assertTemplate = (property, templateRef) => {
681
- const isTemplateRefOrNull = !!(!templateRef || templateRef.createEmbeddedView);
682
- if (!isTemplateRefOrNull) {
683
- throw new Error(`${property} must be a TemplateRef.`);
684
- }
685
- };
642
+ this._mode$ = new BehaviorSubject('and');
643
+ // Subscriptions.
644
+ this._subscription = new Subscription();
686
645
  }
687
646
  set bbPermission(value) {
688
- const permissions = this.getAllowedPermissions(value);
647
+ const permissions = Array.isArray(value) ? value : [value];
689
648
  this._permission$.next(permissions);
690
649
  this.updateView();
691
650
  }
692
651
  set bbPermissionElse(templateRef) {
693
652
  this.assertTemplate('bbPermissionElse', templateRef);
694
- this._elseTemplateRef = templateRef;
653
+ this.elseTemplateRef = templateRef;
695
654
  this.updateView();
696
655
  }
656
+ set bbPermissionMode(mode) {
657
+ this._mode$.next(mode);
658
+ }
697
659
  ngOnInit() {
698
- const check$ = this._permission$.pipe(switchMap(permissions => this._permissions.has(permissions)));
699
- this._subscription = check$.subscribe(valid => {
700
- this._valid = valid;
660
+ const check$ = combineLatest([this._permission$, this._mode$]).pipe(switchMap(([permissions, mode]) => this._permissions.has(permissions, { mode })), distinctUntilChanged());
661
+ const subscription = check$.subscribe(valid => {
662
+ this.valid = valid;
701
663
  this.updateView();
702
664
  });
665
+ this._subscription.add(subscription);
703
666
  }
704
667
  ngOnDestroy() {
705
668
  this._subscription?.unsubscribe();
706
669
  }
707
- updateView() {
708
- if (this._valid) {
709
- if (!this._thenViewRef) {
710
- this._viewContainerRef.clear();
711
- this._elseViewRef = null;
712
- if (this._templateRef) {
713
- this._thenViewRef = this._viewContainerRef.createEmbeddedView(this._templateRef);
714
- }
715
- }
716
- }
717
- else {
718
- if (!this._elseViewRef) {
719
- this._viewContainerRef.clear();
720
- this._thenViewRef = null;
721
- if (this._elseTemplateRef) {
722
- this._elseViewRef = this._viewContainerRef.createEmbeddedView(this._elseTemplateRef);
723
- }
724
- }
725
- }
726
- }
727
670
  }
728
- BbPermission.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbPermission, deps: [{ token: Permissions }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
729
- BbPermission.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.4", type: BbPermission, selector: "[bbPermission]", inputs: { bbPermission: "bbPermission", bbPermissionElse: "bbPermissionElse" }, ngImport: i0 });
730
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbPermission, decorators: [{
671
+ BbPermission.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbPermission, deps: [{ token: Permissions }, { token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
672
+ BbPermission.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.1", type: BbPermission, selector: "[bbPermission]", inputs: { bbPermission: "bbPermission", bbPermissionElse: "bbPermissionElse", bbPermissionMode: "bbPermissionMode" }, usesInheritance: true, ngImport: i0 });
673
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbPermission, decorators: [{
731
674
  type: Directive,
732
675
  args: [{
733
676
  selector: '[bbPermission]'
@@ -736,80 +679,178 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImpor
736
679
  type: Input
737
680
  }], bbPermissionElse: [{
738
681
  type: Input
682
+ }], bbPermissionMode: [{
683
+ type: Input
739
684
  }] } });
740
685
 
686
+ class AppPermissions {
687
+ constructor(_data) {
688
+ this._data = _data;
689
+ }
690
+ verify(permission, role) {
691
+ if ((typeof ngDevMode === 'undefined' || ngDevMode) && !this._data?.[role]) {
692
+ console?.warn?.(`Current permissions do not include role: "${role}".`);
693
+ }
694
+ const availablePermissions = this._data?.[role] ?? [];
695
+ return availablePermissions.includes(permission);
696
+ }
697
+ verifyForUser(permission, data) {
698
+ const role = this.getRole(data);
699
+ return this.verify(permission, role);
700
+ }
701
+ getRole(data) {
702
+ return data?.['role'] ?? null;
703
+ }
704
+ static forRoles(data) {
705
+ const permissions = Object.keys(data) ?? [];
706
+ const roles = permissions.reduce((previous, current) => ([
707
+ ...previous,
708
+ ...(data?.[current] ?? [])
709
+ ]), []);
710
+ const uniqueRoles = [...new Set(roles)];
711
+ const formattedData = uniqueRoles.reduce((previous, current) => {
712
+ const rolePermissions = permissions.filter(permission => data?.[permission]?.includes(current));
713
+ return { ...previous, [current]: rolePermissions };
714
+ }, {});
715
+ return new AppPermissions(formattedData);
716
+ }
717
+ }
718
+
741
719
  class BbAnonymousGuard {
742
- constructor(_auth) {
720
+ constructor(_auth, _router, _config) {
743
721
  this._auth = _auth;
722
+ this._router = _router;
723
+ this._config = _config;
744
724
  }
745
- async canActivate(_, state) {
746
- // Check if the user is authenticated.
747
- const isAuthenticated$ = await this._auth.user.pipe(map(user => !!user));
748
- // If the user is not authenticated it can
749
- // access the anonymous page.
750
- const isAuthenticated = await firstValueFrom(isAuthenticated$, { defaultValue: null });
751
- if (!isAuthenticated) {
752
- return true;
753
- }
754
- // Return the user back to the authenticated page.
755
- return this._auth.guard('authenticated', state.url);
725
+ canActivate(_, __) {
726
+ return this._auth.user.pipe(map(user => !!user), map(isAuthenticated => {
727
+ if (!isAuthenticated) {
728
+ return true;
729
+ }
730
+ // If we don't have a URL to go to we can just say
731
+ // the user is not allowed in this route by returning false.
732
+ const nextUrl = this._config?.redirects?.authenticated ?? null;
733
+ if (!nextUrl) {
734
+ return false;
735
+ }
736
+ const commands = Array.isArray(nextUrl) ? nextUrl : [nextUrl];
737
+ return this._router.createUrlTree(commands);
738
+ }), first());
756
739
  }
757
740
  canActivateChild(childRoute, state) {
758
741
  return this.canActivate(childRoute, state);
759
742
  }
760
743
  }
761
- BbAnonymousGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbAnonymousGuard, deps: [{ token: Auth }], target: i0.ɵɵFactoryTarget.Injectable });
762
- BbAnonymousGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbAnonymousGuard, providedIn: 'root' });
763
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbAnonymousGuard, decorators: [{
744
+ BbAnonymousGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbAnonymousGuard, deps: [{ token: Auth }, { token: i2$1.Router }, { token: AuthConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
745
+ BbAnonymousGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbAnonymousGuard, providedIn: 'root' });
746
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbAnonymousGuard, decorators: [{
764
747
  type: Injectable,
765
748
  args: [{
766
749
  providedIn: 'root'
767
750
  }]
768
- }], ctorParameters: function () { return [{ type: Auth }]; } });
751
+ }], ctorParameters: function () { return [{ type: Auth }, { type: i2$1.Router }, { type: AuthConfig, decorators: [{
752
+ type: Optional
753
+ }] }]; } });
769
754
 
770
755
  class BbAuthenticatedGuard {
771
- constructor(_auth) {
756
+ constructor(_auth, _router, _config) {
772
757
  this._auth = _auth;
758
+ this._router = _router;
759
+ this._config = _config;
773
760
  }
774
- async canActivate(_, state) {
775
- // Check if the user is authenticated.
776
- const isAuthenticated$ = await this._auth.user.pipe(map(user => !!user));
777
- // If the user is authenticated it can
778
- // access the authenticated page.
779
- const isAuthenticated = await firstValueFrom(isAuthenticated$, { defaultValue: null });
780
- if (isAuthenticated) {
781
- return true;
782
- }
783
- // The user is not authorized to see that
784
- // page so un-authorize him.
785
- return this._auth.guard('unauthenticated', state.url);
761
+ canActivate(_, state) {
762
+ return this._auth.user.pipe(map(user => !!user), map(isAuthenticated => {
763
+ if (isAuthenticated) {
764
+ return true;
765
+ }
766
+ // If we don't have a URL to go to we can just say
767
+ // the user is not allowed in this route by returning false.
768
+ const nextUrl = this._config?.redirects?.unauthenticated ?? null;
769
+ if (!nextUrl) {
770
+ return false;
771
+ }
772
+ const setRedirectOnFailedAuth = this._config?.setRedirectOnFailedAuth ?? true;
773
+ const redirectUrl = state?.url ?? null;
774
+ const queryParams = setRedirectOnFailedAuth && redirectUrl ? { redirectUrl } : {};
775
+ const commands = Array.isArray(nextUrl) ? nextUrl : [nextUrl];
776
+ return this._router.createUrlTree(commands, { queryParams });
777
+ }), first());
786
778
  }
787
779
  canActivateChild(childRoute, state) {
788
780
  return this.canActivate(childRoute, state);
789
781
  }
790
782
  }
791
- BbAuthenticatedGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbAuthenticatedGuard, deps: [{ token: Auth }], target: i0.ɵɵFactoryTarget.Injectable });
792
- BbAuthenticatedGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbAuthenticatedGuard, providedIn: 'root' });
793
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: BbAuthenticatedGuard, decorators: [{
783
+ BbAuthenticatedGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbAuthenticatedGuard, deps: [{ token: Auth }, { token: i2$1.Router }, { token: AuthConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
784
+ BbAuthenticatedGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbAuthenticatedGuard, providedIn: 'root' });
785
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbAuthenticatedGuard, decorators: [{
794
786
  type: Injectable,
795
787
  args: [{
796
788
  providedIn: 'root'
797
789
  }]
798
- }], ctorParameters: function () { return [{ type: Auth }]; } });
790
+ }], ctorParameters: function () { return [{ type: Auth }, { type: i2$1.Router }, { type: AuthConfig, decorators: [{
791
+ type: Optional
792
+ }] }]; } });
793
+
794
+ class BbPermissionGuard {
795
+ constructor(_router, _permissions, _config) {
796
+ this._router = _router;
797
+ this._permissions = _permissions;
798
+ this._config = _config;
799
+ }
800
+ canActivate(snapshot, _) {
801
+ const permission = snapshot?.data?.['permission'] ?? null;
802
+ const permission$ = this.parsePermission(permission);
803
+ return permission$.pipe(map(valid => {
804
+ if (valid) {
805
+ return true;
806
+ }
807
+ const nextUrl = this._config?.redirects?.permissionDenied ?? null;
808
+ if (!nextUrl) {
809
+ return false;
810
+ }
811
+ const commands = Array.isArray(nextUrl) ? nextUrl : [nextUrl];
812
+ return valid ? true : this._router.createUrlTree(commands);
813
+ }));
814
+ }
815
+ canActivateChild(childRoute, state) {
816
+ return this.canActivate(childRoute, state);
817
+ }
818
+ parsePermission(data) {
819
+ if ((typeof ngDevMode === 'undefined' || ngDevMode) && (data === undefined || data === null)) {
820
+ console?.warn?.(`No "data.permission" property was passed.`);
821
+ return of(false);
822
+ }
823
+ if (Array.isArray(data) || typeof data === 'string') {
824
+ return this._permissions.has(data);
825
+ }
826
+ return this._permissions.has(data?.value, data?.options);
827
+ }
828
+ }
829
+ BbPermissionGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbPermissionGuard, deps: [{ token: i2$1.Router }, { token: Permissions }, { token: AuthConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
830
+ BbPermissionGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbPermissionGuard, providedIn: 'root' });
831
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: BbPermissionGuard, decorators: [{
832
+ type: Injectable,
833
+ args: [{
834
+ providedIn: 'root'
835
+ }]
836
+ }], ctorParameters: function () { return [{ type: i2$1.Router }, { type: Permissions }, { type: AuthConfig, decorators: [{
837
+ type: Optional
838
+ }] }]; } });
799
839
 
800
840
  class AuthInterceptor {
801
841
  constructor(_auth, _config) {
802
842
  this._auth = _auth;
803
843
  this._config = _config;
804
844
  // Readonly data.
805
- this._authHeaderString = 'Authorization';
845
+ this._authHeaderString = this._config?.http?.header ?? 'Authorization';
846
+ this._authScheme = this._config?.http?.scheme ?? 'Bearer';
806
847
  // Data.
807
848
  this.isRefreshing = false;
808
849
  this.refreshingAccessToken$ = new BehaviorSubject(null);
809
850
  this.getAccessToken = (request) => {
810
851
  // Get the token based on header.
811
- if (request.headers.has('Authorization')) {
812
- return request.headers.get('Authorization');
852
+ if (request.headers.has(this._authHeaderString)) {
853
+ return request.headers.get(this._authHeaderString);
813
854
  }
814
855
  // Return the default access token.
815
856
  return this._auth.session.accessToken;
@@ -824,13 +865,9 @@ class AuthInterceptor {
824
865
  }
825
866
  // Add the auth header to the request.
826
867
  return request.clone({
827
- setHeaders: { [this._authHeaderString]: this.getFullAuthorizationHeader(accessToken) }
868
+ setHeaders: { [this._authHeaderString]: `${this._authScheme} ${accessToken}` }
828
869
  });
829
870
  };
830
- this.getFullAuthorizationHeader = (token) => {
831
- const authScheme = this._config?.scheme ?? 'Bearer';
832
- return [authScheme, token].join(' ');
833
- };
834
871
  }
835
872
  intercept(request, next) {
836
873
  // 1. Check if the user wants to use the authorization for this request.
@@ -873,9 +910,9 @@ class AuthInterceptor {
873
910
  return of(null);
874
911
  }
875
912
  }
876
- AuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: AuthInterceptor, deps: [{ token: Auth }, { token: AuthConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
877
- AuthInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: AuthInterceptor });
878
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: AuthInterceptor, decorators: [{
913
+ AuthInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: AuthInterceptor, deps: [{ token: Auth }, { token: AuthConfig, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
914
+ AuthInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: AuthInterceptor });
915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: AuthInterceptor, decorators: [{
879
916
  type: Injectable
880
917
  }], ctorParameters: function () { return [{ type: Auth }, { type: AuthConfig, decorators: [{
881
918
  type: Optional
@@ -883,7 +920,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImpor
883
920
 
884
921
  const DECLARATIONS_EXPORTS = [
885
922
  BbAuthenticated,
886
- BbRole,
887
923
  BbPermission
888
924
  ];
889
925
  class AuthModule {
@@ -900,24 +936,17 @@ class AuthModule {
900
936
  };
901
937
  }
902
938
  }
903
- AuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: AuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
904
- AuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.4", ngImport: i0, type: AuthModule, declarations: [BbAuthenticated,
905
- BbRole,
939
+ AuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: AuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
940
+ AuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.1", ngImport: i0, type: AuthModule, declarations: [BbAuthenticated,
906
941
  BbPermission], imports: [HttpClientModule], exports: [BbAuthenticated,
907
- BbRole,
908
942
  BbPermission] });
909
- AuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: AuthModule, providers: [
910
- { provide: AuthMapper, useClass: AuthMapper }
911
- ], imports: [HttpClientModule] });
912
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.4", ngImport: i0, type: AuthModule, decorators: [{
943
+ AuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: AuthModule, imports: [HttpClientModule] });
944
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.1", ngImport: i0, type: AuthModule, decorators: [{
913
945
  type: NgModule,
914
946
  args: [{
915
947
  imports: [HttpClientModule],
916
948
  declarations: [...DECLARATIONS_EXPORTS],
917
- exports: [...DECLARATIONS_EXPORTS],
918
- providers: [
919
- { provide: AuthMapper, useClass: AuthMapper }
920
- ]
949
+ exports: [...DECLARATIONS_EXPORTS]
921
950
  }]
922
951
  }] });
923
952
  function initializeAuth(auth) {
@@ -928,5 +957,5 @@ function initializeAuth(auth) {
928
957
  * Generated bundle index. Do not edit.
929
958
  */
930
959
 
931
- export { Auth, AuthConfig, AuthEmailProvider, AuthMapper, AuthModule, AuthSession, AuthVerifyProvider, BbAnonymousGuard, BbAuthenticated, BbAuthenticatedGuard, BbPermission, BbRole, JwtHelper, Permissions, USE_AUTHORIZATION, initializeAuth };
960
+ export { AppPermissions, Auth, AuthConfig, AuthEmailProvider, AuthModule, AuthSession, AuthVerifyProvider, BbAnonymousGuard, BbAuthenticated, BbAuthenticatedGuard, BbPermission, BbPermissionGuard, JwtHelper, Permissions, USE_AUTHORIZATION, initializeAuth };
932
961
  //# sourceMappingURL=bravobit-bb-foundation-auth.mjs.map