@lenne.tech/ng-base 18.1.2 → 22.0.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 (416) hide show
  1. package/CLAUDE.md +55 -0
  2. package/LICENSE +2 -2
  3. package/README.md +237 -44
  4. package/fesm2022/lenne.tech-ng-base-ai.mjs +767 -0
  5. package/fesm2022/lenne.tech-ng-base-ai.mjs.map +1 -0
  6. package/fesm2022/lenne.tech-ng-base-auth-provide.mjs +939 -0
  7. package/fesm2022/lenne.tech-ng-base-auth-provide.mjs.map +1 -0
  8. package/fesm2022/lenne.tech-ng-base-auth.mjs +454 -0
  9. package/fesm2022/lenne.tech-ng-base-auth.mjs.map +1 -0
  10. package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs +825 -0
  11. package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs.map +1 -0
  12. package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs +351 -0
  13. package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs.map +1 -0
  14. package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs +1046 -0
  15. package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs.map +1 -0
  16. package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs +4 -0
  17. package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs.map +1 -0
  18. package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs +179 -0
  19. package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs.map +1 -0
  20. package/fesm2022/lenne.tech-ng-base-bug-provide.mjs +26 -0
  21. package/fesm2022/lenne.tech-ng-base-bug-provide.mjs.map +1 -0
  22. package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs +62 -0
  23. package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs.map +1 -0
  24. package/fesm2022/lenne.tech-ng-base-bug-server.mjs +818 -0
  25. package/fesm2022/lenne.tech-ng-base-bug-server.mjs.map +1 -0
  26. package/fesm2022/lenne.tech-ng-base-bug.mjs +196 -0
  27. package/fesm2022/lenne.tech-ng-base-bug.mjs.map +1 -0
  28. package/fesm2022/lenne.tech-ng-base-files-ui.mjs +445 -0
  29. package/fesm2022/lenne.tech-ng-base-files-ui.mjs.map +1 -0
  30. package/fesm2022/lenne.tech-ng-base-files.mjs +474 -0
  31. package/fesm2022/lenne.tech-ng-base-files.mjs.map +1 -0
  32. package/fesm2022/lenne.tech-ng-base-server.mjs +408 -0
  33. package/fesm2022/lenne.tech-ng-base-server.mjs.map +1 -0
  34. package/fesm2022/lenne.tech-ng-base-share.mjs +76 -0
  35. package/fesm2022/lenne.tech-ng-base-share.mjs.map +1 -0
  36. package/fesm2022/lenne.tech-ng-base-sync.mjs +1096 -0
  37. package/fesm2022/lenne.tech-ng-base-sync.mjs.map +1 -0
  38. package/fesm2022/lenne.tech-ng-base-testing.mjs +171 -0
  39. package/fesm2022/lenne.tech-ng-base-testing.mjs.map +1 -0
  40. package/fesm2022/lenne.tech-ng-base-ui-provide.mjs +124 -0
  41. package/fesm2022/lenne.tech-ng-base-ui-provide.mjs.map +1 -0
  42. package/fesm2022/lenne.tech-ng-base-ui.mjs +34611 -0
  43. package/fesm2022/lenne.tech-ng-base-ui.mjs.map +1 -0
  44. package/fesm2022/lenne.tech-ng-base-utils.mjs +287 -0
  45. package/fesm2022/lenne.tech-ng-base-utils.mjs.map +1 -0
  46. package/fesm2022/lenne.tech-ng-base.mjs +615 -902
  47. package/fesm2022/lenne.tech-ng-base.mjs.map +1 -1
  48. package/i18n/auth/de.json +17 -0
  49. package/i18n/auth/en.json +17 -0
  50. package/i18n/bug/de.json +85 -0
  51. package/i18n/bug/en.json +85 -0
  52. package/i18n/de.json +8 -0
  53. package/i18n/en.json +8 -0
  54. package/i18n/files/de.json +27 -0
  55. package/i18n/files/en.json +27 -0
  56. package/i18n/share/de.json +8 -0
  57. package/i18n/share/en.json +8 -0
  58. package/i18n/ui/de.json +38 -0
  59. package/i18n/ui/en.json +38 -0
  60. package/package.json +127 -58
  61. package/types/lenne.tech-ng-base-ai.d.ts +830 -0
  62. package/types/lenne.tech-ng-base-auth-provide.d.ts +603 -0
  63. package/types/lenne.tech-ng-base-auth.d.ts +320 -0
  64. package/types/lenne.tech-ng-base-bug-provide.d.ts +272 -0
  65. package/types/lenne.tech-ng-base-bug-rolldown-runtime-C25Le4-w.d.ts +1 -0
  66. package/types/lenne.tech-ng-base-bug-server.d.ts +316 -0
  67. package/types/lenne.tech-ng-base-bug.d.ts +202 -0
  68. package/types/lenne.tech-ng-base-files-ui.d.ts +116 -0
  69. package/types/lenne.tech-ng-base-files.d.ts +288 -0
  70. package/types/lenne.tech-ng-base-server.d.ts +262 -0
  71. package/types/lenne.tech-ng-base-share.d.ts +21 -0
  72. package/types/lenne.tech-ng-base-sync.d.ts +380 -0
  73. package/types/lenne.tech-ng-base-testing.d.ts +327 -0
  74. package/types/lenne.tech-ng-base-ui-provide.d.ts +65 -0
  75. package/types/lenne.tech-ng-base-ui.d.ts +7732 -0
  76. package/types/lenne.tech-ng-base-utils.d.ts +150 -0
  77. package/types/lenne.tech-ng-base.d.ts +503 -0
  78. package/ui/styles/components/accordion.css +3 -0
  79. package/ui/styles/components/alert-dialog.css +4 -0
  80. package/ui/styles/components/alert.css +3 -0
  81. package/ui/styles/components/aspect-ratio.css +3 -0
  82. package/ui/styles/components/attachment.css +4 -0
  83. package/ui/styles/components/autocomplete.css +4 -0
  84. package/ui/styles/components/avatar.css +3 -0
  85. package/ui/styles/components/badge.css +3 -0
  86. package/ui/styles/components/breadcrumb.css +3 -0
  87. package/ui/styles/components/bubble.css +3 -0
  88. package/ui/styles/components/button-group.css +3 -0
  89. package/ui/styles/components/button.css +3 -0
  90. package/ui/styles/components/calendar.css +5 -0
  91. package/ui/styles/components/card.css +3 -0
  92. package/ui/styles/components/checkbox.css +3 -0
  93. package/ui/styles/components/code-block.css +4 -0
  94. package/ui/styles/components/collapsible.css +3 -0
  95. package/ui/styles/components/combobox.css +5 -0
  96. package/ui/styles/components/command.css +5 -0
  97. package/ui/styles/components/context-menu.css +3 -0
  98. package/ui/styles/components/date-picker.css +7 -0
  99. package/ui/styles/components/dialog.css +4 -0
  100. package/ui/styles/components/drawer.css +3 -0
  101. package/ui/styles/components/dropdown-menu.css +3 -0
  102. package/ui/styles/components/empty.css +3 -0
  103. package/ui/styles/components/field.css +5 -0
  104. package/ui/styles/components/hover-card.css +3 -0
  105. package/ui/styles/components/index.css +91 -0
  106. package/ui/styles/components/input-group.css +6 -0
  107. package/ui/styles/components/input-otp.css +3 -0
  108. package/ui/styles/components/input.css +3 -0
  109. package/ui/styles/components/item.css +4 -0
  110. package/ui/styles/components/kbd.css +3 -0
  111. package/ui/styles/components/label.css +3 -0
  112. package/ui/styles/components/lt-breadcrumb.css +3 -0
  113. package/ui/styles/components/lt-bug-attachments.css +5 -0
  114. package/ui/styles/components/lt-bug-journey-timeline.css +5 -0
  115. package/ui/styles/components/lt-bug-report-dialog.css +15 -0
  116. package/ui/styles/components/lt-bug-report.css +4 -0
  117. package/ui/styles/components/lt-color-mode-button.css +3 -0
  118. package/ui/styles/components/lt-confirm-dialog.css +4 -0
  119. package/ui/styles/components/lt-data-view.css +5 -0
  120. package/ui/styles/components/lt-date-picker.css +3 -0
  121. package/ui/styles/components/lt-date-time-picker.css +5 -0
  122. package/ui/styles/components/lt-enter-action.css +2 -0
  123. package/ui/styles/components/lt-footer.css +3 -0
  124. package/ui/styles/components/lt-form-field.css +4 -0
  125. package/ui/styles/components/lt-header.css +5 -0
  126. package/ui/styles/components/lt-imports.css +21 -0
  127. package/ui/styles/components/lt-navigation-menu.css +3 -0
  128. package/ui/styles/components/lt-notice.css +3 -0
  129. package/ui/styles/components/lt-overlay-defaults.css +3 -0
  130. package/ui/styles/components/lt-page-card.css +3 -0
  131. package/ui/styles/components/lt-page-title.css +2 -0
  132. package/ui/styles/components/lt-password-input.css +4 -0
  133. package/ui/styles/components/lt-readonly-field.css +2 -0
  134. package/ui/styles/components/lt-select.css +4 -0
  135. package/ui/styles/components/lt-text-field.css +5 -0
  136. package/ui/styles/components/lt-toolbar-item.css +2 -0
  137. package/ui/styles/components/lt-toolbar.css +3 -0
  138. package/ui/styles/components/lt-tus-upload-component.css +5 -0
  139. package/ui/styles/components/marker.css +3 -0
  140. package/ui/styles/components/menubar.css +3 -0
  141. package/ui/styles/components/message-scroller.css +4 -0
  142. package/ui/styles/components/message.css +3 -0
  143. package/ui/styles/components/native-select.css +3 -0
  144. package/ui/styles/components/navigation-menu.css +3 -0
  145. package/ui/styles/components/pagination.css +4 -0
  146. package/ui/styles/components/popover.css +3 -0
  147. package/ui/styles/components/progress.css +3 -0
  148. package/ui/styles/components/questionnaire.css +4 -0
  149. package/ui/styles/components/radio-group.css +3 -0
  150. package/ui/styles/components/resizable.css +3 -0
  151. package/ui/styles/components/select.css +3 -0
  152. package/ui/styles/components/separator.css +3 -0
  153. package/ui/styles/components/sheet.css +4 -0
  154. package/ui/styles/components/sidebar.css +9 -0
  155. package/ui/styles/components/skeleton.css +3 -0
  156. package/ui/styles/components/slider.css +3 -0
  157. package/ui/styles/components/sonner.css +4 -0
  158. package/ui/styles/components/spinner.css +3 -0
  159. package/ui/styles/components/switch.css +3 -0
  160. package/ui/styles/components/table.css +3 -0
  161. package/ui/styles/components/tabs.css +4 -0
  162. package/ui/styles/components/textarea.css +3 -0
  163. package/ui/styles/components/toggle-group.css +4 -0
  164. package/ui/styles/components/toggle.css +3 -0
  165. package/ui/styles/components/tooltip.css +3 -0
  166. package/ui/styles/components/trace.css +3 -0
  167. package/ui/styles/components/typography.css +3 -0
  168. package/ui/styles/components/utils.css +2 -0
  169. package/ui/styles/core.css +137 -0
  170. package/ui/styles/palette.css +94 -0
  171. package/ui/styles/theme.css +14 -0
  172. package/ui/styles/transitions.css +131 -0
  173. package/base-cms/index.d.ts +0 -5
  174. package/base-cms/interfaces/base-cms-module-config.interface.d.ts +0 -16
  175. package/base-cms/pages/base-cms/base-cms.component.d.ts +0 -92
  176. package/base-cms/public-api.d.ts +0 -5
  177. package/base-components/components/breadcrumb/breadcrumb.component.d.ts +0 -10
  178. package/base-components/components/change-password/change-password.component.d.ts +0 -24
  179. package/base-components/components/checkbox/checkbox.component.d.ts +0 -12
  180. package/base-components/components/delete-account/delete-account.component.d.ts +0 -15
  181. package/base-components/components/fab-button/fab-button.component.d.ts +0 -16
  182. package/base-components/components/input/input.component.d.ts +0 -27
  183. package/base-components/components/loading-bar/loading-bar.component.d.ts +0 -17
  184. package/base-components/components/model-form/model-form-base.component.d.ts +0 -64
  185. package/base-components/components/model-form/model-form.component.d.ts +0 -139
  186. package/base-components/components/model-form-sub/model-form-sub.component.d.ts +0 -56
  187. package/base-components/components/model-table/model-table.component.d.ts +0 -115
  188. package/base-components/components/refence-input/refence-input.component.d.ts +0 -84
  189. package/base-components/components/select/select.component.d.ts +0 -25
  190. package/base-components/components/skeleton-loader/skeleton-loader.component.d.ts +0 -10
  191. package/base-components/components/tags/tags.component.d.ts +0 -60
  192. package/base-components/components/textarea/textarea.component.d.ts +0 -21
  193. package/base-components/components/toast/toast.component.d.ts +0 -19
  194. package/base-components/components/upload-image/upload-image.component.d.ts +0 -111
  195. package/base-components/directives/back-button.directive.d.ts +0 -9
  196. package/base-components/directives/context-menu.directive.d.ts +0 -22
  197. package/base-components/directives/sort.directive.d.ts +0 -15
  198. package/base-components/directives/stop-propagation.directive.d.ts +0 -10
  199. package/base-components/index.d.ts +0 -5
  200. package/base-components/pipes/ellipses.pipe.d.ts +0 -10
  201. package/base-components/public-api.d.ts +0 -26
  202. package/base-prototype/index.d.ts +0 -5
  203. package/base-prototype/pages/email-verification/email-verification.component.d.ts +0 -18
  204. package/base-prototype/pages/forgot-password/forgot-password.component.d.ts +0 -26
  205. package/base-prototype/pages/login/login.component.d.ts +0 -33
  206. package/base-prototype/pages/profile/profile.component.d.ts +0 -24
  207. package/base-prototype/pages/register/register.component.d.ts +0 -31
  208. package/base-prototype/pages/set-password/set-password.component.d.ts +0 -29
  209. package/base-prototype/public-api.d.ts +0 -9
  210. package/esm2022/base-cms/interfaces/base-cms-module-config.interface.mjs +0 -3
  211. package/esm2022/base-cms/lenne.tech-ng-base-base-cms.mjs +0 -5
  212. package/esm2022/base-cms/pages/base-cms/base-cms.component.mjs +0 -238
  213. package/esm2022/base-cms/public-api.mjs +0 -8
  214. package/esm2022/base-components/components/breadcrumb/breadcrumb.component.mjs +0 -23
  215. package/esm2022/base-components/components/change-password/change-password.component.mjs +0 -97
  216. package/esm2022/base-components/components/checkbox/checkbox.component.mjs +0 -38
  217. package/esm2022/base-components/components/delete-account/delete-account.component.mjs +0 -59
  218. package/esm2022/base-components/components/fab-button/fab-button.component.mjs +0 -24
  219. package/esm2022/base-components/components/input/input.component.mjs +0 -75
  220. package/esm2022/base-components/components/loading-bar/loading-bar.component.mjs +0 -37
  221. package/esm2022/base-components/components/model-form/model-form-base.component.mjs +0 -145
  222. package/esm2022/base-components/components/model-form/model-form.component.mjs +0 -591
  223. package/esm2022/base-components/components/model-form-sub/model-form-sub.component.mjs +0 -117
  224. package/esm2022/base-components/components/model-table/model-table.component.mjs +0 -478
  225. package/esm2022/base-components/components/refence-input/refence-input.component.mjs +0 -278
  226. package/esm2022/base-components/components/select/select.component.mjs +0 -62
  227. package/esm2022/base-components/components/skeleton-loader/skeleton-loader.component.mjs +0 -33
  228. package/esm2022/base-components/components/tags/tags.component.mjs +0 -227
  229. package/esm2022/base-components/components/textarea/textarea.component.mjs +0 -79
  230. package/esm2022/base-components/components/toast/toast.component.mjs +0 -69
  231. package/esm2022/base-components/components/upload-image/upload-image.component.mjs +0 -346
  232. package/esm2022/base-components/directives/back-button.directive.mjs +0 -25
  233. package/esm2022/base-components/directives/context-menu.directive.mjs +0 -112
  234. package/esm2022/base-components/directives/sort.directive.mjs +0 -61
  235. package/esm2022/base-components/directives/stop-propagation.directive.mjs +0 -24
  236. package/esm2022/base-components/lenne.tech-ng-base-base-components.mjs +0 -5
  237. package/esm2022/base-components/pipes/ellipses.pipe.mjs +0 -23
  238. package/esm2022/base-components/public-api.mjs +0 -30
  239. package/esm2022/base-prototype/lenne.tech-ng-base-base-prototype.mjs +0 -5
  240. package/esm2022/base-prototype/pages/email-verification/email-verification.component.mjs +0 -60
  241. package/esm2022/base-prototype/pages/forgot-password/forgot-password.component.mjs +0 -78
  242. package/esm2022/base-prototype/pages/login/login.component.mjs +0 -114
  243. package/esm2022/base-prototype/pages/profile/profile.component.mjs +0 -87
  244. package/esm2022/base-prototype/pages/register/register.component.mjs +0 -100
  245. package/esm2022/base-prototype/pages/set-password/set-password.component.mjs +0 -91
  246. package/esm2022/base-prototype/public-api.mjs +0 -11
  247. package/esm2022/lenne.tech-ng-base.mjs +0 -5
  248. package/esm2022/public-api.mjs +0 -25
  249. package/esm2022/shared/classes/auth.class.mjs +0 -14
  250. package/esm2022/shared/classes/basic-user.class.mjs +0 -49
  251. package/esm2022/shared/classes/graphql-enum.class.mjs +0 -10
  252. package/esm2022/shared/classes/graphql-meta.class.mjs +0 -345
  253. package/esm2022/shared/classes/graphql-type.class.mjs +0 -14
  254. package/esm2022/shared/classes/helper.class.mjs +0 -307
  255. package/esm2022/shared/classes/sort.class.mjs +0 -38
  256. package/esm2022/shared/classes/standard.class.mjs +0 -40
  257. package/esm2022/shared/decorators/debounce.decorator.mjs +0 -12
  258. package/esm2022/shared/enums/comparison-operator.enum.mjs +0 -16
  259. package/esm2022/shared/enums/graphql-request-type.enum.mjs +0 -10
  260. package/esm2022/shared/enums/logical-operator.enum.mjs +0 -10
  261. package/esm2022/shared/enums/skeleton-type.enum.mjs +0 -7
  262. package/esm2022/shared/enums/sort-order.enum.mjs +0 -6
  263. package/esm2022/shared/enums/toast-type.enum.mjs +0 -8
  264. package/esm2022/shared/functions/ws-client.function.mjs +0 -39
  265. package/esm2022/shared/interfaces/base-module-config.interface.mjs +0 -3
  266. package/esm2022/shared/interfaces/breadcrumb.interface.mjs +0 -2
  267. package/esm2022/shared/interfaces/can-component-deactivate.interface.mjs +0 -2
  268. package/esm2022/shared/interfaces/cms-enum-values.interface.mjs +0 -2
  269. package/esm2022/shared/interfaces/cms-field-config.interface.mjs +0 -2
  270. package/esm2022/shared/interfaces/cms-model-config.interface.mjs +0 -2
  271. package/esm2022/shared/interfaces/cms-table-field.interface.mjs +0 -2
  272. package/esm2022/shared/interfaces/combined-filter-input.interface.mjs +0 -2
  273. package/esm2022/shared/interfaces/compress-options.interface.mjs +0 -2
  274. package/esm2022/shared/interfaces/cropping-options.interface.mjs +0 -2
  275. package/esm2022/shared/interfaces/field-object.interface.mjs +0 -2
  276. package/esm2022/shared/interfaces/field.interface.mjs +0 -2
  277. package/esm2022/shared/interfaces/filter-input.interface.mjs +0 -2
  278. package/esm2022/shared/interfaces/find-args.interface.mjs +0 -2
  279. package/esm2022/shared/interfaces/graphql-crud-type.interface.mjs +0 -2
  280. package/esm2022/shared/interfaces/graphql-fields-object.interface.mjs +0 -2
  281. package/esm2022/shared/interfaces/graphql-options.interface.mjs +0 -2
  282. package/esm2022/shared/interfaces/graphql-plus-options.interfacen.mjs +0 -2
  283. package/esm2022/shared/interfaces/graphql-type-collection.interface.mjs +0 -2
  284. package/esm2022/shared/interfaces/login-config.interface.mjs +0 -2
  285. package/esm2022/shared/interfaces/register-config.interface.mjs +0 -2
  286. package/esm2022/shared/interfaces/single-filter-input.interface.mjs +0 -2
  287. package/esm2022/shared/interfaces/sort-input.interface.mjs +0 -2
  288. package/esm2022/shared/interfaces/time-components.interface.mjs +0 -2
  289. package/esm2022/shared/interfaces/toast.interface.mjs +0 -2
  290. package/esm2022/shared/lenne.tech-ng-base-shared.mjs +0 -5
  291. package/esm2022/shared/public-api.mjs +0 -74
  292. package/esm2022/shared/services/auth.service.mjs +0 -152
  293. package/esm2022/shared/services/breadcrumb.service.mjs +0 -69
  294. package/esm2022/shared/services/cms.service.mjs +0 -82
  295. package/esm2022/shared/services/file.service.mjs +0 -86
  296. package/esm2022/shared/services/forms.service.mjs +0 -61
  297. package/esm2022/shared/services/graphql-meta.service.mjs +0 -132
  298. package/esm2022/shared/services/graphql-plus.service.mjs +0 -93
  299. package/esm2022/shared/services/graphql.service.mjs +0 -510
  300. package/esm2022/shared/services/image.service.mjs +0 -102
  301. package/esm2022/shared/services/loader.service.mjs +0 -78
  302. package/esm2022/shared/services/navigation.service.mjs +0 -38
  303. package/esm2022/shared/services/scroll.service.mjs +0 -207
  304. package/esm2022/shared/services/storage.service.mjs +0 -149
  305. package/esm2022/shared/services/toast.service.mjs +0 -39
  306. package/esm2022/shared/services/user.service.mjs +0 -160
  307. package/esm2022/shared/services/ws.service.mjs +0 -17
  308. package/esm2022/shared/types/graphql-fields.type.mjs +0 -2
  309. package/esm2022/shared/types/storage.type.mjs +0 -2
  310. package/esm2022/shared/validators/email.validator.mjs +0 -7
  311. package/esm2022/shared/validators/match.validator.mjs +0 -22
  312. package/esm2022/shared/validators/secure-password.validator.mjs +0 -7
  313. package/esm2022/src/base.module.mjs +0 -64
  314. package/esm2022/src/decorators/auto-unsubscribe.decorator.mjs +0 -23
  315. package/esm2022/src/directives/lazy-load.directive.mjs +0 -48
  316. package/esm2022/src/directives/match-height.directive.mjs +0 -92
  317. package/esm2022/src/directives/resizable.directive.mjs +0 -92
  318. package/esm2022/src/factories/apollo-options.factory.mjs +0 -108
  319. package/esm2022/src/functions/extract-files.function.mjs +0 -87
  320. package/esm2022/src/guards/auth.guard.mjs +0 -91
  321. package/esm2022/src/guards/can-deactivate.guard.mjs +0 -16
  322. package/esm2022/src/guards/logout.guard.mjs +0 -34
  323. package/esm2022/src/pipes/date-ago.pipe.mjs +0 -64
  324. package/esm2022/src/pipes/safe-html.pipe.mjs +0 -22
  325. package/esm2022/src/services/fullscreen.service.mjs +0 -51
  326. package/esm2022/src/services/seo.service.mjs +0 -109
  327. package/esm2022/src/services/theme.service.mjs +0 -44
  328. package/fesm2022/lenne.tech-ng-base-base-cms.mjs +0 -251
  329. package/fesm2022/lenne.tech-ng-base-base-cms.mjs.map +0 -1
  330. package/fesm2022/lenne.tech-ng-base-base-components.mjs +0 -2917
  331. package/fesm2022/lenne.tech-ng-base-base-components.mjs.map +0 -1
  332. package/fesm2022/lenne.tech-ng-base-base-prototype.mjs +0 -505
  333. package/fesm2022/lenne.tech-ng-base-base-prototype.mjs.map +0 -1
  334. package/fesm2022/lenne.tech-ng-base-shared.mjs +0 -2863
  335. package/fesm2022/lenne.tech-ng-base-shared.mjs.map +0 -1
  336. package/index.d.ts +0 -5
  337. package/public-api.d.ts +0 -17
  338. package/shared/classes/auth.class.d.ts +0 -10
  339. package/shared/classes/basic-user.class.d.ts +0 -27
  340. package/shared/classes/graphql-enum.class.d.ts +0 -7
  341. package/shared/classes/graphql-meta.class.d.ts +0 -66
  342. package/shared/classes/graphql-type.class.d.ts +0 -13
  343. package/shared/classes/helper.class.d.ts +0 -99
  344. package/shared/classes/sort.class.d.ts +0 -12
  345. package/shared/classes/standard.class.d.ts +0 -32
  346. package/shared/decorators/debounce.decorator.d.ts +0 -1
  347. package/shared/enums/comparison-operator.enum.d.ts +0 -14
  348. package/shared/enums/graphql-request-type.enum.d.ts +0 -8
  349. package/shared/enums/logical-operator.enum.d.ts +0 -8
  350. package/shared/enums/skeleton-type.enum.d.ts +0 -5
  351. package/shared/enums/sort-order.enum.d.ts +0 -4
  352. package/shared/enums/toast-type.enum.d.ts +0 -6
  353. package/shared/functions/ws-client.function.d.ts +0 -5
  354. package/shared/index.d.ts +0 -5
  355. package/shared/interfaces/base-module-config.interface.d.ts +0 -61
  356. package/shared/interfaces/breadcrumb.interface.d.ts +0 -4
  357. package/shared/interfaces/can-component-deactivate.interface.d.ts +0 -7
  358. package/shared/interfaces/cms-enum-values.interface.d.ts +0 -4
  359. package/shared/interfaces/cms-field-config.interface.d.ts +0 -45
  360. package/shared/interfaces/cms-model-config.interface.d.ts +0 -14
  361. package/shared/interfaces/cms-table-field.interface.d.ts +0 -10
  362. package/shared/interfaces/combined-filter-input.interface.d.ts +0 -9
  363. package/shared/interfaces/compress-options.interface.d.ts +0 -15
  364. package/shared/interfaces/cropping-options.interface.d.ts +0 -12
  365. package/shared/interfaces/field-object.interface.d.ts +0 -6
  366. package/shared/interfaces/field.interface.d.ts +0 -5
  367. package/shared/interfaces/filter-input.interface.d.ts +0 -9
  368. package/shared/interfaces/find-args.interface.d.ts +0 -11
  369. package/shared/interfaces/graphql-crud-type.interface.d.ts +0 -7
  370. package/shared/interfaces/graphql-fields-object.interface.d.ts +0 -6
  371. package/shared/interfaces/graphql-options.interface.d.ts +0 -11
  372. package/shared/interfaces/graphql-plus-options.interfacen.d.ts +0 -9
  373. package/shared/interfaces/graphql-type-collection.interface.d.ts +0 -7
  374. package/shared/interfaces/login-config.interface.d.ts +0 -6
  375. package/shared/interfaces/register-config.interface.d.ts +0 -4
  376. package/shared/interfaces/single-filter-input.interface.d.ts +0 -11
  377. package/shared/interfaces/sort-input.interface.d.ts +0 -5
  378. package/shared/interfaces/time-components.interface.d.ts +0 -6
  379. package/shared/interfaces/toast.interface.d.ts +0 -8
  380. package/shared/public-api.d.ts +0 -65
  381. package/shared/services/auth.service.d.ts +0 -44
  382. package/shared/services/breadcrumb.service.d.ts +0 -32
  383. package/shared/services/cms.service.d.ts +0 -27
  384. package/shared/services/file.service.d.ts +0 -22
  385. package/shared/services/forms.service.d.ts +0 -14
  386. package/shared/services/graphql-meta.service.d.ts +0 -45
  387. package/shared/services/graphql-plus.service.d.ts +0 -27
  388. package/shared/services/graphql.service.d.ts +0 -71
  389. package/shared/services/image.service.d.ts +0 -27
  390. package/shared/services/loader.service.d.ts +0 -32
  391. package/shared/services/navigation.service.d.ts +0 -15
  392. package/shared/services/scroll.service.d.ts +0 -85
  393. package/shared/services/storage.service.d.ts +0 -49
  394. package/shared/services/toast.service.d.ts +0 -15
  395. package/shared/services/user.service.d.ts +0 -77
  396. package/shared/services/ws.service.d.ts +0 -8
  397. package/shared/types/graphql-fields.type.d.ts +0 -5
  398. package/shared/types/storage.type.d.ts +0 -4
  399. package/shared/validators/email.validator.d.ts +0 -1
  400. package/shared/validators/match.validator.d.ts +0 -4
  401. package/shared/validators/secure-password.validator.d.ts +0 -1
  402. package/src/base.module.d.ts +0 -16
  403. package/src/decorators/auto-unsubscribe.decorator.d.ts +0 -5
  404. package/src/directives/lazy-load.directive.d.ts +0 -17
  405. package/src/directives/match-height.directive.d.ts +0 -20
  406. package/src/directives/resizable.directive.d.ts +0 -26
  407. package/src/factories/apollo-options.factory.d.ts +0 -16
  408. package/src/functions/extract-files.function.d.ts +0 -15
  409. package/src/guards/auth.guard.d.ts +0 -27
  410. package/src/guards/can-deactivate.guard.d.ts +0 -10
  411. package/src/guards/logout.guard.d.ts +0 -16
  412. package/src/pipes/date-ago.pipe.d.ts +0 -34
  413. package/src/pipes/safe-html.pipe.d.ts +0 -13
  414. package/src/services/fullscreen.service.d.ts +0 -18
  415. package/src/services/seo.service.d.ts +0 -50
  416. package/src/services/theme.service.d.ts +0 -17
