@aakash58/chatbot 1.1.19 → 1.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +17 -0
- package/.vscode/extensions.json +4 -0
- package/.vscode/launch.json +41 -0
- package/.vscode/settings.json +14 -0
- package/.vscode/tasks.json +60 -0
- package/README.md +298 -22
- package/angular.json +132 -0
- package/docs/PUBLISHING_GUIDE.md +104 -0
- package/package.json +75 -29
- package/projects/app-doohbot/public/assets/const/app-const.json +15 -0
- package/projects/app-doohbot/public/assets/const/doohclick_license.json +6 -0
- package/projects/app-doohbot/public/favicon.ico +0 -0
- package/projects/app-doohbot/src/app/app.config.ts +13 -0
- package/projects/app-doohbot/src/app/app.html +31 -0
- package/projects/app-doohbot/src/app/app.routes.ts +3 -0
- package/projects/app-doohbot/src/app/app.scss +279 -0
- package/projects/app-doohbot/src/app/app.spec.ts +23 -0
- package/projects/app-doohbot/src/app/app.ts +72 -0
- package/projects/app-doohbot/src/index.html +15 -0
- package/projects/app-doohbot/src/main.ts +6 -0
- package/projects/app-doohbot/src/styles.scss +15 -0
- package/projects/app-doohbot/tsconfig.app.json +15 -0
- package/projects/app-doohbot/tsconfig.spec.json +14 -0
- package/projects/doohbot/README.md +64 -0
- package/projects/doohbot/docs/README.md +140 -0
- package/projects/doohbot/ng-package.json +10 -0
- package/projects/doohbot/package.json +16 -0
- package/projects/doohbot/src/lib/app/chat/chat-ui-state.service.ts +194 -0
- package/projects/doohbot/src/lib/app/chat/chat.service.ts +547 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-button/chat-button.component.html +27 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-button/chat-button.component.scss +115 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-button/chat-button.component.ts +35 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-footer/chat-footer.component.html +3 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-footer/chat-footer.component.scss +20 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-footer/chat-footer.component.ts +12 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-header/chat-header.component.html +34 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-header/chat-header.component.scss +78 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-header/chat-header.component.ts +52 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.html +77 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.scss +346 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.ts +188 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-window/chat-window.component.html +146 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-window/chat-window.component.scss +187 -0
- package/projects/doohbot/src/lib/app/chat/components/chat-window/chat-window.component.ts +256 -0
- package/projects/doohbot/src/lib/app/chat/components/message-input/message-input.component.html +17 -0
- package/projects/doohbot/src/lib/app/chat/components/message-input/message-input.component.scss +59 -0
- package/projects/doohbot/src/lib/app/chat/components/message-input/message-input.component.ts +28 -0
- package/projects/doohbot/src/lib/app/chat/components/message-list/message-list.component.html +138 -0
- package/projects/doohbot/src/lib/app/chat/components/message-list/message-list.component.scss +436 -0
- package/projects/doohbot/src/lib/app/chat/components/message-list/message-list.component.ts +106 -0
- package/projects/doohbot/src/lib/app/chat/model/chat-history.model.ts +57 -0
- package/projects/doohbot/src/lib/app/chat/model/chat-request.model.ts +17 -0
- package/projects/doohbot/src/lib/app/chat/model/chat-response.model.ts +9 -0
- package/projects/doohbot/src/lib/app/chat/model/chat-session.model.ts +14 -0
- package/{lib/app/chat/model/chat-stream-message.model.d.ts → projects/doohbot/src/lib/app/chat/model/chat-stream-message.model.ts} +6 -5
- package/projects/doohbot/src/lib/app/chat/model/chat-stream-response.model.ts +12 -0
- package/projects/doohbot/src/lib/app/chat/services/chat-api.service.ts +82 -0
- package/projects/doohbot/src/lib/app/chat/services/chat-audio.service.ts +44 -0
- package/projects/doohbot/src/lib/app/chat/services/chat-history.service.ts +303 -0
- package/projects/doohbot/src/lib/app/login/login-form.component.html +80 -0
- package/projects/doohbot/src/lib/app/login/login-form.component.scss +189 -0
- package/projects/doohbot/src/lib/app/login/login-form.component.ts +45 -0
- package/projects/doohbot/src/lib/app/personalization/personalization-dialog.component.html +81 -0
- package/projects/doohbot/src/lib/app/personalization/personalization-dialog.component.scss +179 -0
- package/projects/doohbot/src/lib/app/personalization/personalization-dialog.component.ts +217 -0
- package/projects/doohbot/src/lib/app/personalization/personalization.service.ts +197 -0
- package/projects/doohbot/src/lib/app/personalization/sections/account/account-section.component.html +111 -0
- package/projects/doohbot/src/lib/app/personalization/sections/account/account-section.component.scss +218 -0
- package/projects/doohbot/src/lib/app/personalization/sections/account/account-section.component.ts +121 -0
- package/projects/doohbot/src/lib/app/personalization/sections/instructions/instructions-section.component.html +46 -0
- package/projects/doohbot/src/lib/app/personalization/sections/instructions/instructions-section.component.scss +138 -0
- package/projects/doohbot/src/lib/app/personalization/sections/instructions/instructions-section.component.ts +28 -0
- package/projects/doohbot/src/lib/app/personalization/sections/preferences/color-picker-dialog.component.ts +92 -0
- package/projects/doohbot/src/lib/app/personalization/sections/preferences/preferences-section.component.html +198 -0
- package/projects/doohbot/src/lib/app/personalization/sections/preferences/preferences-section.component.scss +107 -0
- package/projects/doohbot/src/lib/app/personalization/sections/preferences/preferences-section.component.ts +103 -0
- package/projects/doohbot/src/lib/app/personalization/sections/profile/profile-section.component.html +46 -0
- package/projects/doohbot/src/lib/app/personalization/sections/profile/profile-section.component.scss +131 -0
- package/projects/doohbot/src/lib/app/personalization/sections/profile/profile-section.component.ts +23 -0
- package/projects/doohbot/src/lib/app/personalization/sections/settings/setting-section.component.html +33 -0
- package/projects/doohbot/src/lib/app/personalization/sections/settings/setting-section.component.scss +61 -0
- package/projects/doohbot/src/lib/app/personalization/sections/settings/setting-section.component.ts +20 -0
- package/projects/doohbot/src/lib/app/personalization/sections/terms/terms-section.component.html +30 -0
- package/projects/doohbot/src/lib/app/personalization/sections/terms/terms-section.component.scss +59 -0
- package/projects/doohbot/src/lib/app/personalization/sections/terms/terms-section.component.ts +12 -0
- package/projects/doohbot/src/lib/constant/doohbot-constant.ts +40 -0
- package/projects/doohbot/src/lib/constant/html-entities.ts +8 -0
- package/projects/doohbot/src/lib/constant/utf8.ts +9 -0
- package/projects/doohbot/src/lib/core/app-const.ts +63 -0
- package/projects/doohbot/src/lib/core/auth/account-api.service.ts +53 -0
- package/projects/doohbot/src/lib/core/auth/auth.service.ts +478 -0
- package/projects/doohbot/src/lib/core/auth/models/auth-result.model.ts +4 -0
- package/projects/doohbot/src/lib/core/auth/models/federated-login-request.model.ts +5 -0
- package/projects/doohbot/src/lib/core/auth/models/login-request.model.ts +6 -0
- package/projects/doohbot/src/lib/core/auth/storage.service.ts +113 -0
- package/projects/doohbot/src/lib/core/directives/draggable/draggable-dialog.directive.ts +123 -0
- package/projects/doohbot/src/lib/core/directives/draggable/draggable-dialog.module.ts +9 -0
- package/projects/doohbot/src/lib/core/directives/fullscreen/fullscreen.directive.ts +58 -0
- package/projects/doohbot/src/lib/core/directives/fullscreen/fullscreen.module.ts +9 -0
- package/projects/doohbot/src/lib/core/directives/popout/popout.directive.ts +169 -0
- package/projects/doohbot/src/lib/core/directives/popout/popout.module.ts +9 -0
- package/projects/doohbot/src/lib/core/directives/resizable/resizable-dialog.directive.ts +197 -0
- package/projects/doohbot/src/lib/core/directives/resizable/resizable-dialog.module.ts +9 -0
- package/projects/doohbot/src/lib/core/enums/api-request-state.enum.ts +9 -0
- package/projects/doohbot/src/lib/core/environments/environment.prod.ts +14 -0
- package/projects/doohbot/src/lib/core/environments/environment.ts +14 -0
- package/projects/doohbot/src/lib/core/helpers/crypto-helper.service.ts +72 -0
- package/projects/doohbot/src/lib/core/http/http-stream.service.ts +105 -0
- package/projects/doohbot/src/lib/core/http/http.service.ts +148 -0
- package/projects/doohbot/src/lib/core/interceptors/auth.interceptor.ts +118 -0
- package/projects/doohbot/src/lib/core/interceptors/license.interceptor.ts +50 -0
- package/projects/doohbot/src/lib/core/models/api-config.model.ts +82 -0
- package/projects/doohbot/src/lib/core/models/api-request.model.ts +92 -0
- package/projects/doohbot/src/lib/core/models/api-response.model.ts +13 -0
- package/projects/doohbot/src/lib/core/models/doohbot-config.model.ts +109 -0
- package/{lib/core/models/license.model.d.ts → projects/doohbot/src/lib/core/models/license.model.ts} +27 -23
- package/projects/doohbot/src/lib/core/models/message.ts +18 -0
- package/projects/doohbot/src/lib/core/models/theme-config.model.ts +48 -0
- package/projects/doohbot/src/lib/core/services/core-config.service.ts +53 -0
- package/projects/doohbot/src/lib/core/services/doohbot-api.service.ts +207 -0
- package/projects/doohbot/src/lib/core/services/license.service.ts +171 -0
- package/projects/doohbot/src/lib/core/services/markdown.service.ts +73 -0
- package/projects/doohbot/src/lib/core/services/theme.service.ts +305 -0
- package/{lib/core/types/auth-mode.type.d.ts → projects/doohbot/src/lib/core/types/auth-mode.type.ts} +4 -4
- package/{lib/core/types/auth-status.type.d.ts → projects/doohbot/src/lib/core/types/auth-status.type.ts} +5 -4
- package/{lib/core/types/chat-stream.type.d.ts → projects/doohbot/src/lib/core/types/chat-stream.type.ts} +4 -4
- package/{lib/core/types/message-role.type.d.ts → projects/doohbot/src/lib/core/types/message-role.type.ts} +4 -4
- package/{lib/core/types/prompt-mode.type.d.ts → projects/doohbot/src/lib/core/types/prompt-mode.type.ts} +5 -4
- package/{lib/core/types/snackbar-error.type.d.ts → projects/doohbot/src/lib/core/types/snackbar-error.type.ts} +5 -4
- package/{lib/core/types/tenant-resolution-strategy.type.d.ts → projects/doohbot/src/lib/core/types/tenant-resolution-strategy.type.ts} +4 -4
- package/projects/doohbot/src/lib/core/utils/error-handler.util.ts +31 -0
- package/projects/doohbot/src/lib/core/utils/logger.service.ts +45 -0
- package/projects/doohbot/src/lib/doohbot-input.ts +19 -0
- package/projects/doohbot/src/lib/doohbot.component.html +34 -0
- package/projects/doohbot/src/lib/doohbot.component.scss +17 -0
- package/projects/doohbot/src/lib/doohbot.component.spec.ts +31 -0
- package/projects/doohbot/src/lib/doohbot.component.ts +545 -0
- package/projects/doohbot/src/lib/elements.ts +25 -0
- package/projects/doohbot/src/lib/predefined_messages.ts +14 -0
- package/projects/doohbot/src/lib/shared/chips/chips.component.html +9 -0
- package/projects/doohbot/src/lib/shared/chips/chips.component.scss +29 -0
- package/projects/doohbot/src/lib/shared/chips/chips.component.spec.ts +22 -0
- package/projects/doohbot/src/lib/shared/chips/chips.component.ts +20 -0
- package/projects/doohbot/src/lib/shared/dialog/dialog.component.html +29 -0
- package/projects/doohbot/src/lib/shared/dialog/dialog.component.scss +100 -0
- package/projects/doohbot/src/lib/shared/dialog/dialog.component.ts +42 -0
- package/projects/doohbot/src/lib/shared/dialog/dialog.service.ts +62 -0
- package/projects/doohbot/src/lib/shared/dialog/dialog.utils.ts +102 -0
- package/projects/doohbot/src/lib/shared/dropdown-menu/dropdown-menu.component.html +30 -0
- package/projects/doohbot/src/lib/shared/dropdown-menu/dropdown-menu.component.scss +53 -0
- package/projects/doohbot/src/lib/shared/dropdown-menu/dropdown-menu.component.spec.ts +22 -0
- package/projects/doohbot/src/lib/shared/dropdown-menu/dropdown-menu.component.ts +35 -0
- package/projects/doohbot/src/lib/shared/input-dialog/input-dialog.component.html +16 -0
- package/projects/doohbot/src/lib/shared/input-dialog/input-dialog.component.scss +45 -0
- package/projects/doohbot/src/lib/shared/input-dialog/input-dialog.component.ts +46 -0
- package/projects/doohbot/src/lib/shared/menu-item/menu-item.component.html +5 -0
- package/projects/doohbot/src/lib/shared/menu-item/menu-item.component.scss +0 -0
- package/projects/doohbot/src/lib/shared/menu-item/menu-item.component.spec.ts +22 -0
- package/projects/doohbot/src/lib/shared/menu-item/menu-item.component.ts +20 -0
- package/projects/doohbot/src/lib/shared/pipes/simple-markdown.pipe.ts +19 -0
- package/projects/doohbot/src/lib/shared/popout/popout.html +1 -0
- package/projects/doohbot/src/lib/shared/popout/popout.scss +0 -0
- package/projects/doohbot/src/lib/shared/popout/popout.spec.ts +23 -0
- package/projects/doohbot/src/lib/shared/popout/popout.ts +11 -0
- package/projects/doohbot/src/lib/shared/snackbar/snackbar.component.html +7 -0
- package/projects/doohbot/src/lib/shared/snackbar/snackbar.component.scss +125 -0
- package/projects/doohbot/src/lib/shared/snackbar/snackbar.component.spec.ts +21 -0
- package/projects/doohbot/src/lib/shared/snackbar/snackbar.component.ts +44 -0
- package/projects/doohbot/src/lib/shared/snackbar/snackbar.service.ts +54 -0
- package/{lib/shared/snackbar/snackbar.utils.d.ts → projects/doohbot/src/lib/shared/snackbar/snackbar.utils.ts} +49 -33
- package/projects/doohbot/src/lib/styles/_theme.scss +132 -0
- package/projects/doohbot/src/lib/styles/material-override.scss +302 -0
- package/projects/doohbot/src/lib/styles/utility.scss +588 -0
- package/projects/doohbot/src/public-api.ts +42 -0
- package/projects/doohbot/tsconfig.lib.json +15 -0
- package/projects/doohbot/tsconfig.lib.prod.json +11 -0
- package/projects/doohbot/tsconfig.spec.json +10 -0
- package/proxy.conf.json +8 -0
- package/publish.config.js +25 -0
- package/scripts/publishing/index.ts +67 -0
- package/scripts/publishing/pipeline/01-clean.ts +11 -0
- package/scripts/publishing/pipeline/02-validate-pre.ts +8 -0
- package/scripts/publishing/pipeline/03-build.ts +7 -0
- package/scripts/publishing/pipeline/04-validate-post.ts +8 -0
- package/scripts/publishing/pipeline/05-prepare-package.ts +29 -0
- package/scripts/publishing/pipeline/06-version.ts +23 -0
- package/scripts/publishing/pipeline/07-publish.ts +14 -0
- package/scripts/publishing/pipeline/08-cleanup.ts +5 -0
- package/scripts/publishing/types.ts +36 -0
- package/scripts/publishing/utils/command.ts +15 -0
- package/scripts/publishing/utils/config.ts +17 -0
- package/scripts/validate.ts +166 -0
- package/tsconfig.json +45 -0
- package/tsconfig.scripts.json +15 -0
- package/esm2022/aakash58-chatbot.mjs +0 -5
- package/esm2022/lib/app/chat/chat-ui-state.service.mjs +0 -170
- package/esm2022/lib/app/chat/chat.service.mjs +0 -445
- package/esm2022/lib/app/chat/components/chat-button/chat-button.component.mjs +0 -50
- package/esm2022/lib/app/chat/components/chat-footer/chat-footer.component.mjs +0 -12
- package/esm2022/lib/app/chat/components/chat-header/chat-header.component.mjs +0 -66
- package/esm2022/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.mjs +0 -186
- package/esm2022/lib/app/chat/components/chat-window/chat-window.component.mjs +0 -312
- package/esm2022/lib/app/chat/components/message-input/message-input.component.mjs +0 -36
- package/esm2022/lib/app/chat/components/message-list/message-list.component.mjs +0 -115
- package/esm2022/lib/app/chat/model/chat-history.model.mjs +0 -2
- package/esm2022/lib/app/chat/model/chat-request.model.mjs +0 -2
- package/esm2022/lib/app/chat/model/chat-response.model.mjs +0 -2
- package/esm2022/lib/app/chat/model/chat-session.model.mjs +0 -2
- package/esm2022/lib/app/chat/model/chat-stream-message.model.mjs +0 -2
- package/esm2022/lib/app/chat/model/chat-stream-response.model.mjs +0 -2
- package/esm2022/lib/app/chat/services/chat-api.service.mjs +0 -61
- package/esm2022/lib/app/chat/services/chat-audio.service.mjs +0 -50
- package/esm2022/lib/app/chat/services/chat-history.service.mjs +0 -252
- package/esm2022/lib/app/login/login-form.component.mjs +0 -46
- package/esm2022/lib/app/personalization/personalization-dialog.component.mjs +0 -194
- package/esm2022/lib/app/personalization/personalization.service.mjs +0 -149
- package/esm2022/lib/app/personalization/sections/account/account-section.component.mjs +0 -122
- package/esm2022/lib/app/personalization/sections/preferences/color-picker-dialog.component.mjs +0 -86
- package/esm2022/lib/app/personalization/sections/preferences/preferences-section.component.mjs +0 -115
- package/esm2022/lib/app/personalization/sections/profile/profile-section.component.mjs +0 -29
- package/esm2022/lib/app/personalization/sections/settings/setting-section.component.mjs +0 -30
- package/esm2022/lib/app/personalization/sections/terms/terms-section.component.mjs +0 -12
- package/esm2022/lib/constant/doohbot-constant.mjs +0 -28
- package/esm2022/lib/constant/html-entities.mjs +0 -9
- package/esm2022/lib/constant/utf8.mjs +0 -10
- package/esm2022/lib/core/app-const.mjs +0 -61
- package/esm2022/lib/core/auth/account-api.service.mjs +0 -40
- package/esm2022/lib/core/auth/auth.service.mjs +0 -391
- package/esm2022/lib/core/auth/models/auth-result.model.mjs +0 -3
- package/esm2022/lib/core/auth/models/federated-login-request.model.mjs +0 -6
- package/esm2022/lib/core/auth/models/login-request.model.mjs +0 -6
- package/esm2022/lib/core/auth/storage.service.mjs +0 -110
- package/esm2022/lib/core/directives/draggable/draggable-dialog.directive.mjs +0 -112
- package/esm2022/lib/core/directives/fullscreen/fullscreen.directive.mjs +0 -55
- package/esm2022/lib/core/directives/resizable/resizable-dialog.directive.mjs +0 -179
- package/esm2022/lib/core/environments/environment.mjs +0 -15
- package/esm2022/lib/core/environments/environment.prod.mjs +0 -15
- package/esm2022/lib/core/helpers/crypto-helper.service.mjs +0 -52
- package/esm2022/lib/core/http/http-stream.service.mjs +0 -97
- package/esm2022/lib/core/http/http.service.mjs +0 -103
- package/esm2022/lib/core/interceptors/auth.interceptor.mjs +0 -96
- package/esm2022/lib/core/interceptors/license.interceptor.mjs +0 -44
- package/esm2022/lib/core/models/api-config.model.mjs +0 -18
- package/esm2022/lib/core/models/api-request.model.mjs +0 -2
- package/esm2022/lib/core/models/api-response.model.mjs +0 -8
- package/esm2022/lib/core/models/doohbot-config.model.mjs +0 -18
- package/esm2022/lib/core/models/license.model.mjs +0 -2
- package/esm2022/lib/core/models/message.mjs +0 -2
- package/esm2022/lib/core/models/theme-config.model.mjs +0 -2
- package/esm2022/lib/core/services/core-config.service.mjs +0 -52
- package/esm2022/lib/core/services/license.service.mjs +0 -145
- package/esm2022/lib/core/services/markdown.service.mjs +0 -64
- package/esm2022/lib/core/services/theme.service.mjs +0 -248
- package/esm2022/lib/core/types/auth-mode.type.mjs +0 -2
- package/esm2022/lib/core/types/auth-status.type.mjs +0 -5
- package/esm2022/lib/core/types/chat-stream.type.mjs +0 -2
- package/esm2022/lib/core/types/message-role.type.mjs +0 -2
- package/esm2022/lib/core/types/prompt-mode.type.mjs +0 -5
- package/esm2022/lib/core/types/snackbar-error.type.mjs +0 -5
- package/esm2022/lib/core/types/tenant-resolution-strategy.type.mjs +0 -2
- package/esm2022/lib/core/utils/logger.service.mjs +0 -42
- package/esm2022/lib/doohbot-input.mjs +0 -20
- package/esm2022/lib/doohbot.component.mjs +0 -444
- package/esm2022/lib/predefined_messages.mjs +0 -15
- package/esm2022/lib/shared/chips/chips.component.mjs +0 -28
- package/esm2022/lib/shared/dialog/dialog.component.mjs +0 -36
- package/esm2022/lib/shared/dialog/dialog.service.mjs +0 -64
- package/esm2022/lib/shared/dialog/dialog.utils.mjs +0 -85
- package/esm2022/lib/shared/dropdown-menu/dropdown-menu.component.mjs +0 -29
- package/esm2022/lib/shared/input-dialog/input-dialog.component.mjs +0 -38
- package/esm2022/lib/shared/menu-item/menu-item.component.mjs +0 -24
- package/esm2022/lib/shared/pipes/simple-markdown.pipe.mjs +0 -27
- package/esm2022/lib/shared/snackbar/snackbar.component.mjs +0 -43
- package/esm2022/lib/shared/snackbar/snackbar.service.mjs +0 -46
- package/esm2022/lib/shared/snackbar/snackbar.utils.mjs +0 -43
- package/esm2022/public-api.mjs +0 -37
- package/fesm2022/aakash58-chatbot.mjs +0 -5193
- package/fesm2022/aakash58-chatbot.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/lib/app/chat/chat-ui-state.service.d.ts +0 -96
- package/lib/app/chat/chat.service.d.ts +0 -88
- package/lib/app/chat/components/chat-button/chat-button.component.d.ts +0 -16
- package/lib/app/chat/components/chat-footer/chat-footer.component.d.ts +0 -5
- package/lib/app/chat/components/chat-header/chat-header.component.d.ts +0 -24
- package/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.d.ts +0 -49
- package/lib/app/chat/components/chat-window/chat-window.component.d.ts +0 -107
- package/lib/app/chat/components/message-input/message-input.component.d.ts +0 -12
- package/lib/app/chat/components/message-list/message-list.component.d.ts +0 -40
- package/lib/app/chat/model/chat-history.model.d.ts +0 -51
- package/lib/app/chat/model/chat-request.model.d.ts +0 -10
- package/lib/app/chat/model/chat-response.model.d.ts +0 -9
- package/lib/app/chat/model/chat-session.model.d.ts +0 -12
- package/lib/app/chat/model/chat-stream-response.model.d.ts +0 -10
- package/lib/app/chat/services/chat-api.service.d.ts +0 -30
- package/lib/app/chat/services/chat-audio.service.d.ts +0 -19
- package/lib/app/chat/services/chat-history.service.d.ts +0 -53
- package/lib/app/login/login-form.component.d.ts +0 -20
- package/lib/app/personalization/personalization-dialog.component.d.ts +0 -53
- package/lib/app/personalization/personalization.service.d.ts +0 -66
- package/lib/app/personalization/sections/account/account-section.component.d.ts +0 -30
- package/lib/app/personalization/sections/preferences/color-picker-dialog.component.d.ts +0 -17
- package/lib/app/personalization/sections/preferences/preferences-section.component.d.ts +0 -27
- package/lib/app/personalization/sections/profile/profile-section.component.d.ts +0 -17
- package/lib/app/personalization/sections/settings/setting-section.component.d.ts +0 -10
- package/lib/app/personalization/sections/terms/terms-section.component.d.ts +0 -5
- package/lib/constant/doohbot-constant.d.ts +0 -12
- package/lib/constant/html-entities.d.ts +0 -8
- package/lib/constant/utf8.d.ts +0 -9
- package/lib/core/app-const.d.ts +0 -11
- package/lib/core/auth/account-api.service.d.ts +0 -20
- package/lib/core/auth/auth.service.d.ts +0 -90
- package/lib/core/auth/models/auth-result.model.d.ts +0 -4
- package/lib/core/auth/models/federated-login-request.model.d.ts +0 -5
- package/lib/core/auth/models/login-request.model.d.ts +0 -6
- package/lib/core/auth/storage.service.d.ts +0 -21
- package/lib/core/directives/draggable/draggable-dialog.directive.d.ts +0 -23
- package/lib/core/directives/fullscreen/fullscreen.directive.d.ts +0 -14
- package/lib/core/directives/resizable/resizable-dialog.directive.d.ts +0 -30
- package/lib/core/environments/environment.d.ts +0 -7
- package/lib/core/environments/environment.prod.d.ts +0 -7
- package/lib/core/helpers/crypto-helper.service.d.ts +0 -12
- package/lib/core/http/http-stream.service.d.ts +0 -18
- package/lib/core/http/http.service.d.ts +0 -20
- package/lib/core/interceptors/auth.interceptor.d.ts +0 -18
- package/lib/core/interceptors/license.interceptor.d.ts +0 -11
- package/lib/core/models/api-config.model.d.ts +0 -58
- package/lib/core/models/api-request.model.d.ts +0 -77
- package/lib/core/models/api-response.model.d.ts +0 -6
- package/lib/core/models/doohbot-config.model.d.ts +0 -81
- package/lib/core/models/message.d.ts +0 -16
- package/lib/core/models/theme-config.model.d.ts +0 -28
- package/lib/core/services/core-config.service.d.ts +0 -23
- package/lib/core/services/license.service.d.ts +0 -33
- package/lib/core/services/markdown.service.d.ts +0 -8
- package/lib/core/services/theme.service.d.ts +0 -40
- package/lib/core/utils/logger.service.d.ts +0 -11
- package/lib/doohbot-input.d.ts +0 -19
- package/lib/doohbot.component.d.ts +0 -108
- package/lib/predefined_messages.d.ts +0 -2
- package/lib/shared/chips/chips.component.d.ts +0 -10
- package/lib/shared/dialog/dialog.component.d.ts +0 -19
- package/lib/shared/dialog/dialog.service.d.ts +0 -29
- package/lib/shared/dialog/dialog.utils.d.ts +0 -41
- package/lib/shared/dropdown-menu/dropdown-menu.component.d.ts +0 -11
- package/lib/shared/input-dialog/input-dialog.component.d.ts +0 -20
- package/lib/shared/menu-item/menu-item.component.d.ts +0 -9
- package/lib/shared/pipes/simple-markdown.pipe.d.ts +0 -10
- package/lib/shared/snackbar/snackbar.component.d.ts +0 -14
- package/lib/shared/snackbar/snackbar.service.d.ts +0 -19
- package/public-api.d.ts +0 -11
- /package/{src → projects/doohbot/src}/assets/bot.mp3 +0 -0
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
import { inject, Injectable, signal } from '@angular/core';
|
|
2
|
+
import { CoreConfigService } from '../services/core-config.service';
|
|
3
|
+
import { DoohbotInput } from '../../doohbot-input';
|
|
4
|
+
import {
|
|
5
|
+
BehaviorSubject,
|
|
6
|
+
map,
|
|
7
|
+
Observable,
|
|
8
|
+
catchError,
|
|
9
|
+
of,
|
|
10
|
+
tap,
|
|
11
|
+
retry,
|
|
12
|
+
throwError,
|
|
13
|
+
firstValueFrom,
|
|
14
|
+
} from 'rxjs';
|
|
15
|
+
import { AuthResult } from './models/auth-result.model';
|
|
16
|
+
import { FederatedLoginRequest } from './models/federated-login-request.model';
|
|
17
|
+
import { LoginRequest } from './models/login-request.model';
|
|
18
|
+
import { JwtHelperService } from '@auth0/angular-jwt';
|
|
19
|
+
import { CryptoHelperService } from '../helpers/crypto-helper.service';
|
|
20
|
+
import { StorageService } from './storage.service';
|
|
21
|
+
import logger from '../utils/logger.service';
|
|
22
|
+
import { AuthStatus } from '../types/auth-status.type';
|
|
23
|
+
import { AccountService } from './account-api.service';
|
|
24
|
+
import { SnackbarUtils } from './../../shared/snackbar/snackbar.utils';
|
|
25
|
+
import { DoohbotConst } from '../../constant/doohbot-constant';
|
|
26
|
+
import { Router } from '@angular/router';
|
|
27
|
+
import { LicensingContext } from '../models/license.model';
|
|
28
|
+
import { DOOHBOT_ADVANCED_CONFIG } from '../models/doohbot-config.model';
|
|
29
|
+
|
|
30
|
+
//! inherit Window storageEventAdded for duplicate tab detection
|
|
31
|
+
declare global {
|
|
32
|
+
interface Window {
|
|
33
|
+
storageEventAdded?: boolean;
|
|
34
|
+
tabCLoseEventAdded?: boolean;
|
|
35
|
+
abp?: any;
|
|
36
|
+
AppPreBootstrap?: any;
|
|
37
|
+
AppConsts?: any;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@Injectable({
|
|
42
|
+
providedIn: 'root',
|
|
43
|
+
})
|
|
44
|
+
export class AuthService {
|
|
45
|
+
get apiUrl(): string {
|
|
46
|
+
return this.coreConfig.apiUrl;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get storageKey(): string {
|
|
50
|
+
return this.coreConfig.storageKey;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get secretKey(): string {
|
|
54
|
+
return this.coreConfig.secretKey;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get companyCode(): string {
|
|
58
|
+
return this.coreConfig.companyCode;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
jwtHelper: JwtHelperService = new JwtHelperService();
|
|
62
|
+
private advancedConfig = inject(DOOHBOT_ADVANCED_CONFIG, { optional: true });
|
|
63
|
+
|
|
64
|
+
// Reactive Authentication State
|
|
65
|
+
private authStatusSubject = new BehaviorSubject<AuthStatus>('unauthenticated');
|
|
66
|
+
public authStatus$ = this.authStatusSubject.asObservable();
|
|
67
|
+
|
|
68
|
+
// UI State Signals (Merged from ChatAuthService)
|
|
69
|
+
public isLoggingIn = signal<boolean>(false);
|
|
70
|
+
public authError = signal<string | null>(null);
|
|
71
|
+
public authSuccess = signal<string | null>(null);
|
|
72
|
+
|
|
73
|
+
constructor(
|
|
74
|
+
private accountService: AccountService,
|
|
75
|
+
private cryptoHelper: CryptoHelperService,
|
|
76
|
+
private tokenStorage: StorageService,
|
|
77
|
+
private router: Router,
|
|
78
|
+
private coreConfig: CoreConfigService,
|
|
79
|
+
) {
|
|
80
|
+
// Properties are now derived from coreConfig
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Updates the service configuration from the component input
|
|
85
|
+
*/
|
|
86
|
+
public updateConfig(config: DoohbotInput): void {
|
|
87
|
+
this.coreConfig.updateConfig(config);
|
|
88
|
+
if (config.secretKey) {
|
|
89
|
+
this.cryptoHelper.setSecretKey(config.secretKey);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getLoggedInUserName(): string {
|
|
94
|
+
const username = this.tokenStorage.get('username');
|
|
95
|
+
return username || '';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
getLoggedInUserImageUrl(): string | null {
|
|
99
|
+
return DoohbotConst.userAvatar;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
getLoggedInUserRole(): string {
|
|
103
|
+
const roles = this.tokenStorage.get('roles');
|
|
104
|
+
// If roles is an array, return the first role, otherwise return the string
|
|
105
|
+
if (Array.isArray(roles) && roles.length > 0) {
|
|
106
|
+
return roles[0];
|
|
107
|
+
}
|
|
108
|
+
return roles || 'User';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Add getters for backward compatibility if needed, but preferably use authStatus$
|
|
112
|
+
public get authStatus(): AuthStatus {
|
|
113
|
+
return this.authStatusSubject.value;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Resolves a federated token from browser storage
|
|
118
|
+
*/
|
|
119
|
+
private resolveSilentToken(): string | null {
|
|
120
|
+
const config = this.coreConfig.config$();
|
|
121
|
+
const commonKeys = ['access_token', 'id_token', 'token', 'authToken'];
|
|
122
|
+
|
|
123
|
+
// 1. Try explicit authToken from config (Highest Priority)
|
|
124
|
+
if (config.authToken) {
|
|
125
|
+
logger.info(`[Auth] Using explicit authToken from input`);
|
|
126
|
+
return config.authToken;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 2. Try configured storage key from advanced config
|
|
130
|
+
if (this.advancedConfig?.autoConfigFromStorage) {
|
|
131
|
+
const key = this.advancedConfig.autoConfigFromStorage;
|
|
132
|
+
const token = localStorage.getItem(key) || sessionStorage.getItem(key);
|
|
133
|
+
if (token) {
|
|
134
|
+
logger.debug(`[Auth] Resolved token from configured key: ${key}`);
|
|
135
|
+
return token;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// 3. Try common fallback keys
|
|
140
|
+
for (const key of commonKeys) {
|
|
141
|
+
const token = localStorage.getItem(key) || sessionStorage.getItem(key);
|
|
142
|
+
if (token) {
|
|
143
|
+
logger.debug(`[Auth] Resolved token from fallback key: ${key}`);
|
|
144
|
+
return token;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Authenticate user with federated credentials
|
|
153
|
+
*/
|
|
154
|
+
async federatedLogin(
|
|
155
|
+
credentials: Partial<FederatedLoginRequest>,
|
|
156
|
+
silent: boolean = true,
|
|
157
|
+
): Promise<boolean> {
|
|
158
|
+
logger.log('>>>>>>>Attempting federated login...');
|
|
159
|
+
|
|
160
|
+
// Resolve token if not provided
|
|
161
|
+
if (!credentials.accessToken) {
|
|
162
|
+
credentials.accessToken = this.resolveSilentToken() || '';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// If still no token, exit gracefully
|
|
166
|
+
if (!credentials.accessToken) {
|
|
167
|
+
logger.log('[Auth] No federated token found in storage.');
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
this.isLoggingIn.set(true);
|
|
172
|
+
if (!silent) {
|
|
173
|
+
this.authError.set(null);
|
|
174
|
+
this.authSuccess.set(null);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
const response = await firstValueFrom(
|
|
179
|
+
this.accountService.federateLogin(credentials as FederatedLoginRequest),
|
|
180
|
+
);
|
|
181
|
+
logger.log('>>>>>>>>>>>Federated Login response<<<<<<<<<<:', response);
|
|
182
|
+
if (response && response.success && response.data) {
|
|
183
|
+
// Map federated result to something AuthService can handle
|
|
184
|
+
// Federated result: { access_token: string, remember_me: boolean }
|
|
185
|
+
const authResult = {
|
|
186
|
+
access_token: response.data.access_token,
|
|
187
|
+
refresh_token: credentials.rememberMe ? response.data.refresh_token : '',
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
this.setSession(authResult, credentials.rememberMe || false);
|
|
191
|
+
|
|
192
|
+
logger.log('Federated login successful, authenticated state set to true');
|
|
193
|
+
if (!silent) {
|
|
194
|
+
SnackbarUtils.success('Login successful!');
|
|
195
|
+
this.authSuccess.set('Login successful!');
|
|
196
|
+
}
|
|
197
|
+
this.isLoggingIn.set(false);
|
|
198
|
+
return true;
|
|
199
|
+
} else {
|
|
200
|
+
if (!silent) {
|
|
201
|
+
this.authError.set('Federated login failed.');
|
|
202
|
+
}
|
|
203
|
+
this.isLoggingIn.set(false);
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
} catch (error) {
|
|
207
|
+
logger.error('Federated login failed:', error);
|
|
208
|
+
if (!silent) {
|
|
209
|
+
this.authError.set('An error occurred during federated login.');
|
|
210
|
+
}
|
|
211
|
+
this.isLoggingIn.set(false);
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Authenticate user with credentials
|
|
218
|
+
*/
|
|
219
|
+
async login(credentials: LoginRequest, silent: boolean = false): Promise<boolean> {
|
|
220
|
+
this.isLoggingIn.set(true);
|
|
221
|
+
if (!silent) {
|
|
222
|
+
this.authError.set(null); //TODO
|
|
223
|
+
this.authSuccess.set(null);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
try {
|
|
227
|
+
const response = await firstValueFrom(this.accountService.login(credentials));
|
|
228
|
+
logger.log('>>>>>>>>>>>Login response<<<<<<<<<<:', response);
|
|
229
|
+
if (response && response.success && response.data) {
|
|
230
|
+
this.setSession(response.data, credentials.rememberMe);
|
|
231
|
+
|
|
232
|
+
logger.log('Login successful, authenticated state set to true');
|
|
233
|
+
if (!silent) {
|
|
234
|
+
this.authSuccess.set('Login successful!');
|
|
235
|
+
}
|
|
236
|
+
this.isLoggingIn.set(false);
|
|
237
|
+
return true;
|
|
238
|
+
} else {
|
|
239
|
+
if (!silent) {
|
|
240
|
+
SnackbarUtils.error('Login failed. Please check your credentials.');
|
|
241
|
+
this.authError.set('Login failed. Please check your credentials.');
|
|
242
|
+
}
|
|
243
|
+
this.isLoggingIn.set(false);
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
} catch (error) {
|
|
247
|
+
logger.error('Login failed:', error);
|
|
248
|
+
if (!silent) {
|
|
249
|
+
this.authError.set('An error occurred during login.');
|
|
250
|
+
}
|
|
251
|
+
this.isLoggingIn.set(false);
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/*
|
|
257
|
+
* Logout logic enhanced with UI signals
|
|
258
|
+
*/
|
|
259
|
+
async logout(refreshToken?: string): Promise<boolean> {
|
|
260
|
+
const token = refreshToken || this.getRefreshToken() || '';
|
|
261
|
+
|
|
262
|
+
try {
|
|
263
|
+
// If no token, just clear local state
|
|
264
|
+
if (!token) {
|
|
265
|
+
this.clearAuth();
|
|
266
|
+
this.authSuccess.set('Logged out successfully!');
|
|
267
|
+
setTimeout(() => this.authSuccess.set(null), 3000);
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const response = await firstValueFrom(this.accountService.logout(token));
|
|
272
|
+
|
|
273
|
+
if (response && response.success) {
|
|
274
|
+
this.clearAuth();
|
|
275
|
+
this.authSuccess.set('Logged out successfully!');
|
|
276
|
+
setTimeout(() => this.authSuccess.set(null), 3000);
|
|
277
|
+
return true;
|
|
278
|
+
} else {
|
|
279
|
+
this.clearAuth();
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
} catch (error) {
|
|
283
|
+
logger.error('Logout failed:', error);
|
|
284
|
+
SnackbarUtils.error('An error occurred during logout.');
|
|
285
|
+
// Force clear auth on error to ensure user isn't stuck
|
|
286
|
+
this.clearAuth();
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Utility
|
|
292
|
+
setSession(session: AuthResult, rememberMe: boolean = true) {
|
|
293
|
+
const user = this.jwtHelper.decodeToken(session.access_token);
|
|
294
|
+
|
|
295
|
+
// Set storage type based on rememberMe preference
|
|
296
|
+
this.tokenStorage.setRememberMe(rememberMe);
|
|
297
|
+
|
|
298
|
+
this.tokenStorage.set('access_token', session.access_token);
|
|
299
|
+
this.tokenStorage.set('refresh_token', session.refresh_token);
|
|
300
|
+
this.tokenStorage.set('user_id', user?.user_id);
|
|
301
|
+
this.tokenStorage.set('username', user?.username);
|
|
302
|
+
this.tokenStorage.set('roles', user?.roles);
|
|
303
|
+
this.tokenStorage.set('permissions', user?.permissions);
|
|
304
|
+
this.tokenStorage.set('organization_id', user?.organization_id);
|
|
305
|
+
this.tokenStorage.set('company_id', user?.company_id);
|
|
306
|
+
this.tokenStorage.set('office_id', user?.office_id);
|
|
307
|
+
|
|
308
|
+
// Notify subscribers
|
|
309
|
+
this.authStatusSubject.next('authenticated');
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
getOrganizationId(): string | null {
|
|
313
|
+
logger.debug('>>>>>>>>>>getOrganizationId<<<<<<<:', this.tokenStorage.get('organization_id'));
|
|
314
|
+
return this.tokenStorage.get('organization_id');
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
getRefreshToken(): string | null {
|
|
318
|
+
logger.debug('>>>>>>>>>>getRefreshToken<<<<<<<:', this.tokenStorage.get('refresh_token'));
|
|
319
|
+
return this.tokenStorage.get('refresh_token');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
refreshToken(): Observable<AuthResult> {
|
|
323
|
+
const refreshToken = this.getRefreshToken();
|
|
324
|
+
if (!refreshToken) {
|
|
325
|
+
return throwError(() => new Error('No refresh token available'));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return this.accountService.refreshLogin({ refresh_token: refreshToken }).pipe(
|
|
329
|
+
retry(3), // Retry 3 times on failure
|
|
330
|
+
tap((response: any) => {
|
|
331
|
+
if (response && response.success && response.data) {
|
|
332
|
+
this.setSession(response.data);
|
|
333
|
+
}
|
|
334
|
+
}),
|
|
335
|
+
map((response: any) => {
|
|
336
|
+
if (response && response.success && response.data) {
|
|
337
|
+
return response.data as AuthResult;
|
|
338
|
+
} else {
|
|
339
|
+
throw new Error('Token refresh failed');
|
|
340
|
+
}
|
|
341
|
+
}),
|
|
342
|
+
catchError((err) => {
|
|
343
|
+
logger.error('[Auth] Token refresh failed after retries:', err);
|
|
344
|
+
this.clearAuth();
|
|
345
|
+
SnackbarUtils.error('Session Expired. Please login.');
|
|
346
|
+
return throwError(() => err);
|
|
347
|
+
}),
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
isAuthenticated(): boolean {
|
|
352
|
+
const token = this.tokenStorage.get('access_token');
|
|
353
|
+
return !!token && !this.isTokenExpired();
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
isTokenExpired(): boolean {
|
|
357
|
+
let token = (this.tokenStorage.get('access_token') ?? '') as string;
|
|
358
|
+
if (token) {
|
|
359
|
+
return this.jwtHelper.isTokenExpired(token);
|
|
360
|
+
} else {
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Validate stored token on app startup
|
|
367
|
+
*/
|
|
368
|
+
validateStoredToken(): Observable<AuthStatus> {
|
|
369
|
+
const accessToken = this.tokenStorage.get('access_token');
|
|
370
|
+
|
|
371
|
+
//! No access token
|
|
372
|
+
if (!accessToken) {
|
|
373
|
+
//TODO: FORCE AUTHENTICATED FOR DEV
|
|
374
|
+
// this.authStatusSubject.next('authenticated');
|
|
375
|
+
// return of('authenticated');
|
|
376
|
+
|
|
377
|
+
//! For production ( Backend Validation )
|
|
378
|
+
this.authStatusSubject.next('unauthenticated');
|
|
379
|
+
return of('unauthenticated');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Access token valid
|
|
383
|
+
if (!this.isTokenExpired()) {
|
|
384
|
+
this.authStatusSubject.next('authenticated');
|
|
385
|
+
return of('authenticated');
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Access Token expired -> try refresh
|
|
389
|
+
const refreshToken = this.getRefreshToken();
|
|
390
|
+
if (!refreshToken) {
|
|
391
|
+
this.clearAuth();
|
|
392
|
+
this.authStatusSubject.next('unauthenticated');
|
|
393
|
+
return of('unauthenticated');
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
//! Access expired but refresh token exists → attempt refresh
|
|
397
|
+
this.authStatusSubject.next('expired');
|
|
398
|
+
return this.refreshToken().pipe(
|
|
399
|
+
map(() => {
|
|
400
|
+
this.authStatusSubject.next('authenticated');
|
|
401
|
+
return 'authenticated' as AuthStatus;
|
|
402
|
+
}),
|
|
403
|
+
catchError((err) => {
|
|
404
|
+
logger.error('[Auth] Token refresh failed:', err);
|
|
405
|
+
this.clearAuth();
|
|
406
|
+
this.authStatusSubject.next('unauthenticated');
|
|
407
|
+
return of('unauthenticated' as AuthStatus);
|
|
408
|
+
}),
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
getUserId() {
|
|
413
|
+
return this.tokenStorage.get('user_id') || '';
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
getLicensingContext(): LicensingContext {
|
|
417
|
+
const roles = this.tokenStorage.get('roles');
|
|
418
|
+
// Prefer company_id (specific tenant) over organization_id (system group)
|
|
419
|
+
const tenantId = this.tokenStorage.get('company_id') || this.getOrganizationId() || '';
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
tenantId: tenantId,
|
|
423
|
+
principalId: this.getUserId() || '',
|
|
424
|
+
roles: Array.isArray(roles) ? roles : roles ? [roles] : [],
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
get licenseKey(): string {
|
|
429
|
+
return this.tokenStorage.get('license_key') || this.coreConfig.licenseKey || '';
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
get isFederated(): boolean {
|
|
433
|
+
return this.licenseKey.startsWith('doohbot_lic_');
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
setLicenseKey(key: string) {
|
|
437
|
+
this.tokenStorage.set('license_key', key);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
//! clear local storage
|
|
441
|
+
/**
|
|
442
|
+
* Clear all authentication related data from local storage, session storage, cache, and tokens.
|
|
443
|
+
* This method is called when the user logs out.
|
|
444
|
+
*/
|
|
445
|
+
clearAuth() {
|
|
446
|
+
const userId = this.getUserId();
|
|
447
|
+
logger.log('[Auth] Clearing auth:', { userId });
|
|
448
|
+
|
|
449
|
+
this.clearSession();
|
|
450
|
+
this.clearStorage();
|
|
451
|
+
this.clearCache();
|
|
452
|
+
this.clearLocalStorage();
|
|
453
|
+
|
|
454
|
+
// ENSURE authStatus$ emits unauthenticated
|
|
455
|
+
this.authStatusSubject.next('unauthenticated');
|
|
456
|
+
|
|
457
|
+
logger.log('[Auth] Auth cleared successfully');
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
clearSession() {
|
|
461
|
+
sessionStorage.clear();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
clearTabInfo() {
|
|
465
|
+
localStorage.removeItem('tabs');
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
clearStorage() {
|
|
469
|
+
this.tokenStorage.clear();
|
|
470
|
+
}
|
|
471
|
+
clearLocalStorage() {
|
|
472
|
+
localStorage.clear();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
clearCache() {
|
|
476
|
+
// this.cacheService.clear();
|
|
477
|
+
}
|
|
478
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import * as CryptoJS from 'crypto-js';
|
|
3
|
+
import { CoreConfigService } from '../services/core-config.service';
|
|
4
|
+
import Logger from '../utils/logger.service';
|
|
5
|
+
|
|
6
|
+
@Injectable({
|
|
7
|
+
providedIn: 'root',
|
|
8
|
+
})
|
|
9
|
+
export class StorageService {
|
|
10
|
+
get storageKey(): string {
|
|
11
|
+
return this.coreConfig.storageKey;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
get secretKey(): string {
|
|
15
|
+
return this.coreConfig.secretKey;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private storage: Storage;
|
|
19
|
+
|
|
20
|
+
constructor(private coreConfig: CoreConfigService) {
|
|
21
|
+
// Determine initial storage
|
|
22
|
+
// If session storage has data, use it (implies remember me was false)
|
|
23
|
+
// Otherwise default/fallback to local storage
|
|
24
|
+
if (sessionStorage.getItem(this.storageKey)) {
|
|
25
|
+
this.storage = sessionStorage;
|
|
26
|
+
} else {
|
|
27
|
+
this.storage = localStorage;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
setRememberMe(rememberMe: boolean): void {
|
|
32
|
+
const currentData = this.storage.getItem(this.storageKey);
|
|
33
|
+
const targetStorage = rememberMe ? localStorage : sessionStorage;
|
|
34
|
+
|
|
35
|
+
// If storage type is changing, move data
|
|
36
|
+
if (this.storage !== targetStorage) {
|
|
37
|
+
if (currentData) {
|
|
38
|
+
targetStorage.setItem(this.storageKey, currentData);
|
|
39
|
+
this.storage.removeItem(this.storageKey);
|
|
40
|
+
}
|
|
41
|
+
this.storage = targetStorage;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
set(key: string, value: any): void {
|
|
46
|
+
const data = this.storage.getItem(this.storageKey);
|
|
47
|
+
let dataJson: any = {};
|
|
48
|
+
if (data) {
|
|
49
|
+
const dataDec = this.decrypt(data);
|
|
50
|
+
if (dataDec) {
|
|
51
|
+
dataJson = JSON.parse(dataDec);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
dataJson = Object.assign(dataJson, { [key]: value });
|
|
55
|
+
this.storage.setItem(this.storageKey, this.encrypt(JSON.stringify(dataJson)));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get(key: string): any {
|
|
59
|
+
const data = this.storage.getItem(this.storageKey);
|
|
60
|
+
if (data) {
|
|
61
|
+
const dataDec = this.decrypt(data);
|
|
62
|
+
if (dataDec) {
|
|
63
|
+
try {
|
|
64
|
+
const dataJson = JSON.parse(dataDec);
|
|
65
|
+
return dataJson![key] || null;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
Logger.error(
|
|
68
|
+
'[TokenStorage] Failed to parse decrypted data, clearing corrupt storage:',
|
|
69
|
+
e,
|
|
70
|
+
);
|
|
71
|
+
this.clear();
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
// Decrypt failed, auto-clear corrupt storage
|
|
76
|
+
Logger.error('[TokenStorage] Decrypt failed, clearing corrupt storage');
|
|
77
|
+
this.clear();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Check if storage is valid (can be decrypted) without side effects
|
|
85
|
+
*/
|
|
86
|
+
isValid(): boolean {
|
|
87
|
+
const data = this.storage.getItem(this.storageKey);
|
|
88
|
+
if (!data) return false;
|
|
89
|
+
const decrypted = this.decrypt(data);
|
|
90
|
+
return decrypted !== null && decrypted !== '';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
clear(): void {
|
|
94
|
+
// Clear both to be safe
|
|
95
|
+
localStorage.removeItem(this.storageKey);
|
|
96
|
+
sessionStorage.removeItem(this.storageKey);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private encrypt(value: string): string {
|
|
100
|
+
return CryptoJS.AES.encrypt(value, this.secretKey).toString();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private decrypt(value: string): string | null {
|
|
104
|
+
try {
|
|
105
|
+
const bytes = CryptoJS.AES.decrypt(value, this.secretKey);
|
|
106
|
+
const decrypted = bytes.toString(CryptoJS.enc.Utf8);
|
|
107
|
+
return decrypted || null;
|
|
108
|
+
} catch (e) {
|
|
109
|
+
Logger.error('[TokenStorage] Decryption error:', e);
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|