@@ -0,0 +1,454 @@
1
+ import { LT_AUTH_OPTIONS, LtAuthStore, readLtAuthAnswer } from "@lenne.tech/ng-base/auth/provide";
2
+ import { LtApiUrlService, LtI18nService, ltArrayBufferToBase64Url, ltBase64UrlToUint8Array, ltSha256 } from "@lenne.tech/ng-base";
3
+ import * as i0 from "@angular/core";
4
+ import { Service, inject } from "@angular/core";
5
+ export * from "@lenne.tech/ng-base/auth/provide";
6
+ const pluginRegistry = [];
7
+ function registerLtAuthPlugins(plugins) {
8
+ pluginRegistry.push(...plugins);
9
+ }
10
+ function getLtAuthPluginRegistry() {
11
+ return [...pluginRegistry];
12
+ }
13
+ function clearLtAuthPluginRegistry() {
14
+ pluginRegistry.length = 0;
15
+ }
16
+ function resolveLtAuthClientBase(resolution, basePath) {
17
+ const trimmed = (basePath || "/iam").replace(/\/+$/, "");
18
+ const path = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
19
+ if (resolution.proxy) return {
20
+ basePath: path === "/api" || path.startsWith("/api/") ? path : `/api${path}`,
21
+ baseURL: ""
22
+ };
23
+ return {
24
+ basePath: path,
25
+ baseURL: resolution.baseUrl
26
+ };
27
+ }
28
+ function resolveLtAuthClientUrl(baseURL, basePath) {
29
+ const path = basePath ? basePath.startsWith("/") ? basePath : `/${basePath}` : "";
30
+ if (baseURL) return `${baseURL.replace(/\/+$/, "")}${path}`;
31
+ const origin = typeof location !== "undefined" ? location.origin : "";
32
+ return origin && origin !== "null" ? `${origin}${path}` : path;
33
+ }
34
+ function loadBetterAuth() {
35
+ return Promise.all([import("better-auth/client"), import("better-auth/client/plugins")]);
36
+ }
37
+ async function createLtAuthClient(config) {
38
+ const [{ createAuthClient }, { adminClient, twoFactorClient }] = await loadBetterAuth();
39
+ const plugins = [];
40
+ if (config.enableTwoFactor !== false) plugins.push(twoFactorClient({ onTwoFactorRedirect: () => config.onTwoFactorRedirect?.() }));
41
+ if (config.enableAdmin) plugins.push(adminClient());
42
+ plugins.push(...config.plugins ?? [], ...pluginRegistry);
43
+ const fetchImpl = config.fetch;
44
+ const raw = createAuthClient({
45
+ baseURL: resolveLtAuthClientUrl(config.baseURL, config.basePath),
46
+ fetchOptions: {
47
+ credentials: "include",
48
+ ...fetchImpl ? { customFetchImpl: (input, init) => fetchImpl(input, init) } : {}
49
+ },
50
+ plugins
51
+ });
52
+ const client = raw;
53
+ const call = (path, args) => {
54
+ let target = client;
55
+ for (const key of path) target = target[key];
56
+ return target(...args);
57
+ };
58
+ const hashed = async (params, fields, method) => {
59
+ const result = { ...params };
60
+ for (const field of fields) {
61
+ const value = params[field];
62
+ if (typeof value !== "string" || !value) throw new Error(`[@lenne.tech/ng-base] ${method}: "${field}" is required`);
63
+ result[field] = await ltSha256(value);
64
+ }
65
+ return result;
66
+ };
67
+ const withOptions = (options) => options ? [{ fetchOptions: options }] : [];
68
+ return {
69
+ raw,
70
+ changePassword: async (params, options) => call(["changePassword"], [await hashed(params, ["currentPassword", "newPassword"], "changePassword"), ...withOptions(options)]),
71
+ getSession: (options) => call(["getSession"], options ? [{ fetchOptions: options }] : []),
72
+ passkey: {
73
+ deletePasskey: (params, options) => call(["$fetch"], ["/passkey/delete-passkey", {
74
+ body: params,
75
+ method: "POST",
76
+ ...options
77
+ }]),
78
+ listUserPasskeys: (options) => call(["$fetch"], ["/passkey/list-user-passkeys", {
79
+ method: "GET",
80
+ ...options
81
+ }]),
82
+ updatePasskey: (params, options) => call(["$fetch"], ["/passkey/update-passkey", {
83
+ body: params,
84
+ method: "POST",
85
+ ...options
86
+ }])
87
+ },
88
+ requestPasswordReset: (params, options) => call(["requestPasswordReset"], [params, ...withOptions(options)]),
89
+ resetPassword: async (params, options) => call(["resetPassword"], [await hashed(params, ["newPassword"], "resetPassword"), ...withOptions(options)]),
90
+ sendVerificationEmail: (params, options) => call(["sendVerificationEmail"], [params, ...withOptions(options)]),
91
+ signIn: { email: async (params, options) => call(["signIn", "email"], [await hashed(params, ["password"], "signIn.email"), ...withOptions(options)]) },
92
+ signOut: (options) => call(["signOut"], options ? [{ fetchOptions: options }] : []),
93
+ signUp: { email: async (params, options) => call(["signUp", "email"], [await hashed(params, ["password"], "signUp.email"), ...withOptions(options)]) },
94
+ twoFactor: {
95
+ disable: async (params, options) => call(["twoFactor", "disable"], [await hashed(params, ["password"], "twoFactor.disable"), ...withOptions(options)]),
96
+ enable: async (params, options) => call(["twoFactor", "enable"], [await hashed(params, ["password"], "twoFactor.enable"), ...withOptions(options)]),
97
+ generateBackupCodes: async (params, options) => call(["twoFactor", "generateBackupCodes"], [await hashed(params, ["password"], "twoFactor.generateBackupCodes"), ...withOptions(options)]),
98
+ verifyBackupCode: (params, options) => call(["twoFactor", "verifyBackupCode"], [params, ...withOptions(options)]),
99
+ verifyTotp: (params, options) => call(["twoFactor", "verifyTotp"], [params, ...withOptions(options)])
100
+ },
101
+ verifyEmail: (params, options) => call(["verifyEmail"], [{ query: params }, ...withOptions(options)])
102
+ };
103
+ }
104
+ const LT_AUTH_MESSAGES = {
105
+ de: { lt: { "auth": {
106
+ "loggingOut": "Abmelden...",
107
+ "noPasskeySelected": "Kein Passkey ausgewählt",
108
+ "passkeyAborted": "Passkey-Authentifizierung wurde abgebrochen",
109
+ "passkeyAlreadyRegistered": "Du hast bereits einen Passkey für diese Website registriert. Lösche ihn zuerst oder verwende einen anderen Authenticator.",
110
+ "passkeyCreationAborted": "Passkey-Erstellung wurde abgebrochen",
111
+ "passkeyError": "Konnte Passkey-Optionen nicht laden",
112
+ "passkeyFailed": "Passkey-Anmeldung fehlgeschlagen",
113
+ "passkeyRegisterFailed": "Passkey-Registrierung fehlgeschlagen",
114
+ "passkeyUnsupported": "Passkeys werden in diesem Browser nicht unterstützt",
115
+ "registerOptionsError": "Konnte Registrierungsoptionen nicht laden",
116
+ "sessionExpired": "Sitzung abgelaufen"
117
+ } } },
118
+ en: { lt: { "auth": {
119
+ "loggingOut": "Logging out...",
120
+ "noPasskeySelected": "No passkey selected",
121
+ "passkeyAborted": "Passkey authentication was cancelled",
122
+ "passkeyAlreadyRegistered": "You already registered a passkey for this website. Delete it first or use another authenticator.",
123
+ "passkeyCreationAborted": "Passkey creation was cancelled",
124
+ "passkeyError": "Could not load passkey options",
125
+ "passkeyFailed": "Passkey login failed",
126
+ "passkeyRegisterFailed": "Passkey registration failed",
127
+ "passkeyUnsupported": "Passkeys are not supported in this browser",
128
+ "registerOptionsError": "Could not load registration options",
129
+ "sessionExpired": "Session expired"
130
+ } } }
131
+ };
132
+ function injectLtAuthI18n() {
133
+ const i18n = inject(LtI18nService);
134
+ i18n.registerLibraryMessages("auth", LT_AUTH_MESSAGES);
135
+ return i18n;
136
+ }
137
+ var LtAuthService = class LtAuthService {
138
+ store = inject(LtAuthStore);
139
+ api = inject(LtApiUrlService);
140
+ options = inject(LT_AUTH_OPTIONS);
141
+ i18n = injectLtAuthI18n();
142
+ clientRequest = null;
143
+ user = this.store.user;
144
+ isAuthenticated = this.store.isAuthenticated;
145
+ authMode = this.store.authMode;
146
+ isJwtMode = this.store.isJwtMode;
147
+ isLoading = this.store.isLoading;
148
+ isAdmin = this.store.isAdmin;
149
+ is2FAEnabled = this.store.is2FAEnabled;
150
+ features = this.store.features;
151
+ passkeySupported = this.store.passkeySupported;
152
+ getClient() {
153
+ if (!this.clientRequest) {
154
+ this.clientRequest = createLtAuthClient({
155
+ ...resolveLtAuthClientBase(this.api.resolve(), this.options.basePath),
156
+ enableAdmin: this.options.enableAdmin,
157
+ enableTwoFactor: this.options.enableTwoFactor,
158
+ fetch: (input, init) => this.store.fetchWithAuth(input, init),
159
+ plugins: this.options.plugins
160
+ });
161
+ this.clientRequest.catch(() => {
162
+ this.clientRequest = null;
163
+ });
164
+ }
165
+ return this.clientRequest;
166
+ }
167
+ jwtToken() {
168
+ return this.store.jwtToken();
169
+ }
170
+ hasRole(role) {
171
+ return this.store.hasRole(role);
172
+ }
173
+ hasAnyRole(...roles) {
174
+ return this.store.hasAnyRole(...roles);
175
+ }
176
+ fetchFeatures() {
177
+ return this.store.fetchFeatures();
178
+ }
179
+ ensureFeatures() {
180
+ return this.store.ensureFeatures();
181
+ }
182
+ signIn = {
183
+ email: async (params, options) => this.store.withLoading(async () => {
184
+ const result = await (await this.getClient()).signIn.email(params, options);
185
+ if (readLtAuthAnswer(result).twoFactor) this.store.navigateKeepingRedirect(this.options.twoFactorRedirectPath);
186
+ else this.store.applyAuthResult(result);
187
+ return result;
188
+ }),
189
+ passkey: () => this.authenticateWithPasskey()
190
+ };
191
+ signUp = { email: async (params, options) => this.store.withLoading(async () => {
192
+ const result = await (await this.getClient()).signUp.email(params, options);
193
+ this.store.applyAuthResult(result);
194
+ return result;
195
+ }) };
196
+ signOut(options) {
197
+ return this.store.signOut(options);
198
+ }
199
+ setUser(user, mode = "cookie") {
200
+ this.store.setUser(user, mode);
201
+ }
202
+ clearUser() {
203
+ this.store.clearUser();
204
+ }
205
+ validateSession() {
206
+ return this.store.validateSession();
207
+ }
208
+ fetchWithAuth(input, init = {}) {
209
+ return this.store.fetchWithAuth(input, init);
210
+ }
211
+ recoverFrom401(url, sentToken) {
212
+ return this.store.recoverFrom401(url, sentToken);
213
+ }
214
+ handleUnauthorized(url) {
215
+ return this.store.handleUnauthorized(url);
216
+ }
217
+ switchToJwtMode() {
218
+ return this.store.switchToJwtMode();
219
+ }
220
+ refreshJwtToken() {
221
+ return this.store.refreshJwtToken();
222
+ }
223
+ async authenticateWithPasskey() {
224
+ if (!hasWebAuthn()) return {
225
+ error: this.i18n.t("lt.auth.passkeyUnsupported"),
226
+ success: false
227
+ };
228
+ return this.store.withLoading(async () => {
229
+ try {
230
+ const optionsResponse = await this.store.fetchWithAuth(this.store.authUrl("/passkey/generate-authenticate-options"), { method: "GET" });
231
+ if (!optionsResponse.ok) return {
232
+ error: this.i18n.t("lt.auth.passkeyError"),
233
+ success: false
234
+ };
235
+ const options = await optionsResponse.json();
236
+ const credential = await navigator.credentials.get({ publicKey: {
237
+ allowCredentials: (options.allowCredentials ?? []).map((descriptor) => ({
238
+ ...descriptor,
239
+ id: typeof descriptor.id === "string" ? ltBase64UrlToUint8Array(descriptor.id).buffer : descriptor.id
240
+ })),
241
+ challenge: ltBase64UrlToUint8Array(options.challenge).buffer,
242
+ rpId: options.rpId,
243
+ timeout: options.timeout,
244
+ userVerification: options.userVerification
245
+ } });
246
+ if (!credential) return {
247
+ error: this.i18n.t("lt.auth.noPasskeySelected"),
248
+ success: false
249
+ };
250
+ const assertion = credential.response;
251
+ const authResponse = await this.store.fetchWithAuth(this.store.authUrl("/passkey/verify-authentication"), {
252
+ body: JSON.stringify({
253
+ challengeId: options.challengeId,
254
+ response: {
255
+ clientExtensionResults: credential.getClientExtensionResults?.() ?? {},
256
+ id: credential.id,
257
+ rawId: ltArrayBufferToBase64Url(credential.rawId),
258
+ response: {
259
+ authenticatorData: ltArrayBufferToBase64Url(assertion.authenticatorData),
260
+ clientDataJSON: ltArrayBufferToBase64Url(assertion.clientDataJSON),
261
+ signature: ltArrayBufferToBase64Url(assertion.signature),
262
+ userHandle: assertion.userHandle ? ltArrayBufferToBase64Url(assertion.userHandle) : null
263
+ },
264
+ type: credential.type
265
+ }
266
+ }),
267
+ headers: { "Content-Type": "application/json" },
268
+ method: "POST"
269
+ });
270
+ const result = await authResponse.json().catch(() => ({})) ?? {};
271
+ if (!authResponse.ok) return {
272
+ error: result.message || this.i18n.t("lt.auth.passkeyFailed"),
273
+ success: false
274
+ };
275
+ const user = await this.store.adoptVerifiedSession(result);
276
+ if (!user) return {
277
+ error: this.i18n.t("lt.auth.passkeyFailed"),
278
+ success: false
279
+ };
280
+ return {
281
+ session: result.session,
282
+ success: true,
283
+ user
284
+ };
285
+ } catch (error) {
286
+ if (error instanceof Error && error.name === "NotAllowedError") return {
287
+ error: this.i18n.t("lt.auth.passkeyAborted"),
288
+ success: false
289
+ };
290
+ return {
291
+ error: error instanceof Error && error.message ? error.message : this.i18n.t("lt.auth.passkeyFailed"),
292
+ success: false
293
+ };
294
+ }
295
+ });
296
+ }
297
+ async registerPasskey(name) {
298
+ if (!hasWebAuthn()) return {
299
+ error: this.i18n.t("lt.auth.passkeyUnsupported"),
300
+ success: false
301
+ };
302
+ return this.store.withLoading(async () => {
303
+ try {
304
+ const optionsResponse = await this.store.fetchWithAuth(this.store.authUrl("/passkey/generate-register-options"), { method: "GET" });
305
+ if (!optionsResponse.ok) return {
306
+ error: (await optionsResponse.json().catch(() => ({})))?.message || this.i18n.t("lt.auth.registerOptionsError"),
307
+ success: false
308
+ };
309
+ const options = await optionsResponse.json();
310
+ const credential = await navigator.credentials.create({ publicKey: {
311
+ attestation: options.attestation,
312
+ authenticatorSelection: options.authenticatorSelection,
313
+ challenge: ltBase64UrlToUint8Array(options.challenge).buffer,
314
+ excludeCredentials: (options.excludeCredentials ?? []).map((descriptor) => ({
315
+ ...descriptor,
316
+ id: ltBase64UrlToUint8Array(descriptor.id).buffer
317
+ })),
318
+ pubKeyCredParams: options.pubKeyCredParams,
319
+ rp: options.rp,
320
+ timeout: options.timeout,
321
+ user: {
322
+ ...options.user,
323
+ id: ltBase64UrlToUint8Array(options.user.id).buffer
324
+ }
325
+ } });
326
+ if (!credential) return {
327
+ error: this.i18n.t("lt.auth.passkeyCreationAborted"),
328
+ success: false
329
+ };
330
+ const attestation = credential.response;
331
+ const registerResponse = await this.store.fetchWithAuth(this.store.authUrl("/passkey/verify-registration"), {
332
+ body: JSON.stringify({
333
+ challengeId: options.challengeId,
334
+ name,
335
+ response: {
336
+ clientExtensionResults: credential.getClientExtensionResults?.() ?? {},
337
+ id: credential.id,
338
+ rawId: ltArrayBufferToBase64Url(credential.rawId),
339
+ response: {
340
+ attestationObject: ltArrayBufferToBase64Url(attestation.attestationObject),
341
+ clientDataJSON: ltArrayBufferToBase64Url(attestation.clientDataJSON),
342
+ transports: attestation.getTransports?.() ?? []
343
+ },
344
+ type: credential.type
345
+ }
346
+ }),
347
+ headers: { "Content-Type": "application/json" },
348
+ method: "POST"
349
+ });
350
+ const result = await registerResponse.json().catch(() => ({}));
351
+ if (!registerResponse.ok) return {
352
+ error: result?.message || this.i18n.t("lt.auth.passkeyRegisterFailed"),
353
+ success: false
354
+ };
355
+ return {
356
+ passkey: result,
357
+ success: true
358
+ };
359
+ } catch (error) {
360
+ if (error instanceof Error) {
361
+ if (error.name === "NotAllowedError") return {
362
+ error: this.i18n.t("lt.auth.passkeyCreationAborted"),
363
+ success: false
364
+ };
365
+ if (error.name === "InvalidStateError" || error.message.includes("already registered")) return {
366
+ error: this.i18n.t("lt.auth.passkeyAlreadyRegistered"),
367
+ success: false
368
+ };
369
+ return {
370
+ error: error.message || this.i18n.t("lt.auth.passkeyRegisterFailed"),
371
+ success: false
372
+ };
373
+ }
374
+ return {
375
+ error: this.i18n.t("lt.auth.passkeyRegisterFailed"),
376
+ success: false
377
+ };
378
+ }
379
+ });
380
+ }
381
+ passkey = {
382
+ delete: async (id) => (await this.getClient()).passkey.deletePasskey({ id }),
383
+ list: async () => (await this.getClient()).passkey.listUserPasskeys(),
384
+ update: async (id, name) => (await this.getClient()).passkey.updatePasskey({
385
+ id,
386
+ name
387
+ })
388
+ };
389
+ twoFactor = {
390
+ disable: async (params) => (await this.getClient()).twoFactor.disable(params),
391
+ enable: async (params) => (await this.getClient()).twoFactor.enable(params),
392
+ generateBackupCodes: async (params) => (await this.getClient()).twoFactor.generateBackupCodes(params),
393
+ verifyBackupCode: async (params) => this.adoptVerifiedSession(await (await this.getClient()).twoFactor.verifyBackupCode(params)),
394
+ verifyTotp: async (params) => this.adoptVerifiedSession(await (await this.getClient()).twoFactor.verifyTotp(params))
395
+ };
396
+ async changePassword(params) {
397
+ return (await this.getClient()).changePassword(params);
398
+ }
399
+ async requestPasswordReset(params) {
400
+ const redirectTo = params.redirectTo || this.absoluteAppUrl("/auth/reset-password");
401
+ return (await this.getClient()).requestPasswordReset({
402
+ ...params,
403
+ redirectTo
404
+ });
405
+ }
406
+ async resetPassword(params) {
407
+ return (await this.getClient()).resetPassword(params);
408
+ }
409
+ async sendVerificationEmail(params) {
410
+ const callbackURL = params.callbackURL || this.absoluteAppUrl("/auth/login");
411
+ return (await this.getClient()).sendVerificationEmail({
412
+ ...params,
413
+ callbackURL
414
+ });
415
+ }
416
+ async verifyEmail(params) {
417
+ return (await this.getClient()).verifyEmail(params);
418
+ }
419
+ absoluteAppUrl(path) {
420
+ return this.store.absoluteAppUrl(path);
421
+ }
422
+ async adoptVerifiedSession(result) {
423
+ if (!result || result.error || !result.data) return result;
424
+ await this.store.adoptVerifiedSession(result);
425
+ return result;
426
+ }
427
+ static ɵfac = i0.ɵɵngDeclareFactory({
428
+ minVersion: "12.0.0",
429
+ version: "22.2.4",
430
+ ngImport: i0,
431
+ type: LtAuthService,
432
+ deps: [],
433
+ target: i0.ɵɵFactoryTarget.Service
434
+ });
435
+ static ɵprov = i0.ɵɵngDeclareService({
436
+ minVersion: "22.0.0",
437
+ version: "22.2.4",
438
+ ngImport: i0,
439
+ type: LtAuthService
440
+ });
441
+ };
442
+ i0.ɵɵngDeclareClassMetadata({
443
+ minVersion: "12.0.0",
444
+ version: "22.2.4",
445
+ ngImport: i0,
446
+ type: LtAuthService,
447
+ decorators: [{ type: Service }]
448
+ });
449
+ function hasWebAuthn() {
450
+ return typeof navigator !== "undefined" && !!navigator.credentials;
451
+ }
452
+ export { LtAuthService, clearLtAuthPluginRegistry, createLtAuthClient, getLtAuthPluginRegistry, registerLtAuthPlugins, resolveLtAuthClientBase, resolveLtAuthClientUrl };
453
+
454
+ //# sourceMappingURL=lenne.tech-ng-base-auth.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lenne.tech-ng-base-auth.mjs","names":[],"sources":["../../../projects/ng-base/auth/src/lib/auth-client.ts","../tmp-esm2022/auth/lib/i18n/de.json","../tmp-esm2022/auth/lib/i18n/en.json","../../../projects/ng-base/auth/src/lib/i18n.ts","../../../projects/ng-base/auth/src/lib/auth-service.ts"],"sourcesContent":["import type { createAuthClient } from 'better-auth/client';\nimport { ltSha256, type LtApiUrlResolution, type LtFetch } from '@lenne.tech/ng-base';\n\nimport type { LtAuthCallOptions, LtAuthResponse, LtNoStrayCredential, LtPasskey, LtTwoFactorEnableResult, LtUser } from '@lenne.tech/ng-base/auth/provide';\n\n/** Configuration of {@link createLtAuthClient}. */\nexport interface LtAuthClientConfig {\n /** API origin (`''` for same-origin / proxy). */\n baseURL: string;\n /** Better Auth base path, e.g. `/iam` or `/api/iam` behind the dev proxy. */\n basePath: string;\n /** Register `adminClient()` (default `false`, see `LtAuthOptions.enableAdmin`). */\n enableAdmin?: boolean;\n /** Register `twoFactorClient()` (default `true`). */\n enableTwoFactor?: boolean;\n /** Fetch implementation (the auth-aware `LT_FETCH`). */\n fetch?: LtFetch;\n /** Called when a sign-in answers `twoFactorRedirect` (navigate to the 2FA page). */\n onTwoFactorRedirect?: () => void | Promise<void>;\n /** Additional Better Auth client plugins (e.g. `passkeyClient()` from `@better-auth/passkey/client`). */\n plugins?: unknown[];\n}\n\n/**\n * The Better Auth client surface ng-base exposes. Every method that sends a credential hashes it with SHA-256 first\n * (`{ ...params, field: sha256(field) }`, never a whitelist), so a plaintext password never leaves the browser.\n */\nexport interface LtAuthClient {\n /** The underlying Better Auth client (escape hatch; its methods do NOT hash). */\n readonly raw: ReturnType<typeof createAuthClient>;\n changePassword<T extends { currentPassword: string; newPassword: string; revokeOtherSessions?: boolean }>(\n params: LtNoStrayCredential<T, 'currentPassword' | 'newPassword'>,\n options?: LtAuthCallOptions,\n ): Promise<LtAuthResponse>;\n getSession(options?: LtAuthCallOptions): Promise<LtAuthResponse<{ session: Record<string, unknown>; user: LtUser } | null>>;\n passkey: {\n deletePasskey(params: { id: string }, options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n listUserPasskeys(options?: LtAuthCallOptions): Promise<LtAuthResponse<LtPasskey[]>>;\n updatePasskey(params: { id: string; name: string }, options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n };\n requestPasswordReset<T extends { email: string; redirectTo?: string }>(params: LtNoStrayCredential<T, never>, options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n resetPassword<T extends { newPassword: string; token: string }>(params: LtNoStrayCredential<T, 'newPassword'>, options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n sendVerificationEmail<T extends { callbackURL?: string; email: string }>(params: LtNoStrayCredential<T, never>, options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n signIn: {\n email<T extends { callbackURL?: string; email: string; password: string; rememberMe?: boolean }>(\n params: LtNoStrayCredential<T, 'password'>,\n options?: LtAuthCallOptions,\n ): Promise<LtAuthResponse>;\n };\n signOut(options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n signUp: {\n email<T extends { callbackURL?: string; email: string; name: string; password: string }>(\n params: LtNoStrayCredential<T, 'password'>,\n options?: LtAuthCallOptions,\n ): Promise<LtAuthResponse>;\n };\n twoFactor: {\n disable<T extends { password: string }>(params: LtNoStrayCredential<T, 'password'>, options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n enable<T extends { issuer?: string; password: string }>(\n params: LtNoStrayCredential<T, 'password'>,\n options?: LtAuthCallOptions,\n ): Promise<LtAuthResponse<LtTwoFactorEnableResult>>;\n generateBackupCodes<T extends { password: string }>(\n params: LtNoStrayCredential<T, 'password'>,\n options?: LtAuthCallOptions,\n ): Promise<LtAuthResponse<{ backupCodes: string[] }>>;\n verifyBackupCode(params: { code: string; disableSession?: boolean; trustDevice?: boolean }, options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n verifyTotp(params: { code: string; trustDevice?: boolean }, options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n };\n verifyEmail(params: { callbackURL?: string; token: string }, options?: LtAuthCallOptions): Promise<LtAuthResponse>;\n}\n\nconst pluginRegistry: unknown[] = [];\n\n/** Register extra Better Auth client plugins for every client created afterwards (prefer `provideLtAuth({ plugins })`). */\nexport function registerLtAuthPlugins(plugins: unknown[]): void {\n pluginRegistry.push(...plugins);\n}\n\n/** Plugins registered via {@link registerLtAuthPlugins}. */\nexport function getLtAuthPluginRegistry(): readonly unknown[] {\n return [...pluginRegistry];\n}\n\n/** Clear the plugin registry (tests). */\nexport function clearLtAuthPluginRegistry(): void {\n pluginRegistry.length = 0;\n}\n\n/**\n * `baseURL` / `basePath` of the Better Auth client for an API URL resolution: behind the dev proxy the origin is the\n * app itself (`''`) and the path gets the `/api` prefix (`/iam` → `/api/iam`), otherwise the API base URL with the\n * configured path.\n */\nexport function resolveLtAuthClientBase(resolution: Pick<LtApiUrlResolution, 'baseUrl' | 'proxy'>, basePath: string): { basePath: string; baseURL: string } {\n const trimmed = (basePath || '/iam').replace(/\\/+$/, '');\n const path = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;\n if (resolution.proxy) {\n return { basePath: path === '/api' || path.startsWith('/api/') ? path : `/api${path}`, baseURL: '' };\n }\n return { basePath: path, baseURL: resolution.baseUrl };\n}\n\n/**\n * Absolute Better Auth URL for `baseURL` + `basePath`.\n *\n * Better Auth rejects a relative `baseURL` (\"Invalid base URL\"), so an empty origin (same-origin deployment, dev proxy\n * `/api/iam`) is resolved against the browser origin. Without a usable origin (server without API URL) the path is\n * returned unchanged; such a client cannot reach the backend anyway.\n */\nexport function resolveLtAuthClientUrl(baseURL: string, basePath: string): string {\n const path = basePath ? (basePath.startsWith('/') ? basePath : `/${basePath}`) : '';\n if (baseURL) {\n return `${baseURL.replace(/\\/+$/, '')}${path}`;\n }\n const origin = typeof location !== 'undefined' ? location.origin : '';\n return origin && origin !== 'null' ? `${origin}${path}` : path;\n}\n\n/**\n * Load `better-auth/client` and its plugins on demand. Dynamic imports keep Better Auth (and better-fetch) out of the\n * initial bundle: esbuild puts them into a lazy chunk that is fetched with the first auth action.\n */\nfunction loadBetterAuth(): Promise<[typeof import('better-auth/client'), typeof import('better-auth/client/plugins')]> {\n return Promise.all([import('better-auth/client'), import('better-auth/client/plugins')]);\n}\n\n/**\n * Create the hashing Better Auth client wrapper.\n *\n * Uses the framework-agnostic `better-auth/client` (`createAuthClient`) with `twoFactorClient()` (and `adminClient()` when\n * enabled), the plugins of `config.plugins` and the registry, and the given fetch. Async because Better Auth is loaded\n * on first use (see `LtAuthService.getClient()`, which shares one client per app).\n */\nexport async function createLtAuthClient(config: LtAuthClientConfig): Promise<LtAuthClient> {\n const [{ createAuthClient }, { adminClient, twoFactorClient }] = await loadBetterAuth();\n const plugins: unknown[] = [];\n if (config.enableTwoFactor !== false) {\n plugins.push(twoFactorClient({ onTwoFactorRedirect: () => config.onTwoFactorRedirect?.() }));\n }\n if (config.enableAdmin) {\n plugins.push(adminClient());\n }\n plugins.push(...(config.plugins ?? []), ...pluginRegistry);\n const fetchImpl = config.fetch;\n const raw = createAuthClient({\n baseURL: resolveLtAuthClientUrl(config.baseURL, config.basePath),\n fetchOptions: {\n credentials: 'include',\n ...(fetchImpl ? { customFetchImpl: (input: RequestInfo | URL, init?: RequestInit) => fetchImpl(input, init) } : {}),\n },\n plugins: plugins as never[],\n });\n // Better Auth's client is a Proxy without own keys: every member is listed explicitly, never spread.\n const client = raw as unknown as Record<string, any>;\n const call = (path: string[], args: unknown[]): Promise<LtAuthResponse<any>> => {\n let target: any = client;\n for (const key of path) {\n target = target[key];\n }\n return target(...args);\n };\n const hashed = async <T extends Record<string, unknown>>(params: T, fields: string[], method: string): Promise<T> => {\n const result: Record<string, unknown> = { ...params };\n for (const field of fields) {\n const value = params[field];\n if (typeof value !== 'string' || !value) {\n throw new Error(`[@lenne.tech/ng-base] ${method}: \"${field}\" is required`);\n }\n result[field] = await ltSha256(value);\n }\n return result as T;\n };\n const withOptions = (options?: LtAuthCallOptions) => (options ? [{ fetchOptions: options }] : []);\n\n return {\n raw,\n changePassword: async (params, options) =>\n call(['changePassword'], [await hashed(params as Record<string, unknown>, ['currentPassword', 'newPassword'], 'changePassword'), ...withOptions(options)]),\n getSession: (options) => call(['getSession'], options ? [{ fetchOptions: options }] : []),\n passkey: {\n deletePasskey: (params, options) => call(['$fetch'], ['/passkey/delete-passkey', { body: params, method: 'POST', ...options }]),\n listUserPasskeys: (options) => call(['$fetch'], ['/passkey/list-user-passkeys', { method: 'GET', ...options }]),\n updatePasskey: (params, options) => call(['$fetch'], ['/passkey/update-passkey', { body: params, method: 'POST', ...options }]),\n },\n requestPasswordReset: (params, options) => call(['requestPasswordReset'], [params, ...withOptions(options)]),\n resetPassword: async (params, options) => call(['resetPassword'], [await hashed(params as Record<string, unknown>, ['newPassword'], 'resetPassword'), ...withOptions(options)]),\n sendVerificationEmail: (params, options) => call(['sendVerificationEmail'], [params, ...withOptions(options)]),\n signIn: {\n email: async (params, options) => call(['signIn', 'email'], [await hashed(params as Record<string, unknown>, ['password'], 'signIn.email'), ...withOptions(options)]),\n },\n signOut: (options) => call(['signOut'], options ? [{ fetchOptions: options }] : []),\n signUp: {\n email: async (params, options) => call(['signUp', 'email'], [await hashed(params as Record<string, unknown>, ['password'], 'signUp.email'), ...withOptions(options)]),\n },\n twoFactor: {\n disable: async (params, options) =>\n call(['twoFactor', 'disable'], [await hashed(params as Record<string, unknown>, ['password'], 'twoFactor.disable'), ...withOptions(options)]),\n enable: async (params, options) =>\n call(['twoFactor', 'enable'], [await hashed(params as Record<string, unknown>, ['password'], 'twoFactor.enable'), ...withOptions(options)]),\n generateBackupCodes: async (params, options) =>\n call(['twoFactor', 'generateBackupCodes'], [await hashed(params as Record<string, unknown>, ['password'], 'twoFactor.generateBackupCodes'), ...withOptions(options)]),\n verifyBackupCode: (params, options) => call(['twoFactor', 'verifyBackupCode'], [params, ...withOptions(options)]),\n verifyTotp: (params, options) => call(['twoFactor', 'verifyTotp'], [params, ...withOptions(options)]),\n },\n verifyEmail: (params, options) => call(['verifyEmail'], [{ query: params }, ...withOptions(options)]),\n };\n}\n","","","import { inject } from '@angular/core';\nimport { LtI18nService } from '@lenne.tech/ng-base';\n\nimport de from './i18n/de.json';\nimport en from './i18n/en.json';\n\n/** The `lt.auth.*` texts (also shipped as `i18n/auth/{de,en}.json`). */\nexport const LT_AUTH_MESSAGES = { de, en } as const;\n\n/** `LtI18nService` with the `lt.auth.*` texts registered (injection context). */\nexport function injectLtAuthI18n(): LtI18nService {\n const i18n = inject(LtI18nService);\n i18n.registerLibraryMessages('auth', LT_AUTH_MESSAGES);\n return i18n;\n}\n","import { inject, Service, type Signal } from '@angular/core';\nimport { LtApiUrlService, ltArrayBufferToBase64Url, ltBase64UrlToUint8Array } from '@lenne.tech/ng-base';\nimport {\n LT_AUTH_OPTIONS,\n LtAuthStore,\n readLtAuthAnswer,\n type LtAuthCallOptions,\n type LtAuthFeatures,\n type LtAuthMode,\n type LtAuthResponse,\n type LtNoStrayCredential,\n type LtPasskey,\n type LtPasskeyAuthResult,\n type LtPasskeyRegisterResult,\n type LtTwoFactorEnableResult,\n type LtUser,\n type LtUserInput,\n} from '@lenne.tech/ng-base/auth/provide';\n\nimport { createLtAuthClient, resolveLtAuthClientBase, type LtAuthClient } from './auth-client';\nimport { injectLtAuthI18n } from './i18n';\n\n/** Passkey authentication options as nest-server sends them (base64url strings, plus the `challengeId` extension). */\ninterface LtPasskeyAuthenticationOptions {\n allowCredentials?: { id: string; transports?: string[]; type: string }[];\n challenge: string;\n challengeId?: string;\n rpId?: string;\n timeout?: number;\n userVerification?: UserVerificationRequirement;\n}\n\n/** Passkey registration options as nest-server sends them. */\ninterface LtPasskeyRegistrationOptions {\n attestation?: AttestationConveyancePreference;\n authenticatorSelection?: AuthenticatorSelectionCriteria;\n challenge: string;\n challengeId?: string;\n excludeCredentials?: { id: string; transports?: string[]; type: string }[];\n pubKeyCredParams: PublicKeyCredentialParameters[];\n rp: PublicKeyCredentialRpEntity;\n timeout?: number;\n user: { displayName: string; id: string; name: string };\n}\n\n/**\n * Authentication against nest-server's Better Auth integration (`/iam`), the Angular counterpart of `useLtAuth()`.\n *\n * A facade over {@link LtAuthStore} (`@lenne.tech/ng-base/auth/provide`): state, transport, session validation and\n * sign-out are the store's (same signals, same methods), this service adds the flows that need Better Auth or WebAuthn\n * — sign-in/up, 2FA, passkeys, password and email. Guards, the interceptor and `provideLtAuth()` use the store only, so\n * this service (and Better Auth, loaded on first use) stays out of the initial bundle until a page injects it.\n *\n * State is signal-based and backed by the client-readable `lt-auth-state` cookie, so SSR renders the signed-in shell\n * from the request cookie (UI gating only; the session itself is the httpOnly `iam.session_token`).\n *\n * Transport: session cookie first; when cookies do not work (401 while the state says signed in) the service switches\n * to JWT mode (`GET /iam/token`, Bearer header) and refreshes a stale JWT once per burst. All credentials are SHA-256\n * hashed before they leave the browser.\n */\n@Service()\nexport class LtAuthService {\n private readonly store = inject(LtAuthStore);\n private readonly api = inject(LtApiUrlService);\n private readonly options = inject(LT_AUTH_OPTIONS);\n private readonly i18n = injectLtAuthI18n();\n private clientRequest: Promise<LtAuthClient> | null = null;\n\n // ── state (the store's signals) ────────────────────────────────────────────────────────────────────────────────────\n /** Signed-in user (from the auth-state cookie, refreshed by `validateSession()` and every sign-in). */\n readonly user: Signal<LtUser | null> = this.store.user;\n /** Whether a user is signed in (UI gating; the backend decides). */\n readonly isAuthenticated: Signal<boolean> = this.store.isAuthenticated;\n /** Current transport. */\n readonly authMode: Signal<LtAuthMode> = this.store.authMode;\n /** Whether the JWT fallback is active. */\n readonly isJwtMode: Signal<boolean> = this.store.isJwtMode;\n /** Whether a sign-in/up/out or passkey flow is running. */\n readonly isLoading: Signal<boolean> = this.store.isLoading;\n /** Whether the user has the `admin` role (UX gate only). */\n readonly isAdmin: Signal<boolean> = this.store.isAdmin;\n /** Whether two-factor authentication is enabled for the user. */\n readonly is2FAEnabled: Signal<boolean> = this.store.is2FAEnabled;\n /** nest-server feature flags (`GET /iam/features`); fetched on the server and transferred to the browser. */\n readonly features: Signal<LtAuthFeatures> = this.store.features;\n /** Whether passkeys can be used: enabled in the options, backend feature on and WebAuthn available in this browser. */\n readonly passkeySupported: Signal<boolean> = this.store.passkeySupported;\n\n /**\n * The hashing Better Auth client (see {@link LtAuthClient}), created once per app on first use. Better Auth is loaded\n * lazily (dynamic import), so it is not part of the initial bundle; session state, guards, the interceptor and\n * {@link fetchWithAuth} never need it. The client sends every request through {@link fetchWithAuth} (the same\n * auth-aware fetch as `LT_FETCH`). During SSR it never carries the request's cookies, so do not use it on the\n * server for anything that needs the user's session. A failed load is retried on the next call.\n */\n getClient(): Promise<LtAuthClient> {\n if (!this.clientRequest) {\n this.clientRequest = createLtAuthClient({\n ...resolveLtAuthClientBase(this.api.resolve(), this.options.basePath),\n enableAdmin: this.options.enableAdmin,\n enableTwoFactor: this.options.enableTwoFactor,\n // No onTwoFactorRedirect: nest-server answers `requiresTwoFactor`, Better Auth's plugin only sees\n // `twoFactorRedirect`, so `signIn.email` recognises both itself and navigates once.\n fetch: (input, init) => this.store.fetchWithAuth(input, init),\n plugins: this.options.plugins,\n });\n this.clientRequest.catch(() => {\n this.clientRequest = null;\n });\n }\n return this.clientRequest;\n }\n\n /** The current JWT (JWT mode only), or `null`. */\n jwtToken(): string | null {\n return this.store.jwtToken();\n }\n\n // ── roles ──────────────────────────────────────────────────────────────────────────────────────────────────────────\n /** `user.role === role` or `user.roles` contains it (case-sensitive). */\n hasRole(role: string): boolean {\n return this.store.hasRole(role);\n }\n\n /** Whether the user has any of the roles. */\n hasAnyRole(...roles: string[]): boolean {\n return this.store.hasAnyRole(...roles);\n }\n\n // ── features ───────────────────────────────────────────────────────────────────────────────────────────────────────\n /** Fetch the feature flags (`GET /iam/features`, see {@link LtAuthStore.fetchFeatures}). */\n fetchFeatures(): Promise<LtAuthFeatures> {\n return this.store.fetchFeatures();\n }\n\n /** The feature flags, fetched at most once (transferred from SSR, or fetched on first call). */\n ensureFeatures(): Promise<LtAuthFeatures> {\n return this.store.ensureFeatures();\n }\n\n // ── sign-in / sign-up / sign-out ───────────────────────────────────────────────────────────────────────────────────\n /**\n * Email sign-in (password hashed). A second factor (`requiresTwoFactor` from nest-server or `twoFactorRedirect` from\n * Better Auth) navigates to `twoFactorRedirectPath` (keeping the current `redirect` query parameter) and sets no user. A JWT-shaped body token (nest-server\n * `cookies: false`) switches to JWT mode; otherwise the session cookie is used and a JWT is fetched in the background.\n */\n readonly signIn = {\n email: async <T extends { callbackURL?: string; email: string; password: string; rememberMe?: boolean }>(\n params: LtNoStrayCredential<T, 'password'>,\n options?: LtAuthCallOptions,\n ): Promise<LtAuthResponse> =>\n this.store.withLoading(async () => {\n const result = await (await this.getClient()).signIn.email(params, options);\n if (readLtAuthAnswer(result).twoFactor) {\n this.store.navigateKeepingRedirect(this.options.twoFactorRedirectPath);\n } else {\n this.store.applyAuthResult(result);\n }\n return result;\n }),\n /** Passkey sign-in (same as {@link authenticateWithPasskey}). */\n passkey: (): Promise<LtPasskeyAuthResult> => this.authenticateWithPasskey(),\n };\n\n /**\n * Email sign-up (password hashed), same token handling as sign-in. With email verification nest-server answers\n * `emailVerificationRequired: true` and revokes the session: no user is set, the caller leads to the verify page.\n */\n readonly signUp = {\n email: async <T extends { callbackURL?: string; email: string; name: string; password: string }>(\n params: LtNoStrayCredential<T, 'password'>,\n options?: LtAuthCallOptions,\n ): Promise<LtAuthResponse> =>\n this.store.withLoading(async () => {\n const result = await (await this.getClient()).signUp.email(params, options);\n this.store.applyAuthResult(result);\n return result;\n }),\n };\n\n /**\n * Sign out: sign-out hooks (offline sync flush), `POST /iam/sign-out`, local state cleared, after-hooks (sync wipe).\n * The local state is cleared even when the request fails (offline device). See {@link LtAuthStore.signOut}.\n */\n signOut(options?: LtAuthCallOptions): Promise<void> {\n return this.store.signOut(options);\n }\n\n // ── session ────────────────────────────────────────────────────────────────────────────────────────────────────────\n /** Store the user in state and cookie (browser always; SSR never writes). `image: null` becomes `undefined`. */\n setUser(user: LtUserInput | null, mode: LtAuthMode = 'cookie'): void {\n this.store.setUser(user, mode);\n }\n\n /** Clear local auth state and cookies (browser). Does not delete offline data (use `signOut()` for that). */\n clearUser(): void {\n this.store.clearUser();\n }\n\n /**\n * Validate the session (app start / hard reload). Server: answers from the cookie, no backend call. Browser:\n * `GET /iam/get-session` (≤ 10 s); a user is merged with the cached one (nest-server-only fields kept, authz keys\n * fail-closed); no user but a cached one → `true` (e.g. right after 2FA); else `false`.\n */\n validateSession(): Promise<boolean> {\n return this.store.validateSession();\n }\n\n /** The auth-aware fetch, also provided as `LT_FETCH` (see {@link LtAuthStore.fetchWithAuth}). */\n fetchWithAuth(input: RequestInfo | URL, init: RequestInit = {}): Promise<Response> {\n return this.store.fetchWithAuth(input, init);\n }\n\n /** Token to retry a request with after a 401 (see {@link LtAuthStore.recoverFrom401}). */\n recoverFrom401(url: string, sentToken: string | null): Promise<string | null> {\n return this.store.recoverFrom401(url, sentToken);\n }\n\n /** Session-loss handling for a 401 from `url` (see `LtUnauthorizedHandler`). */\n handleUnauthorized(url?: string): Promise<boolean> {\n return this.store.handleUnauthorized(url);\n }\n\n /** `GET /iam/token` → store the JWT and switch to JWT mode. One request per burst. Browser only. */\n switchToJwtMode(): Promise<boolean> {\n return this.store.switchToJwtMode();\n }\n\n /** Re-mint the JWT (JWT mode only). */\n refreshJwtToken(): Promise<boolean> {\n return this.store.refreshJwtToken();\n }\n\n // ── passkeys (WebAuthn, nest-server challengeId) ───────────────────────────────────────────────────────────────────\n /** Passkey sign-in: options → `navigator.credentials.get` → `verify-authentication` (`challengeId`) → user set. */\n async authenticateWithPasskey(): Promise<LtPasskeyAuthResult> {\n if (!hasWebAuthn()) {\n return { error: this.i18n.t('lt.auth.passkeyUnsupported'), success: false };\n }\n return this.store.withLoading(async () => {\n try {\n const optionsResponse = await this.store.fetchWithAuth(this.store.authUrl('/passkey/generate-authenticate-options'), { method: 'GET' });\n if (!optionsResponse.ok) {\n return { error: this.i18n.t('lt.auth.passkeyError'), success: false };\n }\n const options = (await optionsResponse.json()) as LtPasskeyAuthenticationOptions;\n const credential = (await navigator.credentials.get({\n publicKey: {\n allowCredentials: (options.allowCredentials ?? []).map((descriptor) => ({\n ...descriptor,\n id: typeof descriptor.id === 'string' ? ltBase64UrlToUint8Array(descriptor.id).buffer : descriptor.id,\n })) as PublicKeyCredentialDescriptor[],\n challenge: ltBase64UrlToUint8Array(options.challenge).buffer,\n rpId: options.rpId,\n timeout: options.timeout,\n userVerification: options.userVerification,\n },\n })) as PublicKeyCredential | null;\n if (!credential) {\n return { error: this.i18n.t('lt.auth.noPasskeySelected'), success: false };\n }\n const assertion = credential.response as AuthenticatorAssertionResponse;\n const authResponse = await this.store.fetchWithAuth(this.store.authUrl('/passkey/verify-authentication'), {\n body: JSON.stringify({\n challengeId: options.challengeId,\n response: {\n clientExtensionResults: credential.getClientExtensionResults?.() ?? {},\n id: credential.id,\n rawId: ltArrayBufferToBase64Url(credential.rawId),\n response: {\n authenticatorData: ltArrayBufferToBase64Url(assertion.authenticatorData),\n clientDataJSON: ltArrayBufferToBase64Url(assertion.clientDataJSON),\n signature: ltArrayBufferToBase64Url(assertion.signature),\n userHandle: assertion.userHandle ? ltArrayBufferToBase64Url(assertion.userHandle) : null,\n },\n type: credential.type,\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n });\n const result = ((await authResponse.json().catch(() => ({}))) ?? {}) as { message?: string; session?: { token: string }; user?: LtUserInput };\n if (!authResponse.ok) {\n return { error: result.message || this.i18n.t('lt.auth.passkeyFailed'), success: false };\n }\n // A JWT in the answer (nest-server with `cookies: false`) → JWT mode; otherwise the verification set the session\n // cookie. The opaque session token (`session.token`, or `token` from older servers) is never stored as JWT (it\n // would land in a script-readable cookie). Without user in the answer it is loaded from the session.\n const user = await this.store.adoptVerifiedSession(result);\n if (!user) {\n return { error: this.i18n.t('lt.auth.passkeyFailed'), success: false };\n }\n return { session: result.session, success: true, user };\n } catch (error) {\n if (error instanceof Error && error.name === 'NotAllowedError') {\n return { error: this.i18n.t('lt.auth.passkeyAborted'), success: false };\n }\n return { error: error instanceof Error && error.message ? error.message : this.i18n.t('lt.auth.passkeyFailed'), success: false };\n }\n });\n }\n\n /** Register a passkey for the signed-in user (`challengeId` body as nest-server expects). */\n async registerPasskey(name?: string): Promise<LtPasskeyRegisterResult> {\n if (!hasWebAuthn()) {\n return { error: this.i18n.t('lt.auth.passkeyUnsupported'), success: false };\n }\n return this.store.withLoading(async () => {\n try {\n const optionsResponse = await this.store.fetchWithAuth(this.store.authUrl('/passkey/generate-register-options'), { method: 'GET' });\n if (!optionsResponse.ok) {\n const body = (await optionsResponse.json().catch(() => ({}))) as { message?: string } | null;\n return { error: body?.message || this.i18n.t('lt.auth.registerOptionsError'), success: false };\n }\n const options = (await optionsResponse.json()) as LtPasskeyRegistrationOptions;\n const credential = (await navigator.credentials.create({\n publicKey: {\n attestation: options.attestation,\n authenticatorSelection: options.authenticatorSelection,\n challenge: ltBase64UrlToUint8Array(options.challenge).buffer,\n excludeCredentials: (options.excludeCredentials ?? []).map((descriptor) => ({\n ...descriptor,\n id: ltBase64UrlToUint8Array(descriptor.id).buffer,\n })) as PublicKeyCredentialDescriptor[],\n pubKeyCredParams: options.pubKeyCredParams,\n rp: options.rp,\n timeout: options.timeout,\n user: { ...options.user, id: ltBase64UrlToUint8Array(options.user.id).buffer },\n },\n })) as PublicKeyCredential | null;\n if (!credential) {\n return { error: this.i18n.t('lt.auth.passkeyCreationAborted'), success: false };\n }\n const attestation = credential.response as AuthenticatorAttestationResponse;\n const registerResponse = await this.store.fetchWithAuth(this.store.authUrl('/passkey/verify-registration'), {\n body: JSON.stringify({\n challengeId: options.challengeId,\n name,\n response: {\n clientExtensionResults: credential.getClientExtensionResults?.() ?? {},\n id: credential.id,\n rawId: ltArrayBufferToBase64Url(credential.rawId),\n response: {\n attestationObject: ltArrayBufferToBase64Url(attestation.attestationObject),\n clientDataJSON: ltArrayBufferToBase64Url(attestation.clientDataJSON),\n transports: attestation.getTransports?.() ?? [],\n },\n type: credential.type,\n },\n }),\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n });\n const result = (await registerResponse.json().catch(() => ({}))) as { message?: string } | null;\n if (!registerResponse.ok) {\n return { error: result?.message || this.i18n.t('lt.auth.passkeyRegisterFailed'), success: false };\n }\n return { passkey: result, success: true };\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'NotAllowedError') {\n return { error: this.i18n.t('lt.auth.passkeyCreationAborted'), success: false };\n }\n // The authenticator already holds a credential of this account (it was in excludeCredentials).\n if (error.name === 'InvalidStateError' || error.message.includes('already registered')) {\n return { error: this.i18n.t('lt.auth.passkeyAlreadyRegistered'), success: false };\n }\n return { error: error.message || this.i18n.t('lt.auth.passkeyRegisterFailed'), success: false };\n }\n return { error: this.i18n.t('lt.auth.passkeyRegisterFailed'), success: false };\n }\n });\n }\n\n /** Passkey management of the signed-in user. */\n readonly passkey = {\n delete: async (id: string): Promise<LtAuthResponse> => (await this.getClient()).passkey.deletePasskey({ id }),\n list: async (): Promise<LtAuthResponse<LtPasskey[]>> => (await this.getClient()).passkey.listUserPasskeys(),\n update: async (id: string, name: string): Promise<LtAuthResponse> => (await this.getClient()).passkey.updatePasskey({ id, name }),\n };\n\n // ── two-factor (TOTP + backup codes) ───────────────────────────────────────────────────────────────────────────────\n /** Two-factor methods (passwords hashed). `verifyTotp` / `verifyBackupCode` set the user on success (fix vs. Nuxt). */\n readonly twoFactor = {\n disable: async <T extends { password: string }>(params: LtNoStrayCredential<T, 'password'>): Promise<LtAuthResponse> => (await this.getClient()).twoFactor.disable(params),\n enable: async <T extends { issuer?: string; password: string }>(params: LtNoStrayCredential<T, 'password'>): Promise<LtAuthResponse<LtTwoFactorEnableResult>> =>\n (await this.getClient()).twoFactor.enable(params),\n generateBackupCodes: async <T extends { password: string }>(params: LtNoStrayCredential<T, 'password'>): Promise<LtAuthResponse<{ backupCodes: string[] }>> =>\n (await this.getClient()).twoFactor.generateBackupCodes(params),\n verifyBackupCode: async (params: { code: string; trustDevice?: boolean }): Promise<LtAuthResponse> =>\n this.adoptVerifiedSession(await (await this.getClient()).twoFactor.verifyBackupCode(params)),\n verifyTotp: async (params: { code: string; trustDevice?: boolean }): Promise<LtAuthResponse> =>\n this.adoptVerifiedSession(await (await this.getClient()).twoFactor.verifyTotp(params)),\n };\n\n // ── password & email ───────────────────────────────────────────────────────────────────────────────────────────────\n /** `POST /iam/change-password` (both passwords hashed; `revokeOtherSessions` forwarded). */\n async changePassword<T extends { currentPassword: string; newPassword: string; revokeOtherSessions?: boolean }>(\n params: LtNoStrayCredential<T, 'currentPassword' | 'newPassword'>,\n ): Promise<LtAuthResponse> {\n return (await this.getClient()).changePassword(params);\n }\n\n /** `POST /iam/request-password-reset`; `redirectTo` defaults to `<siteUrl>/auth/reset-password` (absolute, never user-derived). */\n async requestPasswordReset<T extends { email: string; redirectTo?: string }>(params: LtNoStrayCredential<T, never>): Promise<LtAuthResponse> {\n const redirectTo = params.redirectTo || this.absoluteAppUrl('/auth/reset-password');\n return (await this.getClient()).requestPasswordReset({ ...params, redirectTo });\n }\n\n /** `POST /iam/reset-password` with `{ newPassword (hashed), token }`. */\n async resetPassword<T extends { newPassword: string; token: string }>(params: LtNoStrayCredential<T, 'newPassword'>): Promise<LtAuthResponse> {\n return (await this.getClient()).resetPassword(params);\n }\n\n /** `POST /iam/send-verification-email`; `callbackURL` defaults to `<siteUrl>/auth/login` (absolute). */\n async sendVerificationEmail<T extends { callbackURL?: string; email: string }>(params: LtNoStrayCredential<T, never>): Promise<LtAuthResponse> {\n const callbackURL = params.callbackURL || this.absoluteAppUrl('/auth/login');\n return (await this.getClient()).sendVerificationEmail({ ...params, callbackURL });\n }\n\n /** `GET /iam/verify-email?token=` (JSON answer without `callbackURL`). */\n async verifyEmail(params: { callbackURL?: string; token: string }): Promise<LtAuthResponse> {\n return (await this.getClient()).verifyEmail(params);\n }\n\n /**\n * Build an absolute app URL from `NG_PUBLIC_SITE_URL` (or the browser origin), for `redirectTo` / `callbackURL`.\n * Never derived from the request: on the server without a site URL it throws. Absolute input is returned unchanged.\n */\n absoluteAppUrl(path: string): string {\n return this.store.absoluteAppUrl(path);\n }\n\n /**\n * After a successful 2FA verification: see {@link LtAuthStore.adoptVerifiedSession} (a JWT in the answer → JWT mode,\n * else cookie mode; Better Auth's opaque session token is never stored as JWT, that would put the session into a\n * script-readable cookie).\n */\n private async adoptVerifiedSession(result: LtAuthResponse): Promise<LtAuthResponse> {\n if (!result || result.error || !result.data) {\n return result;\n }\n await this.store.adoptVerifiedSession(result);\n return result;\n }\n}\n\nfunction hasWebAuthn(): boolean {\n return typeof navigator !== 'undefined' && !!navigator.credentials;\n}\n"],"mappings":"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"}