├── .editorconfig
├── .env
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .gitlab-ci.yml
├── .gitlab
└── issue_templates
│ ├── Bug.md
│ └── Issue.md
├── .prettierrc.js
├── LICENSE
├── LICENSE.md
├── README.md
├── index.html
├── maven
├── assembly
│ └── bin.xml
└── main
│ └── resources
│ └── version.properties
├── package.json
├── pom.xml
├── public
├── config
│ └── config.js
└── favicon.ico
├── src
├── App.vue
├── api.ts
├── apiv4.ts
├── assets
│ └── images
│ │ ├── app-store.svg
│ │ ├── freeotp-app-icon.png
│ │ ├── freeotp.svg
│ │ ├── google-play.svg
│ │ └── linshare-logo-white.svg
├── config.ts
├── core
│ ├── components
│ │ ├── hydrate-error.vue
│ │ ├── icons
│ │ │ ├── actor-icon.vue
│ │ │ ├── archive-icon.vue
│ │ │ ├── arrow-left-icon.vue
│ │ │ ├── arrow-right-icon.vue
│ │ │ ├── assign-icon.vue
│ │ │ ├── assign-mime-icon.vue
│ │ │ ├── building-icon.vue
│ │ │ ├── calendar-icon.vue
│ │ │ ├── cancel-cross-icon.vue
│ │ │ ├── check-circle-icon.vue
│ │ │ ├── chevron-down-fill-icon.vue
│ │ │ ├── chevron-down-icon.vue
│ │ │ ├── chevron-right-icon.vue
│ │ │ ├── close-circle-icon.vue
│ │ │ ├── close-icon.vue
│ │ │ ├── creation-icon.vue
│ │ │ ├── delete-icon.vue
│ │ │ ├── delete-mime-icon.vue
│ │ │ ├── detail-icon.vue
│ │ │ ├── document-icon.vue
│ │ │ ├── door-icon.vue
│ │ │ ├── dot-icon.vue
│ │ │ ├── edit-icon.vue
│ │ │ ├── empty-icon.vue
│ │ │ ├── file-icon.vue
│ │ │ ├── filter-icon.vue
│ │ │ ├── flag-france.vue
│ │ │ ├── flag-russia.vue
│ │ │ ├── flag-uk.vue
│ │ │ ├── flag-vn.vue
│ │ │ ├── folder-icon.vue
│ │ │ ├── globe-icon.vue
│ │ │ ├── group-domain-icon.vue
│ │ │ ├── identifier-icon.vue
│ │ │ ├── inconsistent-users.vue
│ │ │ ├── info-icon.vue
│ │ │ ├── light-bulb-icon.vue
│ │ │ ├── lock-icon.vue
│ │ │ ├── loggers-icon.vue
│ │ │ ├── menu-icon.vue
│ │ │ ├── music-icon.vue
│ │ │ ├── my-contact.vue
│ │ │ ├── my-drive.vue
│ │ │ ├── my-technical-account.vue
│ │ │ ├── my-users.vue
│ │ │ ├── newsfeed-icon.vue
│ │ │ ├── picture-icon.vue
│ │ │ ├── plus-icon.vue
│ │ │ ├── pollsquare-icon.vue
│ │ │ ├── reload-icon.vue
│ │ │ ├── replay-icon.vue
│ │ │ ├── security-icon.vue
│ │ │ ├── services-icon.vue
│ │ │ ├── sort-icon.vue
│ │ │ ├── status-icon.vue
│ │ │ ├── success-icon.vue
│ │ │ ├── switch-icon.vue
│ │ │ ├── text-icon.vue
│ │ │ ├── unlock-icon.vue
│ │ │ ├── user-add-icon.vue
│ │ │ ├── user-icon.vue
│ │ │ ├── user-profile-icon.vue
│ │ │ ├── users-icon.vue
│ │ │ ├── video-icon.vue
│ │ │ ├── view-icon.vue
│ │ │ ├── view-mimes-icon.vue
│ │ │ └── warning-icon.vue
│ │ ├── language-selector.vue
│ │ ├── ls-language-modal.vue
│ │ ├── ls
│ │ │ ├── ls-alert.vue
│ │ │ ├── ls-button.vue
│ │ │ ├── ls-collapse-panel.vue
│ │ │ ├── ls-collapse.vue
│ │ │ ├── ls-domain-treeview.vue
│ │ │ ├── ls-modal.vue
│ │ │ └── ls-tag.vue
│ │ ├── moderator-select.vue
│ │ ├── otp-input.vue
│ │ ├── page-title.vue
│ │ ├── size-input.vue
│ │ ├── the-copyright.vue
│ │ ├── the-footer.vue
│ │ ├── the-header.vue
│ │ ├── the-menu.vue
│ │ ├── the-mobile-menu.vue
│ │ ├── the-mobile-profile.vue
│ │ ├── the-pagination.vue
│ │ ├── the-profile.vue
│ │ ├── the-subheader.vue
│ │ ├── token-input.vue
│ │ └── user-select.vue
│ ├── constants
│ │ ├── api-errors.ts
│ │ ├── breakpoint.ts
│ │ ├── emails.ts
│ │ ├── index.ts
│ │ ├── languages.ts
│ │ ├── pagination.ts
│ │ └── permissions.ts
│ ├── hooks
│ │ ├── useAdministrationPage.ts
│ │ ├── useAntConfig.ts
│ │ ├── useBreadcrumbs.ts
│ │ ├── useConfigurationPages.ts
│ │ ├── useLanguageModal.ts
│ │ ├── useLegacyFeatures.ts
│ │ ├── useMenu.ts
│ │ ├── useNotification.ts
│ │ ├── useProfile.ts
│ │ ├── useRelativeTime.ts
│ │ └── useUpgradeTaskPage.ts
│ ├── layouts
│ │ ├── administration-page.vue
│ │ ├── home-page.vue
│ │ └── upgrade-page.vue
│ ├── pages
│ │ └── configuration-entries.vue
│ ├── plugins
│ │ ├── antd
│ │ │ └── index.ts
│ │ └── i18n
│ │ │ ├── formats.ts
│ │ │ ├── index.ts
│ │ │ └── locales
│ │ │ ├── en.json
│ │ │ ├── fr.json
│ │ │ ├── index.ts
│ │ │ ├── ru.json
│ │ │ └── vi.json
│ ├── router
│ │ ├── coreRoutes.ts
│ │ ├── index.ts
│ │ └── routes.ts
│ ├── services
│ │ ├── I18nService.ts
│ │ └── configuration-pages.ts
│ ├── store
│ │ ├── hydrate.ts
│ │ └── index.ts
│ ├── styles
│ │ ├── fonts
│ │ │ └── Inter
│ │ │ │ ├── Inter-Black.woff
│ │ │ │ ├── Inter-Black.woff2
│ │ │ │ ├── Inter-BlackItalic.woff
│ │ │ │ ├── Inter-BlackItalic.woff2
│ │ │ │ ├── Inter-Bold.woff
│ │ │ │ ├── Inter-Bold.woff2
│ │ │ │ ├── Inter-BoldItalic.woff
│ │ │ │ ├── Inter-BoldItalic.woff2
│ │ │ │ ├── Inter-ExtraBold.woff
│ │ │ │ ├── Inter-ExtraBold.woff2
│ │ │ │ ├── Inter-ExtraBoldItalic.woff
│ │ │ │ ├── Inter-ExtraBoldItalic.woff2
│ │ │ │ ├── Inter-ExtraLight.woff
│ │ │ │ ├── Inter-ExtraLight.woff2
│ │ │ │ ├── Inter-ExtraLightItalic.woff
│ │ │ │ ├── Inter-ExtraLightItalic.woff2
│ │ │ │ ├── Inter-Italic.woff
│ │ │ │ ├── Inter-Italic.woff2
│ │ │ │ ├── Inter-Light.woff
│ │ │ │ ├── Inter-Light.woff2
│ │ │ │ ├── Inter-LightItalic.woff
│ │ │ │ ├── Inter-LightItalic.woff2
│ │ │ │ ├── Inter-Medium.woff
│ │ │ │ ├── Inter-Medium.woff2
│ │ │ │ ├── Inter-MediumItalic.woff
│ │ │ │ ├── Inter-MediumItalic.woff2
│ │ │ │ ├── Inter-Regular.woff
│ │ │ │ ├── Inter-Regular.woff2
│ │ │ │ ├── Inter-SemiBold.woff
│ │ │ │ ├── Inter-SemiBold.woff2
│ │ │ │ ├── Inter-SemiBoldItalic.woff
│ │ │ │ ├── Inter-SemiBoldItalic.woff2
│ │ │ │ ├── Inter-Thin.woff
│ │ │ │ ├── Inter-Thin.woff2
│ │ │ │ ├── Inter-ThinItalic.woff
│ │ │ │ ├── Inter-ThinItalic.woff2
│ │ │ │ ├── Inter-italic.var.woff2
│ │ │ │ ├── Inter-roman.var.woff2
│ │ │ │ ├── Inter.var.woff2
│ │ │ │ └── inter.less
│ │ ├── main.less
│ │ └── variables.less
│ ├── types
│ │ ├── APIError.ts
│ │ ├── AppConfiguration.ts
│ │ ├── Domain.ts
│ │ ├── Filters.ts
│ │ ├── PaginatedList.ts
│ │ ├── Sort.ts
│ │ ├── Status.ts
│ │ ├── TimePeriod.ts
│ │ └── Unit.ts
│ └── utils
│ │ ├── date.ts
│ │ ├── functionality.ts
│ │ ├── is-email.ts
│ │ └── unitStorage.ts
├── env.d.ts
├── main.ts
├── modules
│ ├── activities
│ │ ├── components
│ │ │ ├── README.md
│ │ │ ├── activities-data-table.vue
│ │ │ ├── activities-filters-list.vue
│ │ │ └── activities-filters-modal.vue
│ │ ├── hooks
│ │ │ ├── README.md
│ │ │ └── use-activities.ts
│ │ ├── layouts
│ │ │ └── activities-layout.vue
│ │ ├── pages
│ │ │ ├── README.md
│ │ │ └── index-page.vue
│ │ ├── router
│ │ │ ├── README.md
│ │ │ └── index.ts
│ │ ├── services
│ │ │ ├── README.md
│ │ │ └── index.ts
│ │ ├── store
│ │ │ ├── README.md
│ │ │ └── index.ts
│ │ └── types
│ │ │ ├── README.md
│ │ │ └── index.ts
│ ├── administration
│ │ ├── pages
│ │ │ ├── contact-list
│ │ │ │ ├── components
│ │ │ │ │ ├── contact-list-actions.vue
│ │ │ │ │ ├── contact-list-table.vue
│ │ │ │ │ ├── delete-contact-card.vue
│ │ │ │ │ ├── delete-contact-fail-card.vue
│ │ │ │ │ └── detail-page
│ │ │ │ │ │ ├── contact-list-detail-action.vue
│ │ │ │ │ │ ├── contact-list-detail-card.vue
│ │ │ │ │ │ ├── contact-list-detail-header.vue
│ │ │ │ │ │ ├── contact-list-email-table.vue
│ │ │ │ │ │ └── delete-mail-card.vue
│ │ │ │ ├── hooks
│ │ │ │ │ └── useContactList.ts
│ │ │ │ ├── pages
│ │ │ │ │ ├── contact-list-detail-page.vue
│ │ │ │ │ ├── contact-list-page.vue
│ │ │ │ │ └── entries-page.vue
│ │ │ │ ├── router
│ │ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── contact-list-api.ts
│ │ │ │ └── types
│ │ │ │ │ └── Contact.ts
│ │ │ ├── entries-page.vue
│ │ │ └── technical-accounts
│ │ │ │ ├── components
│ │ │ │ ├── create-technical-account-card.vue
│ │ │ │ ├── delete-technical-account-card.vue
│ │ │ │ ├── detail-page
│ │ │ │ │ ├── change-password-tab.vue
│ │ │ │ │ ├── system-information-card.vue
│ │ │ │ │ ├── technical-account-informations.vue
│ │ │ │ │ ├── technical-account-permission-table.vue
│ │ │ │ │ └── user-informations.vue
│ │ │ │ └── technical-accounts-table.vue
│ │ │ │ ├── hooks
│ │ │ │ └── useTechnicalAccount.ts
│ │ │ │ ├── pages
│ │ │ │ ├── entries-page.vue
│ │ │ │ ├── technical-account-detail.vue
│ │ │ │ └── technical-accounts.vue
│ │ │ │ ├── router
│ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ └── technical-account-api.ts
│ │ │ │ └── types
│ │ │ │ └── TechnicalAccount.ts
│ │ └── router
│ │ │ └── index.ts
│ ├── auth
│ │ ├── components
│ │ │ ├── key-creation.vue
│ │ │ ├── key-removal.vue
│ │ │ ├── oidc-callback.vue
│ │ │ └── otp-setup-hint.vue
│ │ ├── constants
│ │ │ └── index.ts
│ │ ├── hooks
│ │ │ ├── use2FARequiredCheck.ts
│ │ │ └── useChangePassword.ts
│ │ ├── pages
│ │ │ ├── login-page.vue
│ │ │ ├── login-second-factor.vue
│ │ │ ├── manage-change-password.vue
│ │ │ └── manage-second-factor-authentication.vue
│ │ ├── router
│ │ │ ├── index.ts
│ │ │ ├── requiresAuth.guard.ts
│ │ │ └── requiresSecondFAEnabled.ts
│ │ ├── services
│ │ │ ├── auth-api.ts
│ │ │ ├── basic.ts
│ │ │ └── oidc.ts
│ │ ├── store
│ │ │ ├── auth2FAstore.ts
│ │ │ └── index.ts
│ │ └── types
│ │ │ ├── ChangePassword.ts
│ │ │ ├── OtpSetupHintConfigs.ts
│ │ │ └── SecondFactorAuthentication.ts
│ ├── configuration
│ │ ├── components
│ │ │ ├── config-domain-actions.vue
│ │ │ ├── configuration-tabs.vue
│ │ │ └── select-domain-modal.vue
│ │ ├── layouts
│ │ │ └── configuration-layout.vue
│ │ ├── pages
│ │ │ ├── detail
│ │ │ │ ├── components
│ │ │ │ │ └── domain-form.vue
│ │ │ │ ├── pages
│ │ │ │ │ └── detail-page.vue
│ │ │ │ └── router
│ │ │ │ │ └── index.ts
│ │ │ ├── domain-group-providers
│ │ │ │ ├── components
│ │ │ │ │ └── readme.md
│ │ │ │ ├── composables
│ │ │ │ │ └── readme.md
│ │ │ │ ├── hooks
│ │ │ │ │ └── readme.md
│ │ │ │ ├── pages
│ │ │ │ │ ├── group-providers-page.vue
│ │ │ │ │ └── readme.md
│ │ │ │ ├── router
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── readme.md
│ │ │ │ ├── services
│ │ │ │ │ └── readme.md
│ │ │ │ └── types
│ │ │ │ │ └── readme.md
│ │ │ ├── domain-policies
│ │ │ │ ├── components
│ │ │ │ │ ├── assign-domain-policy-card.vue
│ │ │ │ │ ├── creation-domain-policy-modal.vue
│ │ │ │ │ ├── delete-domain-policies-card.vue
│ │ │ │ │ ├── delete-domain-policy-card.vue
│ │ │ │ │ ├── delete-domain-policy-fail-card.vue
│ │ │ │ │ ├── detail-page
│ │ │ │ │ │ ├── domain-policy-detail-action.vue
│ │ │ │ │ │ ├── domain-policy-detail-card.vue
│ │ │ │ │ │ ├── domain-policy-detail-header.vue
│ │ │ │ │ │ └── domain-policy-rules-table.vue
│ │ │ │ │ ├── domain-policy-actions.vue
│ │ │ │ │ ├── domain-policy-table.vue
│ │ │ │ │ └── duplicate-domain-policy-card.vue
│ │ │ │ ├── hooks
│ │ │ │ │ └── useDomainPolicies.ts
│ │ │ │ ├── pages
│ │ │ │ │ ├── policies-page.vue
│ │ │ │ │ └── policy-detail-page.vue
│ │ │ │ ├── router
│ │ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── domain-policies-api.ts
│ │ │ │ └── types
│ │ │ │ │ └── DomainPolicy.ts
│ │ │ ├── domain-provider-management
│ │ │ │ ├── components
│ │ │ │ │ └── readme.md
│ │ │ │ ├── composables
│ │ │ │ │ └── readme.md
│ │ │ │ ├── hooks
│ │ │ │ │ └── readme.md
│ │ │ │ ├── pages
│ │ │ │ │ ├── domain-provider-management-page.vue
│ │ │ │ │ └── readme.md
│ │ │ │ ├── router
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── readme.md
│ │ │ │ ├── services
│ │ │ │ │ └── readme.md
│ │ │ │ └── types
│ │ │ │ │ └── readme.md
│ │ │ ├── domain-user-providers
│ │ │ │ ├── components
│ │ │ │ │ └── readme.md
│ │ │ │ ├── composables
│ │ │ │ │ └── readme.md
│ │ │ │ ├── hooks
│ │ │ │ │ └── readme.md
│ │ │ │ ├── pages
│ │ │ │ │ ├── domain-user-providers-page.vue
│ │ │ │ │ └── readme.md
│ │ │ │ ├── router
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── readme.md
│ │ │ │ ├── services
│ │ │ │ │ └── readme.md
│ │ │ │ └── types
│ │ │ │ │ └── readme.md
│ │ │ ├── domain-workspace-providers
│ │ │ │ ├── components
│ │ │ │ │ └── readme.md
│ │ │ │ ├── composables
│ │ │ │ │ └── readme.md
│ │ │ │ ├── hooks
│ │ │ │ │ └── readme.md
│ │ │ │ ├── pages
│ │ │ │ │ ├── domain-workspace-providers-page.vue
│ │ │ │ │ └── readme.md
│ │ │ │ ├── router
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── readme.md
│ │ │ │ ├── services
│ │ │ │ │ └── readme.md
│ │ │ │ └── types
│ │ │ │ │ └── readme.md
│ │ │ ├── email-templates
│ │ │ │ ├── components
│ │ │ │ │ ├── email-activation
│ │ │ │ │ │ ├── email-activation-actions.vue
│ │ │ │ │ │ ├── email-activation-detail.vue
│ │ │ │ │ │ └── email-activation-table.vue
│ │ │ │ │ ├── email-configuration
│ │ │ │ │ │ ├── assign-mail-configuration-card.vue
│ │ │ │ │ │ ├── create-mail-configuration-card.vue
│ │ │ │ │ │ ├── delete-mail-configuration-card.vue
│ │ │ │ │ │ ├── delete-mail-configurations-card.vue
│ │ │ │ │ │ ├── delete-mail-configurations-fail-card.vue
│ │ │ │ │ │ ├── detail-page
│ │ │ │ │ │ │ ├── email-configuration-content-table.vue
│ │ │ │ │ │ │ ├── email-configuration-detail-action.vue
│ │ │ │ │ │ │ ├── email-configuration-detail-card.vue
│ │ │ │ │ │ │ ├── email-configuration-detail-header.vue
│ │ │ │ │ │ │ └── system-information-card.vue
│ │ │ │ │ │ ├── mail-configuration-actions.vue
│ │ │ │ │ │ └── mail-configuration-table.vue
│ │ │ │ │ ├── email-content
│ │ │ │ │ │ ├── create-mail-content-card.vue
│ │ │ │ │ │ ├── delete-mail-content-card.vue
│ │ │ │ │ │ ├── delete-mail-contents-card.vue
│ │ │ │ │ │ ├── delete-mail-contents-fail-card.vue
│ │ │ │ │ │ ├── detail-page
│ │ │ │ │ │ │ ├── email-content-detail-actions.vue
│ │ │ │ │ │ │ ├── email-content-detail-card.vue
│ │ │ │ │ │ │ ├── email-content-detail-header.vue
│ │ │ │ │ │ │ ├── email-content-information-card.vue
│ │ │ │ │ │ │ └── email-content-preview-card.vue
│ │ │ │ │ │ ├── email-content-actions.vue
│ │ │ │ │ │ └── email-content-table.vue
│ │ │ │ │ ├── email-footer
│ │ │ │ │ │ ├── create-mail-footer-card.vue
│ │ │ │ │ │ ├── delete-mail-footer-card.vue
│ │ │ │ │ │ ├── delete-mail-footers-card.vue
│ │ │ │ │ │ ├── delete-mail-footers-fail-card.vue
│ │ │ │ │ │ ├── detail-page
│ │ │ │ │ │ │ ├── email-footer-detail-actions.vue
│ │ │ │ │ │ │ ├── email-footer-detail-card.vue
│ │ │ │ │ │ │ ├── email-footer-detail-header.vue
│ │ │ │ │ │ │ └── email-footer-information-card.vue
│ │ │ │ │ │ ├── email-footer-actions.vue
│ │ │ │ │ │ └── email-footer-table.vue
│ │ │ │ │ ├── email-layout
│ │ │ │ │ │ ├── delete-mail-layout-card.vue
│ │ │ │ │ │ ├── delete-mail-layouts-card.vue
│ │ │ │ │ │ ├── delete-mail-layouts-fail-card.vue
│ │ │ │ │ │ ├── detail-page
│ │ │ │ │ │ │ ├── email-layout-detail-actions.vue
│ │ │ │ │ │ │ ├── email-layout-detail-card.vue
│ │ │ │ │ │ │ ├── email-layout-detail-header.vue
│ │ │ │ │ │ │ └── email-layout-information-card.vue
│ │ │ │ │ │ ├── email-layout-creation-modal.vue
│ │ │ │ │ │ ├── email-layout-table.vue
│ │ │ │ │ │ └── mail-layout-actions.vue
│ │ │ │ │ └── email-templates-vertical-tabs.vue
│ │ │ │ ├── hooks
│ │ │ │ │ ├── useEmailTemplatesActivation.ts
│ │ │ │ │ ├── useEmailTemplatesConfiguration.ts
│ │ │ │ │ ├── useEmailTemplatesContent.ts
│ │ │ │ │ ├── useEmailTemplatesFooter.ts
│ │ │ │ │ └── useEmailTemplatesLayout.ts
│ │ │ │ ├── pages
│ │ │ │ │ ├── activation-page.vue
│ │ │ │ │ ├── configuration-detail-page.vue
│ │ │ │ │ ├── configuration-page.vue
│ │ │ │ │ ├── content-detail-page.vue
│ │ │ │ │ ├── content-page.vue
│ │ │ │ │ ├── entries-page.vue
│ │ │ │ │ ├── footer-detail-page.vue
│ │ │ │ │ ├── footer-page.vue
│ │ │ │ │ ├── layout-detail-page.vue
│ │ │ │ │ └── layout-page.vue
│ │ │ │ ├── router
│ │ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── email-templates-api.ts
│ │ │ │ ├── types
│ │ │ │ │ ├── MailActivation.ts
│ │ │ │ │ ├── MailConfiguration.ts
│ │ │ │ │ ├── MailContent.ts
│ │ │ │ │ ├── MailContext.ts
│ │ │ │ │ ├── MailFooter.ts
│ │ │ │ │ └── MailLayout.ts
│ │ │ │ └── utils
│ │ │ │ │ └── mail-content-types.ts
│ │ │ ├── index-page.vue
│ │ │ ├── parameters
│ │ │ │ ├── components
│ │ │ │ │ ├── domain-functionality-details.vue
│ │ │ │ │ └── domain-functionality.vue
│ │ │ │ ├── hooks
│ │ │ │ │ └── useFunctionalities.ts
│ │ │ │ ├── pages
│ │ │ │ │ └── parameters-page.vue
│ │ │ │ ├── router
│ │ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── parameters-api.ts
│ │ │ │ └── types
│ │ │ │ │ └── Functionality.ts
│ │ │ ├── providers
│ │ │ │ ├── components
│ │ │ │ │ ├── domain-group-provider-ldap-form.vue
│ │ │ │ │ ├── domain-group-providers.vue
│ │ │ │ │ ├── domain-management-warning.vue
│ │ │ │ │ ├── domain-provider-management.vue
│ │ │ │ │ ├── domain-user-provider-ldap-form.vue
│ │ │ │ │ ├── domain-user-provider-oidc-form.vue
│ │ │ │ │ ├── domain-user-provider-twake-form.vue
│ │ │ │ │ ├── domain-user-providers.vue
│ │ │ │ │ ├── domain-workspace-provider-ldap-form.vue
│ │ │ │ │ └── domain-workspace-providers.vue
│ │ │ │ ├── hooks
│ │ │ │ │ └── use-providers.ts
│ │ │ │ ├── pages
│ │ │ │ │ └── providers-page.vue
│ │ │ │ ├── router
│ │ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── providers-api.ts
│ │ │ │ └── types
│ │ │ │ │ ├── Domain.ts
│ │ │ │ │ ├── GroupProvider.ts
│ │ │ │ │ ├── UserProvider.ts
│ │ │ │ │ └── WorkspaceProvider.ts
│ │ │ ├── public-keys
│ │ │ │ ├── components
│ │ │ │ │ └── readme.md
│ │ │ │ ├── composables
│ │ │ │ │ └── readme.md
│ │ │ │ ├── hooks
│ │ │ │ │ └── readme.md
│ │ │ │ ├── pages
│ │ │ │ │ ├── public-keys-page.vue
│ │ │ │ │ └── readme.md
│ │ │ │ ├── router
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── readme.md
│ │ │ │ ├── services
│ │ │ │ │ └── readme.md
│ │ │ │ └── types
│ │ │ │ │ └── readme.md
│ │ │ ├── quota
│ │ │ │ ├── components
│ │ │ │ │ ├── allocation-within-the-current-domain.vue
│ │ │ │ │ ├── domain-quota-and-used-space.vue
│ │ │ │ │ ├── quota-doughnut-chart.vue
│ │ │ │ │ ├── quota-input.vue
│ │ │ │ │ ├── quota-visualize.vue
│ │ │ │ │ └── subdomains-allocation-settings.vue
│ │ │ │ ├── hooks
│ │ │ │ │ └── useQuota.ts
│ │ │ │ ├── pages
│ │ │ │ │ └── quota-page.vue
│ │ │ │ ├── router
│ │ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── quota-api.ts
│ │ │ │ └── types
│ │ │ │ │ ├── Container.ts
│ │ │ │ │ └── Quota.ts
│ │ │ ├── remote-filters
│ │ │ │ ├── components
│ │ │ │ │ ├── group-filter-ldap.vue
│ │ │ │ │ ├── group-filters-list.vue
│ │ │ │ │ ├── user-filter-ldap.vue
│ │ │ │ │ ├── user-filters-list.vue
│ │ │ │ │ ├── workspace-filter-ldap.vue
│ │ │ │ │ └── workspace-filters-list.vue
│ │ │ │ ├── composables
│ │ │ │ │ └── readme.md
│ │ │ │ ├── hooks
│ │ │ │ │ └── readme.md
│ │ │ │ ├── pages
│ │ │ │ │ └── remote-filters-page.vue
│ │ │ │ ├── router
│ │ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ │ ├── group-filter-api.ts
│ │ │ │ │ ├── user-filter-api.ts
│ │ │ │ │ └── workspace-filter-api.ts
│ │ │ │ └── types
│ │ │ │ │ ├── GroupFilters.ts
│ │ │ │ │ ├── UserFilter.ts
│ │ │ │ │ └── WorkspaceFilters.ts
│ │ │ ├── remote-servers
│ │ │ │ ├── components
│ │ │ │ │ ├── remote-server-ldap-modal.vue
│ │ │ │ │ └── remote-server-twake-modal.vue
│ │ │ │ ├── hooks
│ │ │ │ │ └── readme.md
│ │ │ │ ├── pages
│ │ │ │ │ └── remote-servers-page.vue
│ │ │ │ ├── router
│ │ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── remote-server-api.ts
│ │ │ │ └── types
│ │ │ │ │ └── RemoteServer.ts
│ │ │ ├── type-mime-policies
│ │ │ │ ├── components
│ │ │ │ │ ├── assign-mime-policy-card.vue
│ │ │ │ │ ├── delete-mime-policies-card.vue
│ │ │ │ │ ├── delete-mime-policies-fail-card.vue
│ │ │ │ │ ├── delete-mime-policy-card.vue
│ │ │ │ │ ├── detail-page
│ │ │ │ │ │ ├── mime-detail-card.vue
│ │ │ │ │ │ ├── mime-detail-header.vue
│ │ │ │ │ │ ├── mime-system-information.vue
│ │ │ │ │ │ ├── mime-type-options.vue
│ │ │ │ │ │ └── mime-types-table.vue
│ │ │ │ │ ├── mime-policies-actions.vue
│ │ │ │ │ ├── mime-policies-creation-modal.vue
│ │ │ │ │ └── mime-policies-table.vue
│ │ │ │ ├── hooks
│ │ │ │ │ └── useMimePolicies.ts
│ │ │ │ ├── pages
│ │ │ │ │ ├── mime-policy-detail-page.vue
│ │ │ │ │ └── type-mime-policies-page.vue
│ │ │ │ ├── router
│ │ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ │ └── mime-policies-api.ts
│ │ │ │ └── types
│ │ │ │ │ └── MimeType.ts
│ │ │ └── welcome-messages
│ │ │ │ ├── components
│ │ │ │ ├── domain-welcome-message-form.vue
│ │ │ │ ├── domain-welcome-message.vue
│ │ │ │ ├── domain-welcome-messages-large-table.vue
│ │ │ │ └── domain-welcome-messages-small-table.vue
│ │ │ │ ├── composables
│ │ │ │ └── readme.md
│ │ │ │ ├── hooks
│ │ │ │ └── useWelcomeMessages.ts
│ │ │ │ ├── pages
│ │ │ │ └── welcome-messages-page.vue
│ │ │ │ ├── router
│ │ │ │ └── index.ts
│ │ │ │ ├── services
│ │ │ │ └── welcome-messages-api.ts
│ │ │ │ └── types
│ │ │ │ └── WelcomeMessages.ts
│ │ └── router
│ │ │ └── index.ts
│ ├── design-system
│ │ ├── pages
│ │ │ ├── data-entry-page.vue
│ │ │ ├── feedback-page.vue
│ │ │ ├── form-page.vue
│ │ │ ├── general-page.vue
│ │ │ ├── index-page.vue
│ │ │ └── navigation-page.vue
│ │ └── router
│ │ │ └── index.ts
│ ├── domain
│ │ ├── components
│ │ │ ├── domain-associated-list-modal.vue
│ │ │ ├── domain-creation-form-modal.vue
│ │ │ ├── domain-functionalities-list.vue
│ │ │ ├── domain-functionality-details.vue
│ │ │ ├── domain-functionality.vue
│ │ │ ├── domains-tree-node.vue
│ │ │ └── domains-tree.vue
│ │ ├── hooks
│ │ │ ├── useAssociatedDomainsModal.ts
│ │ │ ├── useDomainDelete.ts
│ │ │ └── useFunctionalities.ts
│ │ ├── pages
│ │ │ ├── domain-page.vue
│ │ │ └── domain-providers-page.vue
│ │ ├── router
│ │ │ ├── index.ts
│ │ │ ├── requiresDomainAccessibility.ts
│ │ │ └── requiresDomainUpdate.ts
│ │ ├── services
│ │ │ └── domain-api.ts
│ │ ├── store
│ │ │ └── index.ts
│ │ └── types
│ │ │ ├── Domain.ts
│ │ │ └── DomainTreeNode.ts
│ ├── inconsistent-users
│ │ ├── components
│ │ │ ├── inconsistent-users-list.vue
│ │ │ ├── inconsistent-users-migration-modal.vue
│ │ │ ├── inconsistent-users-tabs.vue
│ │ │ ├── profil-creation-modal.vue
│ │ │ ├── user-diagnostic-quota.vue
│ │ │ ├── users-diagnostic-detail-card.vue
│ │ │ └── users-diagnostic-table.vue
│ │ ├── hooks
│ │ │ ├── useInconsistentUsers.ts
│ │ │ └── useUsersDiagnostic.ts
│ │ ├── pages
│ │ │ ├── entries-page.vue
│ │ │ ├── inconsistent-users-entries-page.vue
│ │ │ ├── manage-diagnostic-users.vue
│ │ │ └── manage-inconsistent-users.vue
│ │ ├── router
│ │ │ └── index.ts
│ │ ├── services
│ │ │ └── inconsistent-users-api.ts
│ │ ├── store
│ │ │ └── index.ts
│ │ └── types
│ │ │ ├── InconsistentUsers.ts
│ │ │ └── UserDiagnotic.ts
│ ├── password
│ │ └── router
│ │ │ └── index.ts
│ ├── reporting
│ │ ├── components
│ │ │ ├── human-mime-type-icon.vue
│ │ │ ├── mime-type-statistic.vue
│ │ │ ├── reporting-filters-list.vue
│ │ │ ├── reporting-filters-modal.vue
│ │ │ ├── reporting-page.vue
│ │ │ ├── reporting-shares-filters-list.vue
│ │ │ ├── reporting-shares-filters-modal.vue
│ │ │ ├── reporting-shares-page.vue
│ │ │ ├── reporting-statistic-files-quantity.vue
│ │ │ ├── reporting-statistic-generics-list.vue
│ │ │ ├── reporting-statistic-generics-table.vue
│ │ │ ├── reporting-statistic-generics.vue
│ │ │ ├── reporting-statistic-most-uploaded.vue
│ │ │ ├── reporting-statistic-storage-consumption.vue
│ │ │ ├── reporting-statistic-summary.vue
│ │ │ ├── reporting-statistic-total-storage.vue
│ │ │ ├── reporting-statistic-user-used-storage-table.vue
│ │ │ ├── reporting-statistic-user-used-storage.vue
│ │ │ ├── reporting-storage-page.vue
│ │ │ ├── top-shares-by-file-count.vue
│ │ │ └── top-shares-by-file-size.vue
│ │ ├── constants
│ │ │ └── human-mime-type-color.ts
│ │ ├── hooks
│ │ │ ├── useMimeType.ts
│ │ │ ├── useStorageConsumption.ts
│ │ │ ├── useTopSharesFiles.ts
│ │ │ └── useTopSharesFilesSize.ts
│ │ ├── router
│ │ │ └── index.ts
│ │ ├── services
│ │ │ └── statistic-api.ts
│ │ ├── store
│ │ │ └── index.ts
│ │ └── types
│ │ │ ├── AccountQuotaStatistic.ts
│ │ │ ├── GenericStatistic.ts
│ │ │ ├── MimeTypeStatistic.ts
│ │ │ ├── StorageConsumptionStatistic.ts
│ │ │ ├── TopSharesFileCount.ts
│ │ │ └── TopSharesFileSize.ts
│ ├── shared-spaces
│ │ ├── components
│ │ │ ├── member-large-table.vue
│ │ │ ├── member-small-table.vue
│ │ │ ├── shared-space-details.vue
│ │ │ ├── shared-space-member-role-modal.vue
│ │ │ ├── shared-space-members-add-modal.vue
│ │ │ ├── shared-space-members-list-item.vue
│ │ │ ├── shared-space-members-list.vue
│ │ │ ├── shared-space-role-select.vue
│ │ │ ├── shared-spaces-list.vue
│ │ │ ├── workgroup-icon.vue
│ │ │ └── workspace-icon.vue
│ │ ├── hooks
│ │ │ ├── useSharedSpaceMemberList.ts
│ │ │ └── useSharedSpacesList.ts
│ │ ├── pages
│ │ │ ├── entries-page.vue
│ │ │ └── manage-shared-spaces.vue
│ │ ├── router
│ │ │ └── index.ts
│ │ ├── services
│ │ │ └── shared-space-api.ts
│ │ ├── store
│ │ │ └── index.ts
│ │ └── types
│ │ │ ├── ShareSpaceList.ts
│ │ │ ├── SharedSpace.ts
│ │ │ ├── SharedSpaceAccount.ts
│ │ │ ├── SharedSpaceMember.ts
│ │ │ └── SharedSpaceRole.ts
│ ├── upgrades
│ │ ├── components
│ │ │ ├── async-task-table.vue
│ │ │ ├── retry-upgrade-task-card.vue
│ │ │ ├── upgrade-list-actions.vue
│ │ │ └── upgrade-list-table.vue
│ │ ├── hooks
│ │ │ └── useUpgradeTasks.ts
│ │ ├── pages
│ │ │ ├── upgrade-console.vue
│ │ │ ├── upgrade-list-detail-page.vue
│ │ │ └── upgrade-list-page.vue
│ │ ├── router
│ │ │ └── index.ts
│ │ ├── services
│ │ │ └── upgrade-task-api.ts
│ │ └── types
│ │ │ └── UpgradeTask.ts
│ └── user
│ │ ├── components
│ │ ├── account-autocomplete-item.vue
│ │ ├── current-user-guests-small-table.vue
│ │ ├── current-user-guests.vue
│ │ ├── guest-moderator-add-modal.vue
│ │ ├── large-table.vue
│ │ ├── search-form.vue
│ │ ├── small-table.vue
│ │ ├── user-guest-moderators.vue
│ │ ├── user-locked-alert.vue
│ │ ├── user-personal-space-quota.vue
│ │ ├── user-profile.vue
│ │ ├── user-restricted-contacts.vue
│ │ └── user-shared-key-alert.vue
│ │ ├── hooks
│ │ ├── useGuest.ts
│ │ ├── useGuestList.ts
│ │ └── useUsersList.ts
│ │ ├── pages
│ │ ├── entries-page.vue
│ │ ├── manage-users.vue
│ │ └── user-detail.vue
│ │ ├── router
│ │ └── index.ts
│ │ ├── services
│ │ ├── guest-api.ts
│ │ ├── user-api.ts
│ │ └── user-utils.ts
│ │ └── types
│ │ ├── GuestList.ts
│ │ ├── GuestModerator.ts
│ │ ├── RestrictedContact.ts
│ │ ├── User.ts
│ │ ├── UserQuota.ts
│ │ └── UsersList.ts
├── router.d.ts
├── shims-vue.d.ts
└── window.d.ts
├── tsconfig.json
└── vite.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | trim_trailing_whitespace = true
5 | insert_final_newline = true
6 |
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | BACKEND_API_URL = 'https://admin.linshare-dev-on-commit.integration-linshare.org'
2 | ACCESS_TOKEN='7cQx7y-pw-WnXfHSNngm'
3 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | node
4 | maven
5 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const defaultRules = {
2 | 'no-debugger': process.env.NODE_ENV !== 'development' ? 'error' : 'off',
3 | 'prettier/prettier': 'error',
4 | };
5 |
6 | module.exports = {
7 | root: true,
8 | env: {
9 | browser: true,
10 | node: true,
11 | },
12 | plugins: ['@typescript-eslint', 'prettier'],
13 | extends: ['eslint:recommended', 'prettier'],
14 | rules: defaultRules,
15 | parserOptions: {
16 | ecmaVersion: 2020,
17 | },
18 | overrides: [
19 | {
20 | files: ['vite.config.js'],
21 | parserOptions: {
22 | sourceType: 'module',
23 | },
24 | },
25 | {
26 | files: ['*.ts', '*.vue'],
27 | parser: 'vue-eslint-parser',
28 | parserOptions: {
29 | parser: '@typescript-eslint/parser',
30 | },
31 | extends: [
32 | 'eslint:recommended',
33 | 'plugin:@typescript-eslint/recommended',
34 | 'plugin:vue/vue3-recommended',
35 | 'prettier',
36 | ],
37 | rules: {
38 | ...defaultRules,
39 | 'no-undef': 'off',
40 | 'no-console': ['error', { allow: ['warn', 'error'] }],
41 | '@typescript-eslint/ban-ts-comment': 'off',
42 | '@typescript-eslint/no-explicit-any': 'off',
43 | '@typescript-eslint/no-unused-vars': 'off',
44 | 'vue/no-v-html': 'off',
45 | },
46 | },
47 | ],
48 | };
49 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 | node
10 |
11 | # Log files
12 | npm-debug.log*
13 | yarn-debug.log*
14 | yarn-error.log*
15 | pnpm-debug.log*
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
25 | # npm file
26 | package-lock.json
27 | yarn.lock
28 | .yarn
29 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | stages:
2 | - build
3 |
4 | .curl-tpl: &curl-tpl
5 | variables:
6 | GIT_STRATEGY: none
7 | tags:
8 | - curl
9 |
10 | check_author:
11 | image: docker-registry.linagora.com:5000/lgs-releases/gitlab-integrity-checks:latest
12 | stage: build
13 | variables:
14 | GIT_DEPTH: "1"
15 | tags:
16 | - ultralight
17 | script:
18 | - check_author.py check "$GITLAB_USER_EMAIL" "$GITLAB_USER_NAME" --no-accents
19 | except:
20 | refs:
21 | - master@linagora/lgs/linshare/products/linshare-ui-admin
22 | - tags@linagora/lgs/linshare/products/linshare-ui-admin
23 | - /^release-.*/@linagora/lgs/linshare/products/linshare-ui-admin
24 | retry:
25 | max: 2
26 | when:
27 | - runner_system_failure
28 | - stuck_or_timeout_failure
29 |
30 | build:
31 | <<: *curl-tpl
32 | stage: build
33 | script:
34 | - echo skip
35 | retry:
36 | max: 2
37 | when:
38 | - runner_system_failure
39 | - stuck_or_timeout_failure
40 |
--------------------------------------------------------------------------------
/.gitlab/issue_templates/Bug.md:
--------------------------------------------------------------------------------
1 | ## **Bug details**
2 |
3 | - **User detail:**
4 |
5 |
6 | - **Description:**
7 |
8 |
9 | - **Bug occurred time:**
10 |
11 |
12 | - **Environment(version):**
13 |
14 |
15 | - **API(optional)**
16 |
17 |
18 | - **Params/cURL(backend)(optional):**
19 |
20 |
21 | - **Steps to reproduce:**
22 |
23 |
24 | - **Expectation:**
25 |
26 |
27 | - **Image/Video envidence:**
28 |
29 |
30 | ## **Related issues**
31 | - **QA**
32 |
33 |
34 | - **Story**
35 |
36 |
37 | - **Tech**
38 |
39 |
--------------------------------------------------------------------------------
/.gitlab/issue_templates/Issue.md:
--------------------------------------------------------------------------------
1 | ## Related issues
2 | - QA
3 | - Story
4 | - Tech
5 | ## Technical details
6 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | singleQuote: true,
3 | printWidth: 120
4 | };
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # linshare-ui-admin
2 |
3 | ## Project setup
4 | ```
5 | yarn
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn run dev
11 |
12 | # Development with a custom backend API base url
13 |
14 | BACKEND_API_URL='https://example.linshare.org' yarn run dev
15 | ```
16 |
17 | ### Compiles and minifies for production
18 | ```
19 | yarn run build
20 | ```
21 |
22 |
23 | ### Lints and fixes files
24 | ```
25 | yarn run lint
26 |
27 | # Fix lint errors
28 |
29 | yarn run lint:fix
30 | ```
31 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | LinShare Admin
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/maven/assembly/bin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | archive
4 |
5 | tar.bz2
6 |
7 |
8 |
9 | dist
10 | .
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/maven/main/resources/version.properties:
--------------------------------------------------------------------------------
1 | Implementation-Version=${project.version}
2 | Project-Version=${project.version}
3 | Compilation-Version=${sources.version}
4 | Compilation-Timestamp=${build.timestamp}
5 |
--------------------------------------------------------------------------------
/public/config/config.js:
--------------------------------------------------------------------------------
1 | window.APP_CONFIGURATION = Object.freeze({
2 | beta: true,
3 | legacyAppUrl: '/',
4 | oidcEnabled: false,
5 | oidcSetting: {
6 | authority: 'http://auth.linshare.local/',
7 | client_id: 'linshare',
8 | client_secret: 'linshare',
9 | scope: 'openid email profile',
10 | },
11 | });
12 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/public/favicon.ico
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
20 |
21 |
41 |
--------------------------------------------------------------------------------
/src/assets/images/freeotp-app-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/assets/images/freeotp-app-icon.png
--------------------------------------------------------------------------------
/src/config.ts:
--------------------------------------------------------------------------------
1 | import AppConfiguration from '@/core/types/AppConfiguration';
2 |
3 | export const DEFAULT_CONFIGURATION: AppConfiguration = {
4 | beta: true,
5 | legacyAppUrl: '/',
6 | homeRoute: '/administration',
7 | rootWelcomeMessageUuid: '4bc57114-c8c9-11e4-a859-37b5db95d856',
8 | oidcEnabled: false,
9 | appContext: '/new',
10 | oidcSetting: {
11 | authority: 'https://auth.linshare.local',
12 | client_id: 'linshare',
13 | client_secret: 'linshare',
14 | scope: 'openid email profile',
15 | loadUserInfo: true,
16 | },
17 | };
18 |
19 | const config: AppConfiguration = {
20 | ...DEFAULT_CONFIGURATION,
21 | ...window.APP_CONFIGURATION,
22 | };
23 |
24 | export default config;
25 |
--------------------------------------------------------------------------------
/src/core/components/hydrate-error.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $t('GENERAL.FAIL_TO_LOAD_DATA') }}
5 |
6 |
7 |
12 |
13 |
14 | {{ $t('GENERAL.REQUEST_RELOAD_DATA') }}
15 |
16 |
17 |
18 |
19 |
28 |
29 |
40 |
--------------------------------------------------------------------------------
/src/core/components/icons/actor-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
26 |
--------------------------------------------------------------------------------
/src/core/components/icons/archive-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/arrow-right-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
--------------------------------------------------------------------------------
/src/core/components/icons/assign-mime-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
27 |
28 |
--------------------------------------------------------------------------------
/src/core/components/icons/cancel-cross-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/check-circle-icon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/chevron-down-fill-icon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
16 |
17 |
--------------------------------------------------------------------------------
/src/core/components/icons/chevron-down-icon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
16 |
17 |
--------------------------------------------------------------------------------
/src/core/components/icons/chevron-right-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
--------------------------------------------------------------------------------
/src/core/components/icons/close-circle-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
19 |
--------------------------------------------------------------------------------
/src/core/components/icons/close-icon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/src/core/components/icons/creation-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
31 |
32 |
--------------------------------------------------------------------------------
/src/core/components/icons/detail-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/dot-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
23 |
24 |
--------------------------------------------------------------------------------
/src/core/components/icons/flag-france.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
20 |
21 |
--------------------------------------------------------------------------------
/src/core/components/icons/flag-russia.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
31 |
32 |
--------------------------------------------------------------------------------
/src/core/components/icons/flag-vn.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
19 |
20 |
--------------------------------------------------------------------------------
/src/core/components/icons/info-icon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/src/core/components/icons/menu-icon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/src/core/components/icons/newsfeed-icon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/src/core/components/icons/plus-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/security-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/sort-icon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
16 |
17 |
--------------------------------------------------------------------------------
/src/core/components/icons/status-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/success-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/switch-icon.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/src/core/components/icons/user-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/video-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/view-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/icons/view-mimes-icon.vue:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
26 |
27 |
--------------------------------------------------------------------------------
/src/core/components/ls/ls-alert.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
16 |
58 |
--------------------------------------------------------------------------------
/src/core/components/ls/ls-collapse-panel.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
50 |
--------------------------------------------------------------------------------
/src/core/components/ls/ls-collapse.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
--------------------------------------------------------------------------------
/src/core/components/ls/ls-modal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
15 |
--------------------------------------------------------------------------------
/src/core/components/ls/ls-tag.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 | {{ value }}
13 |
14 |
15 |
16 |
17 |
35 |
--------------------------------------------------------------------------------
/src/core/components/size-input.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ unit.label }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
50 |
--------------------------------------------------------------------------------
/src/core/components/the-copyright.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ $t('FOOTER.COPYRIGHT') }}
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/core/components/the-footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
10 |
11 |
27 |
--------------------------------------------------------------------------------
/src/core/constants/api-errors.ts:
--------------------------------------------------------------------------------
1 | export const ERRORS_REQUIRE_EXTRA_MESSAGE = [1006, 1007, 1008];
2 |
--------------------------------------------------------------------------------
/src/core/constants/breakpoint.ts:
--------------------------------------------------------------------------------
1 | export const LARGE_SCREEN_BREAK_POINT = '(min-width: 1069px)';
2 |
--------------------------------------------------------------------------------
/src/core/constants/emails.ts:
--------------------------------------------------------------------------------
1 | export const EMAIL_DEFAULT_UUID = {
2 | CONFIGURATION: '946b190d-4c95-485f-bfe6-d288a2de1edd',
3 | LAYOUT: '15044750-89d1-11e3-8d50-5404a683a462',
4 | FOOTER: 'e85f4a22-8cf2-11e3-8a7a-5404a683a462',
5 | };
6 |
--------------------------------------------------------------------------------
/src/core/constants/index.ts:
--------------------------------------------------------------------------------
1 | export const CONFIG = {
2 | API: {
3 | BASE_URL: 'linshare/webservice/rest/admin/v5',
4 | DEFAULT_HEADERS: {
5 | 'WWW-No-Authenticate': 'linshare',
6 | },
7 | },
8 | };
9 |
10 | export const CONFIGV4 = {
11 | API: {
12 | BASE_URL: 'linshare/webservice/rest/admin/v4',
13 | DEFAULT_HEADERS: {
14 | 'WWW-No-Authenticate': 'linshare',
15 | },
16 | },
17 | };
18 |
19 | export * from './languages';
20 | export * from './permissions';
21 | export * from './pagination';
22 | export * from './api-errors';
23 |
--------------------------------------------------------------------------------
/src/core/constants/languages.ts:
--------------------------------------------------------------------------------
1 | export const LANGUAGES = {
2 | SUPPORTED_LANGUAGE: [
3 | {
4 | name: 'English',
5 | key: 'us',
6 | language: 'en',
7 | },
8 | {
9 | name: 'Français',
10 | key: 'fr',
11 | language: 'fr',
12 | },
13 | {
14 | name: 'Tiếng Việt',
15 | key: 'vi',
16 | language: 'vi',
17 | },
18 | {
19 | name: 'Pусский',
20 | key: 'ru',
21 | language: 'ru',
22 | },
23 | ],
24 | DEFAULT: 'en',
25 | SUPPORTED_LOCALES: ['en', 'fr', 'ru', 'vi'],
26 | };
27 |
--------------------------------------------------------------------------------
/src/core/constants/pagination.ts:
--------------------------------------------------------------------------------
1 | export const DEFAULT_PAGE_SIZE = 10;
2 |
--------------------------------------------------------------------------------
/src/core/constants/permissions.ts:
--------------------------------------------------------------------------------
1 | export const PERMISSIONS = Object.freeze({
2 | DOMAINS: {
3 | VIEW: 'DOMAINS.VIEW',
4 | MANAGE_DOMAINS: 'DOMAINS.MANAGE_DOMAINS',
5 | FUNCTIONALITIES: 'DOMAINS.FUNCTIONALITIES',
6 | },
7 | USERS: {
8 | VIEW: 'USERS.VIEW',
9 | MANAGE_USERS: 'USERS.MANAGE_USERS',
10 | INCONSISTENT_USERS: 'USERS.INCONSISTENT_USERS',
11 | TECHNICAL_ACCOUNTS: 'USERS.TECHNICAL_ACCOUNTS',
12 | },
13 | WORKGROUPS: {
14 | VIEW: 'WORKGROUPS.VIEW',
15 | },
16 | MAILING_LISTS: {
17 | VIEW: 'MAILING_LISTS.VIEW',
18 | },
19 | HISTORY: {
20 | VIEW: 'HISTORY.VIEW',
21 | },
22 | MAILS: {
23 | VIEW: 'MAILS.VIEW',
24 | CONFIGURATION: 'MAILS.CONFIGURATION',
25 | LAYOUT: 'MAILS.LAYOUT',
26 | FOOTER: 'MAILS.FOOTER',
27 | CONTENT: 'MAILS.CONTENT',
28 | ACTIVATION: 'MAILS.ACTIVATION',
29 | },
30 | UPGRADE_TASKS: {
31 | VIEW: 'UPGRADE_TASKS.VIEW',
32 | },
33 | });
34 |
--------------------------------------------------------------------------------
/src/core/hooks/useAdministrationPage.ts:
--------------------------------------------------------------------------------
1 | import { ref } from 'vue';
2 |
3 | const actions = ref<
4 | {
5 | class: string;
6 | action: () => void;
7 | label: string;
8 | icon?: any;
9 | }[]
10 | >([]);
11 |
12 | export default function useAdministrationPage() {
13 | function setActions(
14 | items: {
15 | class: string;
16 | label: string;
17 | icon?: any;
18 | action: () => void;
19 | }[]
20 | ) {
21 | actions.value = items;
22 | }
23 |
24 | function addActions(
25 | items: {
26 | class: string;
27 | label: string;
28 | icon?: any;
29 | action: () => void;
30 | }[]
31 | ) {
32 | actions.value.push(...items);
33 | }
34 |
35 | return {
36 | actions,
37 | setActions,
38 | addActions,
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/src/core/hooks/useAntConfig.ts:
--------------------------------------------------------------------------------
1 | import { computed, ComputedRef } from 'vue';
2 | import { useI18n } from 'vue-i18n';
3 | import { LANGUAGES } from '@/core/constants';
4 | import { Locale } from 'ant-design-vue/es/locale-provider';
5 | import enUS from 'ant-design-vue/es/locale/en_US';
6 | import frFR from 'ant-design-vue/es/locale/fr_FR';
7 | import ruRU from 'ant-design-vue/es/locale/ru_RU';
8 | import viVN from 'ant-design-vue/es/locale/vi_VN';
9 |
10 | const keyToLocaleMap = new Map();
11 |
12 | keyToLocaleMap.set('en', enUS);
13 | keyToLocaleMap.set('fr', frFR);
14 | keyToLocaleMap.set('ru', ruRU);
15 | keyToLocaleMap.set('vi', viVN);
16 |
17 | type AntConfig = {
18 | antdLocale: ComputedRef;
19 | };
20 |
21 | export default function useAntConfig(): AntConfig {
22 | const { locale } = useI18n();
23 | const antdLocale = computed(() =>
24 | keyToLocaleMap.has(locale.value) ? keyToLocaleMap.get(locale.value) : keyToLocaleMap.get(LANGUAGES.DEFAULT)
25 | );
26 |
27 | return {
28 | antdLocale,
29 | };
30 | }
31 |
--------------------------------------------------------------------------------
/src/core/hooks/useLanguageModal.ts:
--------------------------------------------------------------------------------
1 | import { ref, Ref } from 'vue';
2 |
3 | type UsableLanguageModal = {
4 | languageVisible: Ref;
5 | toogleLanguage: (state: boolean) => void;
6 | };
7 | const languageVisible = ref(false);
8 |
9 | export default function useLanguageModal(): UsableLanguageModal {
10 | const toogleLanguage = (state: boolean) => {
11 | languageVisible.value = state;
12 | };
13 |
14 | return {
15 | languageVisible,
16 | toogleLanguage,
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/src/core/hooks/useMenu.ts:
--------------------------------------------------------------------------------
1 | import { ref, watch, Ref } from 'vue';
2 | import { useRouter } from 'vue-router';
3 |
4 | type UsableMenu = {
5 | current: Ref;
6 | visible: Ref;
7 | onClose: () => void;
8 | showDrawer: () => void;
9 | };
10 |
11 | export default function useMenu(): UsableMenu {
12 | const { currentRoute } = useRouter();
13 | const current = ref([currentRoute.value.path.split('/')[1]]);
14 | const visible = ref(false);
15 |
16 | const showDrawer = () => {
17 | visible.value = true;
18 | };
19 | const onClose = () => {
20 | visible.value = false;
21 | };
22 |
23 | watch(currentRoute, (newRoute) => {
24 | current.value = [newRoute.path.split('/')[1]];
25 | });
26 | return {
27 | visible,
28 | showDrawer,
29 | onClose,
30 | current,
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/src/core/hooks/useNotification.ts:
--------------------------------------------------------------------------------
1 | import { createVNode } from 'vue';
2 | import { Modal } from 'ant-design-vue';
3 | import { useI18n } from 'vue-i18n';
4 | import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
5 |
6 | interface ModalOptions {
7 | title: string;
8 | content: string;
9 | okText?: string;
10 | cancelText?: string;
11 | onOk?: (...args: any[]) => any;
12 | }
13 |
14 | type UsableNotification = {
15 | infoModal: (options: ModalOptions) => void;
16 | confirmModal: (options: ModalOptions) => void;
17 | };
18 |
19 | export default function useNotification(): UsableNotification {
20 | const { t } = useI18n();
21 |
22 | const infoModal = (options: ModalOptions) => {
23 | Modal.info({
24 | title: () => options.title,
25 | icon: () => createVNode(ExclamationCircleOutlined),
26 | content: () => options.content,
27 | okText: () => options.okText || t('GENERAL.OK'),
28 | onOk: options.onOk,
29 | });
30 | };
31 |
32 | const confirmModal = (options: ModalOptions) => {
33 | Modal.confirm({
34 | title: () => options.title,
35 | icon: () => createVNode(ExclamationCircleOutlined),
36 | content: () => options.content,
37 | okText: () => options.okText || t('GENERAL.OK'),
38 | cancelText: () => options.cancelText || t('GENERAL.CANCEL'),
39 | onOk: options.onOk,
40 | });
41 | };
42 |
43 | return {
44 | infoModal,
45 | confirmModal,
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/src/core/hooks/useProfile.ts:
--------------------------------------------------------------------------------
1 | import { ref, watch, Ref } from 'vue';
2 | import { useRouter } from 'vue-router';
3 |
4 | type UsableProfile = {
5 | current: Ref;
6 | visible: Ref;
7 | onClose: () => void;
8 | showDrawer: () => void;
9 | };
10 |
11 | export default function useProfile(): UsableProfile {
12 | const { currentRoute, push } = useRouter();
13 | const current = ref([currentRoute.value.path.split('/')[1]]);
14 | const visible = ref(false);
15 |
16 | const showDrawer = () => {
17 | visible.value = true;
18 | };
19 | const onClose = () => {
20 | visible.value = false;
21 | };
22 |
23 | watch(currentRoute, (newRoute) => {
24 | current.value = [newRoute.path.split('/')[1]];
25 | });
26 | return {
27 | visible,
28 | showDrawer,
29 | onClose,
30 | current,
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/src/core/hooks/useRelativeTime.ts:
--------------------------------------------------------------------------------
1 | import { useI18n } from 'vue-i18n';
2 | import { computed, ComputedRef } from 'vue';
3 | interface Unit {
4 | max: number;
5 | value: number;
6 | name: Intl.RelativeTimeFormatUnit;
7 | }
8 |
9 | const UNITS: Unit[] = [
10 | { max: 2760000, value: 60000, name: 'minute' },
11 | { max: 72000000, value: 3600000, name: 'hour' },
12 | { max: 518400000, value: 86400000, name: 'day' },
13 | { max: 2419200000, value: 604800000, name: 'week' },
14 | { max: 28512000000, value: 2592000000, name: 'month' },
15 | { max: Infinity, value: 31536000000, name: 'year' },
16 | ];
17 |
18 | type UsableRelativeTime = ComputedRef | undefined;
19 |
20 | export default function useRelativeTime(from: Date | string | number): UsableRelativeTime {
21 | const { locale, t } = useI18n();
22 | const { abs, round } = Math;
23 | const diff = +new Date(from) - +new Date();
24 |
25 | if (abs(diff) < 60000) {
26 | return computed(() => t('GENERAL.JUST_NOW', locale.value));
27 | }
28 |
29 | for (const unit of UNITS) {
30 | if (abs(diff) < unit.max) {
31 | return computed(() => new Intl.RelativeTimeFormat(locale.value).format(round(diff / unit.value), unit.name));
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/core/hooks/useUpgradeTaskPage.ts:
--------------------------------------------------------------------------------
1 | import { ref } from 'vue';
2 |
3 | const actions = ref<
4 | {
5 | class: string;
6 | action: () => void;
7 | loading?: boolean;
8 | label: string;
9 | icon?: any;
10 | }[]
11 | >([]);
12 |
13 | export default function useUpgradeTaskPage() {
14 | function setActions(
15 | items: {
16 | class: string;
17 | label: string;
18 | icon?: any;
19 | action: () => void;
20 | }[]
21 | ) {
22 | actions.value = items;
23 | }
24 |
25 | function addActions(
26 | items: {
27 | class: string;
28 | label: string;
29 | icon?: any;
30 | action: () => void;
31 | }[]
32 | ) {
33 | actions.value.push(...items);
34 | }
35 |
36 | return {
37 | actions,
38 | setActions,
39 | addActions,
40 | };
41 | }
42 |
--------------------------------------------------------------------------------
/src/core/layouts/home-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
24 |
25 |
55 |
--------------------------------------------------------------------------------
/src/core/pages/configuration-entries.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
14 |
--------------------------------------------------------------------------------
/src/core/plugins/i18n/index.ts:
--------------------------------------------------------------------------------
1 | import { createI18n } from 'vue-i18n';
2 | import i18nService from '@/core/services/I18nService';
3 | import messages from '@/core/plugins/i18n/locales';
4 | import { DATETIME_FORMATS as datetimeFormats } from './formats';
5 |
6 | const locale = i18nService && i18nService.getLocale();
7 |
8 | const i18n = createI18n({
9 | legacy: false,
10 | globalInjection: true,
11 | missingWarn: false,
12 | fallbackWarn: false,
13 | datetimeFormats,
14 | locale,
15 | messages,
16 | });
17 |
18 | export default i18n;
19 |
--------------------------------------------------------------------------------
/src/core/plugins/i18n/locales/index.ts:
--------------------------------------------------------------------------------
1 | import en from './en.json';
2 | import fr from './fr.json';
3 | import ru from './ru.json';
4 | import vi from './vi.json';
5 |
6 | export default {
7 | en,
8 | fr,
9 | ru,
10 | vi,
11 | };
12 |
--------------------------------------------------------------------------------
/src/core/router/coreRoutes.ts:
--------------------------------------------------------------------------------
1 | import config from '@/config';
2 | import { RouteRecordRaw } from 'vue-router';
3 | import HomePage from '@/core/layouts/home-page.vue';
4 | import { UpgradesRoute } from '@/modules/upgrades/router';
5 | import { ReportingRoute } from '@/modules/reporting/router';
6 | import { ActivitiesRoute } from '@/modules/activities/router';
7 | import { ConfigurationRoute } from '@/modules/configuration/router';
8 | import { AdministrationRoute } from '@/modules/administration/router';
9 | import { ManageSecondFactorAuthenticationRoute, ManageChangePasswordRoute } from '@/modules/auth/router';
10 |
11 | export const CoreRoutes: Array = [
12 | {
13 | name: 'Home',
14 | path: '/',
15 | redirect: config.homeRoute,
16 | component: HomePage,
17 | meta: {
18 | requiresAuth: true,
19 | },
20 | children: [
21 | UpgradesRoute,
22 | ReportingRoute,
23 | ActivitiesRoute,
24 | ConfigurationRoute,
25 | AdministrationRoute,
26 | ManageSecondFactorAuthenticationRoute,
27 | ManageChangePasswordRoute,
28 | ],
29 | },
30 | ];
31 |
--------------------------------------------------------------------------------
/src/core/router/index.ts:
--------------------------------------------------------------------------------
1 | import { createRouter, createWebHistory } from 'vue-router';
2 | import routes from './routes';
3 | import config from '@/config';
4 |
5 | /**
6 | * We prefer hash routing for 2 reasons:
7 | * - Ease for webserver configuration as the app can be served under a subpath
8 | * - Callback uri for OIDC authentication is fixed in the app
9 | */
10 | const router = createRouter({
11 | history: createWebHistory(config.appContext),
12 | routes,
13 | });
14 |
15 | export default router;
16 |
--------------------------------------------------------------------------------
/src/core/router/routes.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import { LoginRoutes } from '@/modules/auth/router';
3 | import { CoreRoutes } from '@/core/router/coreRoutes';
4 |
5 | export default [...LoginRoutes, ...CoreRoutes] as Array;
6 |
--------------------------------------------------------------------------------
/src/core/services/I18nService.ts:
--------------------------------------------------------------------------------
1 | import { LANGUAGES } from '@/core/constants';
2 |
3 | /**
4 | * I18n service
5 | *
6 | * This service stores selected locale in LocalStorage.
7 | */
8 | class I18nService {
9 | private localStorage: Storage;
10 |
11 | constructor() {
12 | if (!window.localStorage) {
13 | console.warn('Local storage is not supported by your browser. English will be used as the default language.');
14 | }
15 |
16 | this.localStorage = window.localStorage;
17 | }
18 |
19 | setLocale(locale: string) {
20 | if (!this.localStorage) return;
21 |
22 | if (LANGUAGES.SUPPORTED_LOCALES.indexOf(locale) === -1) {
23 | console.warn(`The locale is not supported: ${locale}`);
24 |
25 | return;
26 | }
27 |
28 | localStorage.setItem('locale', locale);
29 | }
30 |
31 | getLocale(): string {
32 | if (!this.localStorage) return LANGUAGES.DEFAULT;
33 |
34 | return localStorage.getItem('locale') || LANGUAGES.DEFAULT;
35 | }
36 | }
37 |
38 | export default new I18nService();
39 |
--------------------------------------------------------------------------------
/src/core/store/index.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia';
2 | interface AppState {
3 | hydrating: boolean;
4 | hydrated: boolean;
5 | authenticating: boolean;
6 | authenticated: boolean;
7 | error: boolean;
8 | }
9 |
10 | export const useAppStore = defineStore('appStore', {
11 | state: (): AppState => ({
12 | hydrated: false,
13 | hydrating: false,
14 | authenticating: false,
15 | authenticated: false,
16 | error: false,
17 | }),
18 | actions: {
19 | setHydrating(hydrating: boolean) {
20 | this.hydrating = hydrating;
21 | },
22 | setHydrated(hydrated: boolean) {
23 | this.hydrated = hydrated;
24 | },
25 | setAuthenticated(authenticated: boolean) {
26 | this.authenticated = authenticated;
27 | },
28 | setAuthenticating(authenticating: boolean) {
29 | this.authenticating = authenticating;
30 | },
31 | setError(errorState: boolean) {
32 | this.error = errorState;
33 | },
34 | },
35 | });
36 |
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Black.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Black.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Black.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Black.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-BlackItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-BlackItalic.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-BlackItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-BlackItalic.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Bold.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Bold.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-BoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-BoldItalic.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-BoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-BoldItalic.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ExtraBold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ExtraBold.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ExtraBold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ExtraBold.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ExtraBoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ExtraBoldItalic.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ExtraBoldItalic.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ExtraLight.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ExtraLight.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ExtraLight.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ExtraLight.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ExtraLightItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ExtraLightItalic.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ExtraLightItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ExtraLightItalic.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Italic.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Italic.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Light.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Light.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-LightItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-LightItalic.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-LightItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-LightItalic.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Medium.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Medium.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-MediumItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-MediumItalic.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-MediumItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-MediumItalic.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Regular.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Regular.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-SemiBold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-SemiBold.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-SemiBold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-SemiBold.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-SemiBoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-SemiBoldItalic.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-SemiBoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-SemiBoldItalic.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Thin.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-Thin.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ThinItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ThinItalic.woff
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-ThinItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-ThinItalic.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-italic.var.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-italic.var.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter-roman.var.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter-roman.var.woff2
--------------------------------------------------------------------------------
/src/core/styles/fonts/Inter/Inter.var.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linagora/linshare-ui-admin/715bdfc967b504b51ccaf6c619239161cdccefcd/src/core/styles/fonts/Inter/Inter.var.woff2
--------------------------------------------------------------------------------
/src/core/types/AppConfiguration.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable camelcase */
2 | export default interface AppConfiguration {
3 | beta: boolean;
4 | rootWelcomeMessageUuid: string;
5 | legacyAppUrl: string;
6 | homeRoute: string;
7 | appContext: string;
8 | oidcEnabled: boolean;
9 | oidcSetting: {
10 | authority: string;
11 | client_id: string;
12 | client_secret: string;
13 | scope: string;
14 | loadUserInfo: boolean;
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/src/core/types/Domain.ts:
--------------------------------------------------------------------------------
1 | export default interface Domain {
2 | name?: string;
3 | checked?: boolean;
4 | children?: Domain[];
5 | type?: string;
6 | uuid: string;
7 | label?: string;
8 | identifier?: string;
9 | }
10 |
--------------------------------------------------------------------------------
/src/core/types/Filters.ts:
--------------------------------------------------------------------------------
1 | export default interface Filters {
2 | [key: string]: string | boolean | undefined;
3 | }
4 |
--------------------------------------------------------------------------------
/src/core/types/PaginatedList.ts:
--------------------------------------------------------------------------------
1 | export interface PaginatedList {
2 | data: T[];
3 | total: number;
4 | totalPages: number;
5 | current: number;
6 | }
7 |
--------------------------------------------------------------------------------
/src/core/types/Sort.ts:
--------------------------------------------------------------------------------
1 | export enum SORT_ORDER {
2 | ASC = 'ASC',
3 | DESC = 'DESC',
4 | }
5 |
6 | export default interface Sort {
7 | field?: string;
8 | order: SORT_ORDER;
9 | }
10 |
--------------------------------------------------------------------------------
/src/core/types/Status.ts:
--------------------------------------------------------------------------------
1 | enum STATUS {
2 | LOADING = 'loading',
3 | SUCCESS = 'success',
4 | ERROR = 'error',
5 | }
6 |
7 | export { STATUS };
8 |
--------------------------------------------------------------------------------
/src/core/types/TimePeriod.ts:
--------------------------------------------------------------------------------
1 | export type TimePeriod =
2 | | 'ALL_TIME'
3 | | 'LAST_DAY'
4 | | 'LAST_7_DAYS'
5 | | 'LAST_30_DAYS'
6 | | 'LAST_6_MONTHS'
7 | | 'LAST_YEAR'
8 | | 'CUSTOM';
9 |
--------------------------------------------------------------------------------
/src/core/types/Unit.ts:
--------------------------------------------------------------------------------
1 | export type Unit = {
2 | name: string;
3 | value: string;
4 | factor: number;
5 | };
6 |
--------------------------------------------------------------------------------
/src/core/utils/functionality.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Functionality,
3 | UnitSizeParameterValue,
4 | UnitTimeParameterValue,
5 | IntegerParameterValue,
6 | } from '../types/Functionality';
7 |
8 | export function getMaximumParameter(
9 | functionality: Functionality | undefined
10 | ): UnitSizeParameterValue | UnitTimeParameterValue | IntegerParameterValue | null {
11 | if (!functionality) {
12 | return null;
13 | }
14 |
15 | const parameter = functionality.parameter;
16 |
17 | switch (parameter?.type) {
18 | case 'UNIT_SIZE_ALL':
19 | case 'UNIT_TIME_ALL':
20 | case 'INTEGER_ALL':
21 | return parameter.maximum;
22 |
23 | default:
24 | return null;
25 | }
26 | }
27 |
28 | export function isEnable(functionality: Functionality | undefined): boolean {
29 | if (!functionality) {
30 | return false;
31 | }
32 | return functionality?.activationPolicy.enable.value;
33 | }
34 |
--------------------------------------------------------------------------------
/src/core/utils/is-email.ts:
--------------------------------------------------------------------------------
1 | export function isEmail(string: string): boolean {
2 | const emailRegex = /^\S+@\S+\.\S+$/;
3 |
4 | return emailRegex.test(string);
5 | }
6 |
--------------------------------------------------------------------------------
/src/env.d.ts:
--------------------------------------------------------------------------------
1 | interface ImportMetaEnv extends Readonly> {
2 | readonly MODE: string;
3 | }
4 |
5 | interface ImportMeta {
6 | readonly env: ImportMetaEnv;
7 | }
8 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue';
2 | import App from './App.vue';
3 | import router from '@/core/router';
4 | import i18n from '@/core/plugins/i18n';
5 | import { createPinia } from 'pinia';
6 | import useAntdComponents from '@/core/plugins/antd';
7 | import { requiresAuthGuard } from '@/modules/auth/router/requiresAuth.guard';
8 | import { requiresDomainAccessibility } from '@/modules/domain/router/requiresDomainAccessibility';
9 | import { requiresDomainUpdate } from '@/modules/domain/router/requiresDomainUpdate';
10 |
11 | requiresDomainUpdate(router);
12 | requiresAuthGuard(router);
13 | requiresDomainAccessibility(router);
14 |
15 | const app = createApp(App).use(router).use(i18n).use(createPinia());
16 |
17 | useAntdComponents(app).mount('#app');
18 |
--------------------------------------------------------------------------------
/src/modules/activities/components/README.md:
--------------------------------------------------------------------------------
1 | Component folder
--------------------------------------------------------------------------------
/src/modules/activities/hooks/README.md:
--------------------------------------------------------------------------------
1 | Hooks folder
--------------------------------------------------------------------------------
/src/modules/activities/pages/README.md:
--------------------------------------------------------------------------------
1 | Pages folder
--------------------------------------------------------------------------------
/src/modules/activities/pages/index-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
--------------------------------------------------------------------------------
/src/modules/activities/router/README.md:
--------------------------------------------------------------------------------
1 | Router folder
--------------------------------------------------------------------------------
/src/modules/activities/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 |
3 | export const ActivitiesRoute: RouteRecordRaw = {
4 | name: 'Activities',
5 | path: 'activities',
6 | component: () => import('../layouts/activities-layout.vue'),
7 | meta: {
8 | label: 'NAVIGATOR.ACTIVITIES',
9 | requiresAuth: true,
10 | uiBeta: true,
11 | },
12 | children: [
13 | {
14 | name: 'ActivitiesEntries',
15 | path: '',
16 | component: () => import('../pages/index-page.vue'),
17 | },
18 | ],
19 | };
20 |
--------------------------------------------------------------------------------
/src/modules/activities/services/README.md:
--------------------------------------------------------------------------------
1 | Service folder
--------------------------------------------------------------------------------
/src/modules/activities/services/index.ts:
--------------------------------------------------------------------------------
1 | import api from '@/api';
2 | import type { PaginatedList } from '@/core/types/PaginatedList';
3 | import { ActivityLogParameters } from '@/modules/activities/types';
4 |
5 | async function getActivitiesLogs(
6 | domainUuid: string,
7 | includeNestedDomains: boolean,
8 | beginDate: string | undefined,
9 | endDate: string | undefined,
10 | action?: string,
11 | type?: string,
12 | domain?: string,
13 | size?: number,
14 | page?: number,
15 | sortField?: string,
16 | sortOrder?: string,
17 | actorEmail?: string,
18 | resourceName?: string
19 | ): Promise> {
20 | const queryUrl = `domains/${domainUuid}/audit`;
21 |
22 | return await api.get(queryUrl, {
23 | params: {
24 | includeNestedDomains,
25 | beginDate,
26 | endDate,
27 | action,
28 | type,
29 | domain,
30 | size,
31 | page,
32 | sortField,
33 | sortOrder,
34 | actorEmail,
35 | resourceName,
36 | },
37 | });
38 | }
39 |
40 | export { getActivitiesLogs };
41 |
--------------------------------------------------------------------------------
/src/modules/activities/store/README.md:
--------------------------------------------------------------------------------
1 | Store folder
--------------------------------------------------------------------------------
/src/modules/activities/types/README.md:
--------------------------------------------------------------------------------
1 | Type folder
--------------------------------------------------------------------------------
/src/modules/administration/pages/contact-list/components/contact-list-actions.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
17 |
47 |
--------------------------------------------------------------------------------
/src/modules/administration/pages/contact-list/pages/entries-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
--------------------------------------------------------------------------------
/src/modules/administration/pages/contact-list/types/Contact.ts:
--------------------------------------------------------------------------------
1 | import Domain from '@/core/types/Domain';
2 | import User from '@/modules/user/types/User';
3 | import Filters from '@/core/types/Filters';
4 | import { SORT_ORDER } from '@/core/types/Sort';
5 |
6 | export interface Contact {
7 | identifier: string;
8 | description: string;
9 | owner: User;
10 | contacts: ContactInfo[];
11 | uuid: string;
12 | domainId: string;
13 | domainLabel: string;
14 | domain: Domain;
15 | public: boolean;
16 | }
17 |
18 | export interface ContactInfo {
19 | mail?: string;
20 | email?: string;
21 | firstName: string;
22 | lastName: string;
23 | }
24 |
25 | export interface ContactListFilters extends Filters {
26 | domainUuid?: string;
27 | ownerUuid?: string;
28 | memberMail?: string;
29 | }
30 |
31 | export interface ContactListParameters {
32 | domainUuid?: string;
33 | ownerUuid?: string;
34 | memberMail?: string;
35 | page?: number;
36 | size?: number;
37 | sortOrder?: SORT_ORDER;
38 | sortField?: string;
39 | }
40 |
--------------------------------------------------------------------------------
/src/modules/administration/pages/technical-accounts/components/detail-page/user-informations.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
19 |
34 |
--------------------------------------------------------------------------------
/src/modules/administration/pages/technical-accounts/pages/entries-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
--------------------------------------------------------------------------------
/src/modules/administration/pages/technical-accounts/services/technical-account-api.ts:
--------------------------------------------------------------------------------
1 | import apiv4 from '@/apiv4';
2 | import { TechnicalAccount, TechnicalAccountCreation, TechnicalAccountDetails } from '../types/TechnicalAccount';
3 |
4 | async function getTechnicalAccountsList(): Promise {
5 | return await apiv4.get(`/technical_accounts`);
6 | }
7 |
8 | async function createTechnicalAccount(payload: TechnicalAccountCreation): Promise {
9 | return await apiv4.post(`technical_accounts`, payload);
10 | }
11 |
12 | async function getTechnicalAccountDetail(uuid: string | string[]): Promise {
13 | return await apiv4.get(`/technical_accounts/${uuid}`);
14 | }
15 |
16 | async function updateTechnicalAccount(payload: TechnicalAccountDetails): Promise {
17 | return await apiv4.put(`/technical_accounts`, payload);
18 | }
19 |
20 | async function deleteTechnicalAccount(payload: TechnicalAccount): Promise {
21 | return await apiv4.delete(`technical_accounts`, { data: payload });
22 | }
23 |
24 | async function changeTechnicalAccountPassword(uuid: string | string[], payload: { newPwd: string; oldPwd: string }) {
25 | return await apiv4.post(`/technical_accounts/${uuid}/change_password`, payload);
26 | }
27 |
28 | export {
29 | getTechnicalAccountsList,
30 | createTechnicalAccount,
31 | getTechnicalAccountDetail,
32 | updateTechnicalAccount,
33 | deleteTechnicalAccount,
34 | changeTechnicalAccountPassword,
35 | };
36 |
--------------------------------------------------------------------------------
/src/modules/auth/components/oidc-callback.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
29 |
30 |
43 |
--------------------------------------------------------------------------------
/src/modules/auth/constants/index.ts:
--------------------------------------------------------------------------------
1 | export const OTP_DEFAULT_CONFIGURATION = {
2 | type: 'totp',
3 | digits: 6,
4 | issuer: 'LinShare',
5 | algorithm: 'SHA1',
6 | period: 30,
7 | };
8 |
9 | export const OTP_APP_INSTALL_LINKS = {
10 | googlePlay: 'https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp',
11 | appStore: 'https://apps.apple.com/us/app/freeotp-authenticator/id872559395',
12 | };
13 |
--------------------------------------------------------------------------------
/src/modules/auth/router/requiresAuth.guard.ts:
--------------------------------------------------------------------------------
1 | import { Router } from 'vue-router';
2 | import { useAppStore } from '@/core/store';
3 | import { hydrate } from '@/core/store/hydrate';
4 | import { useAuthStore } from '@/modules/auth/store';
5 |
6 | let firstLoad = true;
7 |
8 | export const requiresAuthGuard = async (router: Router): Promise => {
9 | router.beforeEach(async (to) => {
10 | const requiresAuth = to.matched.some((record) => record.meta.requiresAuth);
11 |
12 | if (!requiresAuth) {
13 | return;
14 | }
15 |
16 | if (firstLoad) {
17 | firstLoad = false;
18 | const authStore = useAuthStore();
19 | const appStore = useAppStore();
20 | try {
21 | appStore.setAuthenticating(true);
22 | await authStore.fetchLoggedUser();
23 | appStore.setAuthenticated(true);
24 | } catch (error) {
25 | return { name: 'Login' };
26 | } finally {
27 | appStore.setAuthenticating(false);
28 | }
29 | await hydrate();
30 | }
31 | });
32 | };
33 |
--------------------------------------------------------------------------------
/src/modules/auth/router/requiresSecondFAEnabled.ts:
--------------------------------------------------------------------------------
1 | import { isEnable } from '@/core/utils/functionality';
2 | import { Router } from 'vue-router';
3 | import { useAuthStore } from '../store';
4 |
5 | export const requiresSecondFAEnabled = (router: Router): void => {
6 | router.beforeEach((to) => {
7 | const authStore = useAuthStore();
8 |
9 | if (to.name === 'ManageSecondFactorAuthentication') {
10 | return isEnable(authStore.functionalities.SECOND_FACTOR_AUTHENTICATION) || '/';
11 | }
12 | });
13 | };
14 |
--------------------------------------------------------------------------------
/src/modules/auth/services/auth-api.ts:
--------------------------------------------------------------------------------
1 | import { AxiosRequestConfig } from 'axios';
2 | import api from '@/api';
3 | import SecondFactorAuthentication from '../types/SecondFactorAuthentication';
4 | import ChangePassword from '../types/ChangePassword';
5 | import User from '@/modules/user/types/User';
6 |
7 | async function getAuthorizedUser(config?: AxiosRequestConfig): Promise {
8 | return await api.get('authentication/authorized', config);
9 | }
10 |
11 | async function get2FAStatus(uuid: string): Promise {
12 | return await api.get(`authentication/2fa/${uuid}`);
13 | }
14 |
15 | async function create2FAKey(): Promise {
16 | return await api.post('authentication/2fa');
17 | }
18 |
19 | async function logOut(): Promise {
20 | return await api.get('authentication/logout');
21 | }
22 |
23 | async function remove2FAKey(uuid: string): Promise {
24 | return await api.delete(`authentication/2fa/${uuid}`);
25 | }
26 |
27 | async function changePassword(payload: { oldPwd: string; newPwd: string }): Promise {
28 | return await api.post('authentication/change_password/', payload);
29 | }
30 |
31 | export { create2FAKey, get2FAStatus, getAuthorizedUser, logOut, remove2FAKey, changePassword };
32 |
--------------------------------------------------------------------------------
/src/modules/auth/services/basic.ts:
--------------------------------------------------------------------------------
1 | import { useAuthStore } from '@/modules/auth/store';
2 | import { useAppStore } from '@/core/store';
3 | import { hydrate, dehydrate } from '@/core/store/hydrate';
4 | import { logOut } from './auth-api';
5 | import { AxiosRequestConfig } from 'axios';
6 |
7 | export interface LoginCredentials {
8 | email: string;
9 | password: string;
10 | otp?: string;
11 | }
12 |
13 | interface AuthRequestConfig extends AxiosRequestConfig {
14 | headers: {
15 | 'x-linShare-2fa-pin'?: string;
16 | };
17 | }
18 |
19 | export async function login(credentials: LoginCredentials): Promise {
20 | const params: AuthRequestConfig = {
21 | auth: {
22 | username: credentials.email,
23 | password: credentials.password,
24 | },
25 | headers: {},
26 | };
27 |
28 | if (credentials.otp) {
29 | params.headers['x-linShare-2fa-pin'] = credentials.otp;
30 | }
31 |
32 | const authStore = useAuthStore();
33 | const appStore = useAppStore();
34 | await authStore.fetchLoggedUser(params);
35 | appStore.setAuthenticated(true);
36 | hydrate();
37 | }
38 |
39 | export async function logout(): Promise {
40 | await logOut();
41 | await dehydrate();
42 | }
43 |
--------------------------------------------------------------------------------
/src/modules/auth/store/auth2FAstore.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia';
2 |
3 | interface Auth2FAState {
4 | email: string;
5 | password: string;
6 | redirect?: string;
7 | }
8 |
9 | export const useAuth2FAStore = defineStore('useAuth2FAStore', {
10 | state: (): Auth2FAState => ({
11 | email: '',
12 | password: '',
13 | redirect: '',
14 | }),
15 | actions: {
16 | setCredentials(email: string, password: string, redirect = ''): void {
17 | this.email = email;
18 | this.password = password;
19 | this.redirect = redirect;
20 | },
21 | dehydrate(): void {
22 | this.email = '';
23 | this.password = '';
24 | this.redirect = '';
25 | },
26 | },
27 | });
28 |
--------------------------------------------------------------------------------
/src/modules/auth/types/ChangePassword.ts:
--------------------------------------------------------------------------------
1 | export default interface ChangePasswordType {
2 | oldPwd: string;
3 | newPwd: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/modules/auth/types/OtpSetupHintConfigs.ts:
--------------------------------------------------------------------------------
1 | export default interface OtpSetupHintConfigs {
2 | secret: string;
3 | issuer: string;
4 | account: string;
5 | type: string;
6 | digits: number;
7 | algorithm: string;
8 | period: number;
9 | }
10 |
--------------------------------------------------------------------------------
/src/modules/auth/types/SecondFactorAuthentication.ts:
--------------------------------------------------------------------------------
1 | export default interface SecondFactorAuthentication {
2 | uuid: string;
3 | canDeleteIt: boolean;
4 | creationDate: number;
5 | enabled: boolean;
6 | required: boolean;
7 | sharedKey?: string;
8 | }
9 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/detail/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import DetailPage from '../pages/detail-page.vue';
3 | export const ConfigurationDomainDetailRoutes: RouteRecordRaw[] = [
4 | {
5 | name: 'ConfigurationDomainDetail',
6 | path: ':domainUuid/detail',
7 | component: DetailPage,
8 | meta: {
9 | requiresAuth: true,
10 | parentRoute: 'Configuration',
11 | label: 'NAVIGATOR.DETAILS',
12 | },
13 | children: [],
14 | },
15 | ];
16 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-group-providers/components/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store component files of configuration/domain-group-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-group-providers/composables/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the composable methods of configuration/domain-group-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-group-providers/hooks/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the methods used in the hook of configuration/domain-group-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-group-providers/pages/group-providers-page.vue:
--------------------------------------------------------------------------------
1 | Here is domain-group-providers page with domainuuid: {{ currentDomainUuid }}
2 |
12 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-group-providers/pages/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store vue page files of configuration/domain-group-providers module ( the file will be import in the routes)
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-group-providers/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import GroupProvidersPage from '../pages/group-providers-page.vue';
3 | export const ConfigurationDomainGroupProvidersRoutes: RouteRecordRaw[] = [
4 | {
5 | name: 'ConfigurationDomainGroupProviders',
6 | path: ':domainUuid/domain-group-providers',
7 | component: GroupProvidersPage,
8 | meta: {
9 | requiresAuth: true,
10 | parentRoute: 'Configuration',
11 | },
12 | children: [],
13 | },
14 | ];
15 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-group-providers/router/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store route config files of configuration/domain-group-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-group-providers/services/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store services files of configuration/domain-group-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-group-providers/types/readme.md:
--------------------------------------------------------------------------------
1 | This directory is for storing type declaration files of configuration/domain-group-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-policies/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import DomainPoliciesPage from '@/modules/configuration/pages/domain-policies/pages/policies-page.vue';
3 | export const CONFIGURATION_DOMAIN_POLICIES_ROUTE_NAMES = {
4 | POLICIES: 'ConfigurationDomainPolicies',
5 | POLICY_DETAIL: 'ConfigurationDomainPoliciesDetail',
6 | };
7 |
8 | export const ConfigurationDomainPoliciesRoutes: RouteRecordRaw[] = [
9 | {
10 | name: CONFIGURATION_DOMAIN_POLICIES_ROUTE_NAMES.POLICIES,
11 | path: ':domainUuid/domain-policies',
12 | component: DomainPoliciesPage,
13 | meta: {
14 | requiresAuth: true,
15 | parentRoute: 'Configuration',
16 | label: 'NAVIGATOR.CONFIGURATION_DOMAIN_POLICIES',
17 | },
18 | children: [],
19 | },
20 | {
21 | name: CONFIGURATION_DOMAIN_POLICIES_ROUTE_NAMES.POLICY_DETAIL,
22 | path: ':domainUuid/domain-policies/:id',
23 | component: () => import('@/modules/configuration/pages/domain-policies/pages/policy-detail-page.vue'),
24 | meta: {
25 | requiresAuth: true,
26 | parentRoute: CONFIGURATION_DOMAIN_POLICIES_ROUTE_NAMES.POLICIES,
27 | label: 'NAVIGATOR.CONFIGURATION_DOMAIN_POLICIES_DETAILS',
28 | },
29 | children: [],
30 | },
31 | ];
32 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-policies/types/DomainPolicy.ts:
--------------------------------------------------------------------------------
1 | import Domain from '@/core/types/Domain';
2 |
3 | export interface DomainPolicy {
4 | identifier: string;
5 | label: string;
6 | description: string;
7 | accessPolicy: {
8 | rules: DomainPolicyRule[];
9 | };
10 | assigned?: boolean;
11 | creationDate?: number;
12 | modificationDate?: number;
13 | }
14 |
15 | export interface DomainPolicyRule {
16 | type: 'ALLOW' | 'ALLOW_ALL' | 'DENY' | 'DENY_ALL';
17 | domain: Domain;
18 | }
19 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-provider-management/components/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store component files of configuration/domain-provider-management module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-provider-management/composables/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the composable methods of configuration/domain-provider-management module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-provider-management/hooks/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the methods used in the hook of configuration/domain-provider-management module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-provider-management/pages/domain-provider-management-page.vue:
--------------------------------------------------------------------------------
1 | Here is domain-provider-management page with domainuuid: {{ currentDomainUuid }}
2 |
12 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-provider-management/pages/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store vue page files of configuration/domain-provider-management module ( the file will be import in the routes)
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-provider-management/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import ProviderManagementPage from '../pages/domain-provider-management-page.vue';
3 | export const ConfigurationDomainProviderManagementRoutes: RouteRecordRaw[] = [
4 | {
5 | name: 'ConfigurationDomainProviderManagement',
6 | path: ':domainUuid/domain-provider-management',
7 | component: ProviderManagementPage,
8 | meta: {
9 | requiresAuth: true,
10 | parentRoute: 'Configuration',
11 | },
12 | children: [],
13 | },
14 | ];
15 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-provider-management/router/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store route config files of configuration/domain-provider-management module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-provider-management/services/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store services files of configuration/domain-provider-management module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-provider-management/types/readme.md:
--------------------------------------------------------------------------------
1 | This directory is for storing type declaration files of configuration/domain-provider-management module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-user-providers/components/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store component files of configuration/domain-user-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-user-providers/composables/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the composable methods of configuration/domain-user-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-user-providers/hooks/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the methods used in the hook of configuration/domain-user-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-user-providers/pages/domain-user-providers-page.vue:
--------------------------------------------------------------------------------
1 | Here is domain-user-providers page with domainuuid: {{ currentDomainUuid }}
2 |
12 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-user-providers/pages/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store vue page files of configuration/domain-user-providers module ( the file will be import in the routes)
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-user-providers/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import DomainUserProvidersPage from '../pages/domain-user-providers-page.vue';
3 | export const ConfigurationDomainDomainUserProvidersRoutes: RouteRecordRaw[] = [
4 | {
5 | name: 'ConfigurationDomainDomainUserProviders',
6 | path: ':domainUuid/domain-user-providers',
7 | component: DomainUserProvidersPage,
8 | meta: {
9 | requiresAuth: true,
10 | parentRoute: 'Configuration',
11 | },
12 | children: [],
13 | },
14 | ];
15 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-user-providers/router/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store route config files of configuration/domain-user-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-user-providers/services/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store services files of configuration/domain-user-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-user-providers/types/readme.md:
--------------------------------------------------------------------------------
1 | This directory is for storing type declaration files of configuration/domain-user-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-workspace-providers/components/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store component files of configuration/domain-workspace-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-workspace-providers/composables/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the composable methods of configuration/domain-workspace-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-workspace-providers/hooks/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the methods used in the hook of configuration/domain-workspace-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-workspace-providers/pages/domain-workspace-providers-page.vue:
--------------------------------------------------------------------------------
1 | Here is domain-workspace-providers page with domainuuid: {{ currentDomainUuid }}
2 |
12 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-workspace-providers/pages/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store vue page files of configuration/domain-workspace-providers module ( the file will be import in the routes)
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-workspace-providers/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import DomainWorkspaceProvidersPage from '../pages/domain-workspace-providers-page.vue';
3 | export const ConfigurationDomainDomainWorkspaceProvidersRoutes: RouteRecordRaw[] = [
4 | {
5 | name: 'ConfigurationDomainDomainWorkspaceProviders',
6 | path: ':domainUuid/domain-workspace-providers',
7 | component: DomainWorkspaceProvidersPage,
8 | meta: {
9 | requiresAuth: true,
10 | parentRoute: 'Configuration',
11 | },
12 | children: [],
13 | },
14 | ];
15 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-workspace-providers/router/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store route config files of configuration/domain-workspace-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-workspace-providers/services/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store services files of configuration/domain-workspace-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/domain-workspace-providers/types/readme.md:
--------------------------------------------------------------------------------
1 | This directory is for storing type declaration files of configuration/domain-workspace-providers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/email-templates/pages/entries-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
30 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/email-templates/types/MailActivation.ts:
--------------------------------------------------------------------------------
1 | export interface MailActivation {
2 | identifier: string;
3 | domain: string;
4 | activationPolicy: {
5 | policy: string;
6 | status: boolean;
7 | defaultStatus: boolean;
8 | parentAllowUpdate: boolean;
9 | system: boolean;
10 | };
11 | configurationPolicy: {
12 | policy: string;
13 | status: boolean;
14 | defaultStatus: boolean;
15 | parentAllowUpdate: boolean;
16 | system: boolean;
17 | };
18 | delegationPolicy: {
19 | policy: string;
20 | status: boolean;
21 | defaultStatus: boolean;
22 | parentAllowUpdate: boolean;
23 | system: boolean;
24 | };
25 | enable: boolean;
26 | }
27 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/email-templates/types/MailConfiguration.ts:
--------------------------------------------------------------------------------
1 | export type MailFooterLangs = { [key: string]: MailLang };
2 | export interface MailConfiguration {
3 | creationDate?: number;
4 | domain: string;
5 | domainName: string;
6 | mailContentLangs: MailLang[];
7 | mailFooterLangs: MailFooterLangs;
8 | mailLayout: string;
9 | modificationDate: number;
10 | name: string;
11 | readonly: string;
12 | uuid: string;
13 | visible: boolean;
14 | assigned?: boolean;
15 | selectLanguage?: string;
16 | }
17 |
18 | export interface MailLang {
19 | language: string;
20 | mailConfig: string;
21 | mailContent: string;
22 | mailContentType: string;
23 | mailFooter?: string;
24 | readonly: boolean;
25 | uuid: string;
26 | mailContentDomainName?: string;
27 | mailContentName?: string;
28 | mailContentModificationDate?: string | number;
29 | legend: string;
30 | }
31 |
32 | export interface MailLangDetail {
33 | description: string;
34 | domain: string;
35 | domainLabel?: string;
36 | visible: boolean;
37 | mailContentType: string;
38 | subject: string;
39 | body: string;
40 | creationDate: number;
41 | modificationDate: number;
42 | uuid: string;
43 | readonly: boolean;
44 | messagesFrench: string;
45 | messagesEnglish: string;
46 | messagesRussian: string;
47 | }
48 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/email-templates/types/MailContent.ts:
--------------------------------------------------------------------------------
1 | export interface MailContent {
2 | description: string;
3 | domain: string;
4 | domainName?: string;
5 | domainLabel: string;
6 | visible: boolean;
7 | footer: string;
8 | creationDate: number;
9 | modificationDate: number;
10 | uuid: string;
11 | plaintext: boolean;
12 | readonly: boolean;
13 | messagesFrench: string;
14 | messagesEnglish: string;
15 | messagesRussian: string;
16 | messagesVietnamese: string;
17 | body: string;
18 | mailContentType: string;
19 | subject: string;
20 | context?: number;
21 | config?: string;
22 | }
23 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/email-templates/types/MailContext.ts:
--------------------------------------------------------------------------------
1 | export interface MailContext {
2 | mailType: string;
3 | variables: {
4 | name: string;
5 | type: string;
6 | stringValue: string;
7 | variables: {
8 | name: string;
9 | type: string;
10 | stringValue: string;
11 | }[];
12 | }[];
13 | }
14 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/email-templates/types/MailFooter.ts:
--------------------------------------------------------------------------------
1 | export interface MailFooter {
2 | description: string;
3 | domain: string;
4 | domainName?: string;
5 | visible: boolean;
6 | footer: string;
7 | creationDate: number;
8 | modificationDate: number;
9 | uuid: string;
10 | plaintext: boolean;
11 | readonly: boolean;
12 | messagesFrench: string;
13 | messagesEnglish: string;
14 | messagesRussian: string;
15 | messagesVietnamese: string;
16 | }
17 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/email-templates/types/MailLayout.ts:
--------------------------------------------------------------------------------
1 | export interface MailLayout {
2 | uuid: string;
3 | domain: string;
4 | domainName: string;
5 | description: string;
6 | layout: string;
7 | visible: boolean;
8 | creationDate: number;
9 | modificationDate: number;
10 | readonly: boolean;
11 | messagesFrench: string;
12 | messagesEnglish: string;
13 | messagesRussian: string;
14 | messagesVietnamese: string;
15 | assigned?: boolean;
16 | }
17 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/parameters/hooks/useFunctionalities.ts:
--------------------------------------------------------------------------------
1 | import { computed, ComputedRef, Ref } from 'vue';
2 | import { useI18n } from 'vue-i18n';
3 | import { Functionality } from '@/modules/configuration/pages/parameters/types/Functionality';
4 |
5 | type UsableFunctionalities = {
6 | getTranslatedText: (functionality: Functionality, key: string) => string;
7 | };
8 |
9 | export default function useFunctionalities(): UsableFunctionalities {
10 | const { t } = useI18n();
11 |
12 | function getTranslatedText(functionality: Functionality, key: string): string {
13 | const i18nKey = `FUNCTIONALITIES.DETAILS.${functionality.identifier}.${key}`;
14 | const i18nValue = t(i18nKey);
15 |
16 | return i18nValue === i18nKey ? t(`FUNCTIONALITIES.DEFAULT.${key}`) : i18nValue;
17 | }
18 |
19 | return {
20 | getTranslatedText,
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/parameters/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import ParametersPage from '../pages/parameters-page.vue';
3 | import ParametersDetailsPage from '../components/domain-functionality-details.vue';
4 | export const ConfigurationDomainParametersRoutes: RouteRecordRaw[] = [
5 | {
6 | name: 'ConfigurationDomainParameters',
7 | path: ':domainUuid/parameters',
8 | component: ParametersPage,
9 | meta: {
10 | requiresAuth: true,
11 | parentRoute: 'Configuration',
12 | label: 'NAVIGATOR.FUNCTIONALITIES',
13 | },
14 | children: [],
15 | },
16 | {
17 | name: 'DomainFunctionality',
18 | path: ':domainUuid/parameters/:identifier',
19 | component: ParametersDetailsPage,
20 | meta: {
21 | parentRoute: 'ConfigurationDomainParameters',
22 | requiresAuth: true,
23 | label: 'NAVIGATOR.FUNCTIONALITIES',
24 | },
25 | children: [],
26 | beforeEnter: (to) => {
27 | to.meta.label = to.params.identifier;
28 | },
29 | },
30 | ];
31 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/parameters/services/parameters-api.ts:
--------------------------------------------------------------------------------
1 | import api from '@/api';
2 | import { Functionality } from '@/modules/configuration/pages/parameters/types/Functionality';
3 |
4 | async function getFunctionalties(
5 | domainUuid: string,
6 | options?: { includeSubs?: boolean; parent?: string }
7 | ): Promise {
8 | return await api.get(`domains/${domainUuid}/functionalities`, {
9 | params: {
10 | subs: options?.includeSubs,
11 | parentIdentifier: options?.parent,
12 | },
13 | });
14 | }
15 |
16 | async function getFunctionality(domainUuid: string, identifier: string): Promise {
17 | return await api.get(`domains/${domainUuid}/functionalities/${identifier}`);
18 | }
19 |
20 | async function updateFunctionality(domainUuid: string, functionality: Functionality): Promise {
21 | return await api.put(`domains/${domainUuid}/functionalities/${functionality.identifier}`, functionality);
22 | }
23 |
24 | export { getFunctionalties, getFunctionality, updateFunctionality };
25 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/providers/components/domain-management-warning.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ $t('DOMAIN.WARNING.BACK_TO_CONFIGURATION') }}
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/providers/components/domain-provider-management.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
36 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/providers/hooks/use-providers.ts:
--------------------------------------------------------------------------------
1 | import { storeToRefs } from 'pinia';
2 | import { useAuthStore } from '@/modules/auth/store';
3 | import { useDomainStore } from '@/modules/domain/store';
4 | import { findDomainPage, canAccessPage } from '@/core/services/configuration-pages';
5 |
6 | export default function useProviders() {
7 | const authStore = useAuthStore();
8 | const domainStore = useDomainStore();
9 | const { loggedUser } = storeToRefs(authStore);
10 | const { currentDomain } = storeToRefs(domainStore);
11 |
12 | function isPageAccessible(name: string) {
13 | const page = findDomainPage(name);
14 |
15 | return page && canAccessPage(page, loggedUser.value?.role, currentDomain.value.type);
16 | }
17 |
18 | return { isPageAccessible };
19 | }
20 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/providers/pages/providers-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
37 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/providers/types/Domain.ts:
--------------------------------------------------------------------------------
1 | export enum DOMAIN_TYPE {
2 | ROOT = 'ROOTDOMAIN',
3 | TOP = 'TOPDOMAIN',
4 | SUB = 'SUBDOMAIN',
5 | GUEST = 'GUESTDOMAIN',
6 | }
7 |
8 | export default interface Domain {
9 | uuid: string;
10 | name: string;
11 | description?: string;
12 | language?: 'RUSSIAN' | 'ENGLISH' | 'FRENCH' | 'VIETNAMESE';
13 | creationDate?: number;
14 | modificationDate?: number;
15 | defaultEmailLanguage?: string;
16 | defaultUserRole?: string;
17 | type?: DOMAIN_TYPE;
18 | parent?: Partial;
19 | domainPolicy?: {
20 | name: string;
21 | uuid: string;
22 | };
23 | mailConfiguration?: {
24 | name: string;
25 | uuid: string;
26 | };
27 | mimePolicy?: {
28 | name: string;
29 | uuid: string;
30 | };
31 | welcomeMessage?: {
32 | name: string;
33 | uuid: string;
34 | };
35 | }
36 |
37 | export const EMPTY_DOMAIN: Domain = {
38 | uuid: '',
39 | name: '',
40 | };
41 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/providers/types/GroupProvider.ts:
--------------------------------------------------------------------------------
1 | export interface LDAPGroupProvider {
2 | uuid?: string;
3 | creationDate?: number;
4 | modificationDate?: number;
5 | type?: 'LDAP_PROVIDER';
6 | ldapServer: {
7 | uuid: string;
8 | name: string;
9 | };
10 | groupFilter: {
11 | uuid: string;
12 | name: string;
13 | };
14 | baseDn: string;
15 | searchInOtherDomains: boolean;
16 | }
17 |
18 | export const EMPTY_PROVIDER: LDAPGroupProvider = {
19 | ldapServer: {
20 | uuid: '',
21 | name: '',
22 | },
23 | groupFilter: {
24 | uuid: '',
25 | name: '',
26 | },
27 | baseDn: '',
28 | searchInOtherDomains: false,
29 | };
30 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/providers/types/UserProvider.ts:
--------------------------------------------------------------------------------
1 | export interface OIDCUserProvider {
2 | uuid: string;
3 | creationDate?: number;
4 | modificationDate?: number;
5 | type?: 'OIDC_PROVIDER';
6 | domainDiscriminator?: string;
7 | checkExternalUserID?: boolean;
8 | useAccessClaim?: boolean;
9 | useRoleClaim?: boolean;
10 | useEmailLocaleClaim?: boolean;
11 | }
12 |
13 | export interface LDAPUserProvider {
14 | uuid: string;
15 | creationDate?: number;
16 | modificationDate?: number;
17 | type?: 'LDAP_PROVIDER';
18 | ldapServer?: {
19 | uuid: string;
20 | name: string;
21 | };
22 | userFilter?: {
23 | uuid: string;
24 | name: string;
25 | };
26 | baseDn?: string;
27 | }
28 |
29 | export interface TwakeUserProvider {
30 | uuid: string;
31 | creationDate?: number;
32 | modificationDate?: number;
33 | type?: 'TWAKE_PROVIDER' | 'TWAKE_GUEST_PROVIDER';
34 | twakeServer: {
35 | uuid: string;
36 | name: string;
37 | };
38 | twakeCompanyId: string;
39 | }
40 |
41 | type UserProvider = OIDCUserProvider | LDAPUserProvider | TwakeUserProvider;
42 |
43 | export const EMPTY_PROVIDER = {
44 | uuid: '',
45 | };
46 |
47 | export default UserProvider;
48 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/providers/types/WorkspaceProvider.ts:
--------------------------------------------------------------------------------
1 | export interface LDAPWorkspaceProvider {
2 | uuid?: string;
3 | creationDate?: number;
4 | modificationDate?: number;
5 | type?: 'LDAP_PROVIDER';
6 | ldapServer: {
7 | uuid: string;
8 | name: string;
9 | };
10 | workSpaceFilter: {
11 | uuid: string;
12 | name: string;
13 | };
14 | baseDn: string;
15 | searchInOtherDomains: boolean;
16 | }
17 |
18 | export const EMPTY_PROVIDER: LDAPWorkspaceProvider = {
19 | ldapServer: {
20 | uuid: '',
21 | name: '',
22 | },
23 | workSpaceFilter: {
24 | uuid: '',
25 | name: '',
26 | },
27 | baseDn: '',
28 | searchInOtherDomains: false,
29 | };
30 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/public-keys/components/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store component files of configuration/public-keys module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/public-keys/composables/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the composable methods of configuration/public-keys module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/public-keys/hooks/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the methods used in the hook of configuration/public-keys module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/public-keys/pages/public-keys-page.vue:
--------------------------------------------------------------------------------
1 | Here is public-keys page with domainuuid: {{ currentDomainUuid }}
2 |
12 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/public-keys/pages/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store vue page files of configuration/public-keys module ( the file will be import in the routes)
--------------------------------------------------------------------------------
/src/modules/configuration/pages/public-keys/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import PublicKeysPage from '../pages/public-keys-page.vue';
3 | export const ConfigurationDomainPublicKeysRoutes: RouteRecordRaw[] = [
4 | {
5 | name: 'ConfigurationDomainPublicKeys',
6 | path: ':domainUuid/public-keys',
7 | component: PublicKeysPage,
8 | meta: {
9 | requiresAuth: true,
10 | parentRoute: 'Configuration',
11 | label: 'NAVIGATOR.PUBLIC_KEYS',
12 | },
13 | children: [],
14 | },
15 | ];
16 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/public-keys/router/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store route config files of configuration/public-keys module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/public-keys/services/readme.md:
--------------------------------------------------------------------------------
1 | This directory to store services files of configuration/public-keys module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/public-keys/types/readme.md:
--------------------------------------------------------------------------------
1 | This directory is for storing type declaration files of configuration/public-keys module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/quota/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import QuotaPage from '../pages/quota-page.vue';
3 | export const ConfigurationDomainQuotaRoutes: RouteRecordRaw[] = [
4 | {
5 | name: 'ConfigurationDomainQuota',
6 | path: ':domainUuid/quota',
7 | component: QuotaPage,
8 | meta: {
9 | requiresAuth: true,
10 | parentRoute: 'Configuration',
11 | label: 'NAVIGATOR.QUOTA',
12 | },
13 | children: [],
14 | },
15 | ];
16 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/quota/services/quota-api.ts:
--------------------------------------------------------------------------------
1 | import { AxiosRequestConfig } from 'axios';
2 | import apiv4 from '@/apiv4';
3 | import Quota from '../types/Quota';
4 | import ContainerQuota from '../types/Container';
5 |
6 | async function getQuotaInformations(domainUuid: string) {
7 | return await apiv4.get(`quotas/domains/${domainUuid}`);
8 | }
9 |
10 | async function getQuotaUuid(domainUuid: string) {
11 | return await apiv4.get(`domains/${domainUuid}?parent=false&tree=true`);
12 | }
13 |
14 | async function updateQuota(domainUuid: StringConstructor, quota: Quota): Promise {
15 | return await apiv4.put(`quotas/domains/${domainUuid}`, quota);
16 | }
17 |
18 | async function updateSubdomainQuota(containerUuid: string, ContainerQuota: ContainerQuota): Promise {
19 | return await apiv4.put(`quotas/containers/${containerUuid}`, ContainerQuota);
20 | }
21 |
22 | async function getContainerInformations(containerUuid: string) {
23 | return await apiv4.get(`quotas/containers/${containerUuid}`);
24 | }
25 |
26 | export { getQuotaInformations, updateQuota, getQuotaUuid, getContainerInformations, updateSubdomainQuota };
27 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/quota/types/Container.ts:
--------------------------------------------------------------------------------
1 | export default interface QuotaContainer {
2 | accountQuota: number;
3 | accountQuotaOverride: boolean;
4 | batchModificationDate: number;
5 | creationDate: number;
6 | defaultAccountQuota: number;
7 | defaultAccountQuotaOverride: boolean;
8 | defaultMaxFileSize: number;
9 | defaultMaxFileSizeOverride: boolean;
10 | defaultQuota: number;
11 | defaultQuotaOverride: boolean;
12 | domain: {
13 | identifier: string;
14 | label: string;
15 | type: string;
16 | };
17 | maintenance: boolean;
18 | maxFileSize: number;
19 | maxFileSizeOverride: boolean;
20 | modificationDate: number;
21 | quota: number;
22 | quotaOverride: boolean;
23 | type: string;
24 | usedSpace: number;
25 | uuid: string;
26 | yersterdayUsedSpace: number;
27 | }
28 |
29 | export const EMPTY_CONTAINER: QuotaContainer = {
30 | accountQuota: 0,
31 | accountQuotaOverride: false,
32 | batchModificationDate: 0,
33 | creationDate: 0,
34 | defaultAccountQuota: 0,
35 | defaultAccountQuotaOverride: false,
36 | defaultMaxFileSize: 0,
37 | defaultMaxFileSizeOverride: false,
38 | defaultQuota: 0,
39 | defaultQuotaOverride: false,
40 | domain: {
41 | identifier: '',
42 | label: '',
43 | type: '',
44 | },
45 | maintenance: false,
46 | maxFileSize: 0,
47 | maxFileSizeOverride: false,
48 | modificationDate: 0,
49 | quota: 0,
50 | quotaOverride: false,
51 | type: '',
52 | usedSpace: 0,
53 | uuid: '',
54 | yersterdayUsedSpace: 0,
55 | };
56 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/quota/types/Quota.ts:
--------------------------------------------------------------------------------
1 | export default interface DomainQuota {
2 | creationDate?: number;
3 | domain?: {
4 | label?: string;
5 | identifier?: string;
6 | type?: string;
7 | };
8 | parentDomain?: {
9 | label?: string;
10 | identifier?: string;
11 | type?: string;
12 | };
13 | currentValueForSubdomains?: number;
14 | defaultDomainShared?: boolean;
15 | defaultDomainSharedOverride?: boolean;
16 | defaultQuota: number;
17 | defaultQuotaOverride?: boolean;
18 | maintenance?: boolean;
19 | modificationDate?: number;
20 | quota: number;
21 | quotaOverride?: boolean;
22 | usedSpace: number;
23 | uuid: string;
24 | yersterdayUsedSpace?: number;
25 | batchModificationDate?: number;
26 | domainShared?: boolean;
27 | domainSharedOverride?: boolean;
28 | containerUuids?: string[];
29 | }
30 |
31 | export const EMPTY_QUOTA: DomainQuota = {
32 | creationDate: 0,
33 | currentValueForSubdomains: 0,
34 | defaultDomainShared: false,
35 | defaultDomainSharedOverride: false,
36 | defaultQuota: 0,
37 | defaultQuotaOverride: false,
38 | maintenance: false,
39 | modificationDate: 0,
40 | quota: 0,
41 | quotaOverride: false,
42 | usedSpace: 0,
43 | uuid: '',
44 | yersterdayUsedSpace: 0,
45 | domainShared: false,
46 | domainSharedOverride: false,
47 | };
48 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-filters/composables/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the composable methods of configuration/remote-filter-list module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-filters/hooks/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the methods used in the hook of configuration/remote-filter-list module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-filters/pages/remote-filters-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ $t('DOMAIN.REMOTE_FILTERS_HELPER') }}"
4 |
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
36 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-filters/services/group-filter-api.ts:
--------------------------------------------------------------------------------
1 | import api from '@/api';
2 | import { LDAPGroupFilter } from '../types/GroupFilters';
3 | import Domain from '@/modules/domain/types/Domain';
4 |
5 | async function listGroupFilters(listModel?: boolean): Promise {
6 | return await api.get('group_filters', {
7 | params: { model: listModel },
8 | });
9 | }
10 |
11 | async function createGroupFilter(filter: Omit): Promise {
12 | return await api.post('group_filters', filter);
13 | }
14 |
15 | async function updateGroupFilter(filter: LDAPGroupFilter): Promise {
16 | return await api.put(`group_filters/${filter.uuid}`, filter);
17 | }
18 |
19 | async function getGroupFilter(uuid: string | string[]): Promise {
20 | return await api.get(`group_filters/${uuid}`);
21 | }
22 |
23 | async function getGroupFilterAssociatedDomains(uuid: string | string[]): Promise {
24 | return await api.get(`group_filters/${uuid}/domains`);
25 | }
26 |
27 | async function deleteGroupFilter(uuid: string | string[]): Promise {
28 | return await api.delete(`group_filters/${uuid}`);
29 | }
30 |
31 | export {
32 | createGroupFilter,
33 | deleteGroupFilter,
34 | getGroupFilter,
35 | getGroupFilterAssociatedDomains,
36 | listGroupFilters,
37 | updateGroupFilter,
38 | };
39 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-filters/services/user-filter-api.ts:
--------------------------------------------------------------------------------
1 | import api from '@/api';
2 | import Domain from '@/modules/domain/types/Domain';
3 | import UserFilter from '../types/UserFilter';
4 |
5 | async function listUserFilters(listModel?: boolean): Promise {
6 | return await api.get('user_filters', {
7 | params: {
8 | model: listModel,
9 | },
10 | });
11 | }
12 |
13 | async function createUserFilter(filter: Partial): Promise {
14 | return await api.post('user_filters', filter);
15 | }
16 |
17 | async function updateUserFilter(uuid: string | string[], filter: Partial): Promise {
18 | return await api.put(`user_filters/${uuid}`, filter);
19 | }
20 |
21 | async function getUserFilter(uuid: string | string[]): Promise {
22 | return await api.get(`user_filters/${uuid}`);
23 | }
24 |
25 | async function getAssociatedDomains(uuid: string | string[]): Promise {
26 | return await api.get(`user_filters/${uuid}/domains`);
27 | }
28 |
29 | async function deleteUserFilter(uuid: string | string[]): Promise {
30 | return await api.delete(`user_filters/${uuid}`);
31 | }
32 |
33 | export { listUserFilters, createUserFilter, updateUserFilter, getUserFilter, getAssociatedDomains, deleteUserFilter };
34 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-filters/services/workspace-filter-api.ts:
--------------------------------------------------------------------------------
1 | import api from '@/api';
2 | import Domain from '@/modules/domain/types/Domain';
3 | import { LDAPWorkspaceFilter } from '../types/WorkspaceFilters';
4 |
5 | async function listWorkspaceFilters(listModel?: boolean): Promise {
6 | return await api.get('workspace_filters', {
7 | params: {
8 | model: listModel,
9 | },
10 | });
11 | }
12 |
13 | async function createWorkspaceFilter(filter: LDAPWorkspaceFilter): Promise {
14 | return await api.post('workspace_filters', filter);
15 | }
16 |
17 | async function updateWorkspaceFilter(filter: LDAPWorkspaceFilter): Promise {
18 | return await api.put(`workspace_filters/${filter.uuid}`, filter);
19 | }
20 |
21 | async function getWorkspaceFilter(uuid: string | string[]): Promise {
22 | return await api.get(`workspace_filters/${uuid}`);
23 | }
24 |
25 | async function getWorkspaceFilterAssociatedDomains(uuid: string | string[]): Promise {
26 | return await api.get(`workspace_filters/${uuid}/domains`);
27 | }
28 |
29 | async function deleteWorkspaceFilter(uuid: string | string[]): Promise {
30 | return await api.delete(`workspace_filters/${uuid}`);
31 | }
32 |
33 | export {
34 | createWorkspaceFilter,
35 | deleteWorkspaceFilter,
36 | getWorkspaceFilter,
37 | getWorkspaceFilterAssociatedDomains,
38 | listWorkspaceFilters,
39 | updateWorkspaceFilter,
40 | };
41 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-filters/types/GroupFilters.ts:
--------------------------------------------------------------------------------
1 | export interface LDAPGroupFilter {
2 | uuid: string;
3 | name: string;
4 | description?: string;
5 | type: 'LDAP';
6 | creationDate?: number;
7 | modificationDate?: number;
8 | searchPageSize: number;
9 | searchAllGroupsQuery: string;
10 | searchGroupQuery: string;
11 | groupPrefixToRemove: string;
12 | groupNameAttribute: string;
13 | groupMemberAttribute: string;
14 | memberMailAttribute: string;
15 | memberFirstNameAttribute: string;
16 | memberLastNameAttribute: string;
17 | }
18 |
19 | export const EMPTY_LDAP_GROUP_FILTER: LDAPGroupFilter = {
20 | uuid: '',
21 | name: '',
22 | groupMemberAttribute: '',
23 | groupPrefixToRemove: '',
24 | memberFirstNameAttribute: '',
25 | memberLastNameAttribute: '',
26 | memberMailAttribute: '',
27 | groupNameAttribute: '',
28 | searchAllGroupsQuery: '',
29 | searchGroupQuery: '',
30 | searchPageSize: 1,
31 | type: 'LDAP',
32 | };
33 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-filters/types/UserFilter.ts:
--------------------------------------------------------------------------------
1 | export enum USER_FILTER_TYPE {
2 | LDAP = 'LDAP',
3 | }
4 |
5 | export default interface UserFilter {
6 | uuid: string;
7 | name: string;
8 | description: string;
9 | type: USER_FILTER_TYPE;
10 | creationDate: number;
11 | modificationDate: number;
12 | authenticationQuery: string;
13 | searchUserQuery: string;
14 | autoCompleteCommandOnAllAttributes: string;
15 | autoCompleteCommandOnFirstAndLastName: string;
16 | userMailAttribute: string;
17 | userFirstNameAttribute: string;
18 | userLastNameAttribute: string;
19 | userUidAttribute: string;
20 | searchPageSize: number;
21 | searchSizeLimit: number;
22 | completionPageSize: number;
23 | completionSizeLimit: number;
24 | }
25 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-filters/types/WorkspaceFilters.ts:
--------------------------------------------------------------------------------
1 | export interface LDAPWorkspaceFilter {
2 | uuid: string;
3 | name: string;
4 | description?: string;
5 | type: 'LDAP';
6 | creationDate?: number;
7 | modificationDate?: number;
8 | searchPageSize: number;
9 | searchAllGroupsQuery: string;
10 | searchGroupQuery: string;
11 | groupPrefixToRemove: string;
12 | groupNameAttribute: string;
13 | groupMemberAttribute: string;
14 | memberMailAttribute: string;
15 | memberFirstNameAttribute: string;
16 | memberLastNameAttribute: string;
17 | }
18 |
19 | export const EMPTY_FILTER: LDAPWorkspaceFilter = {
20 | uuid: '',
21 | name: '',
22 | groupMemberAttribute: '',
23 | groupPrefixToRemove: '',
24 | memberFirstNameAttribute: '',
25 | memberLastNameAttribute: '',
26 | memberMailAttribute: '',
27 | groupNameAttribute: '',
28 | searchAllGroupsQuery: '',
29 | searchGroupQuery: '',
30 | searchPageSize: 1,
31 | type: 'LDAP',
32 | };
33 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-servers/hooks/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the methods used in the hook of configuration/remote-servers module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-servers/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import RemoteServersPage from '../pages/remote-servers-page.vue';
3 | export const ConfigurationDomainRemoteServersRoutes: RouteRecordRaw[] = [
4 | {
5 | name: 'ConfigurationDomainRemoteServers',
6 | path: ':domainUuid/remote-servers',
7 | component: RemoteServersPage,
8 | meta: {
9 | requiresAuth: true,
10 | parentRoute: 'Configuration',
11 | label: 'NAVIGATOR.REMOTE_SERVERS',
12 | },
13 | children: [],
14 | },
15 | ];
16 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-servers/services/remote-server-api.ts:
--------------------------------------------------------------------------------
1 | import api from '@/api';
2 | import RemoteServer from '@/modules/remote-server/types/RemoteServer';
3 | import Domain from '@/modules/domain/types/Domain';
4 |
5 | async function listRemoteServers(): Promise {
6 | return await api.get('remote_servers');
7 | }
8 |
9 | async function createRemoteServer(payload: Omit): Promise {
10 | return await api.post('remote_servers', payload);
11 | }
12 |
13 | async function updateRemoteServer(payload: RemoteServer): Promise {
14 | return await api.put(`remote_servers/${payload.uuid}`, payload);
15 | }
16 |
17 | async function getAssociatedDomains(uuid: string): Promise {
18 | return await api.get(`remote_servers/${uuid}/domains`);
19 | }
20 |
21 | async function deleteRemoteServer(uuid: string): Promise {
22 | return await api.delete(`remote_servers/${uuid}`);
23 | }
24 |
25 | export { listRemoteServers, createRemoteServer, updateRemoteServer, getAssociatedDomains, deleteRemoteServer };
26 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/remote-servers/types/RemoteServer.ts:
--------------------------------------------------------------------------------
1 | export interface LDAPRemoteServer {
2 | uuid: string;
3 | name: string;
4 | url: string;
5 | creationDate?: number;
6 | modificationDate?: number;
7 | bindDn?: string;
8 | bindPassword?: string;
9 | serverType: 'LDAP';
10 | }
11 |
12 | export interface TwakeRemoteServer {
13 | uuid: string;
14 | name: string;
15 | url: string;
16 | creationDate?: number;
17 | modificationDate?: number;
18 | clientId?: string;
19 | clientSecret?: string;
20 | serverType: 'TWAKE';
21 | }
22 |
23 | type RemoteServer = LDAPRemoteServer | TwakeRemoteServer;
24 |
25 | export const EMPTY_LDAP_SERVER: LDAPRemoteServer = {
26 | uuid: '',
27 | name: '',
28 | url: '',
29 | serverType: 'LDAP',
30 | };
31 |
32 | export const EMPTY_TWAKE_SERVER: TwakeRemoteServer = {
33 | uuid: '',
34 | name: '',
35 | url: '',
36 | serverType: 'TWAKE',
37 | };
38 |
39 | export default RemoteServer;
40 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/type-mime-policies/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import TypeMimePoliciesPage from '../pages/type-mime-policies-page.vue';
3 |
4 | export const CONFIGURATION_MIME_POLICIES_ROUTE_NAMES = {
5 | ENTRIES: 'ConfigurationDomainTypeMimePolicies',
6 | DETAIL: 'ConfigurationDomainTypeMimePolicyDetail',
7 | };
8 |
9 | export const ConfigurationDomainTypeMimePoliciesRoutes: RouteRecordRaw[] = [
10 | {
11 | name: CONFIGURATION_MIME_POLICIES_ROUTE_NAMES.ENTRIES,
12 | path: ':domainUuid/type-mime-policies',
13 | component: TypeMimePoliciesPage,
14 | meta: {
15 | requiresAuth: true,
16 | parentRoute: 'Configuration',
17 | label: 'NAVIGATOR.TYPE_MIME',
18 | },
19 | children: [],
20 | },
21 | {
22 | name: CONFIGURATION_MIME_POLICIES_ROUTE_NAMES.DETAIL,
23 | path: ':domainUuid/type-mime-policies/:mimePolicyUuid',
24 | component: () => import('@/modules/configuration/pages/type-mime-policies/pages/mime-policy-detail-page.vue'),
25 | meta: {
26 | requiresAuth: true,
27 | parentRoute: CONFIGURATION_MIME_POLICIES_ROUTE_NAMES.ENTRIES,
28 | label: 'NAVIGATOR.TYPE_MIME_DETAILS',
29 | },
30 | children: [],
31 | },
32 | ];
33 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/type-mime-policies/types/MimeType.ts:
--------------------------------------------------------------------------------
1 | export interface MimePolicy {
2 | uuid: string;
3 | creationDate?: number;
4 | name: string;
5 | modificationDate: number;
6 | domainId: string;
7 | domainName: string;
8 | mimeTypes: MimeType[];
9 | assigned?: boolean;
10 | unknownTypeAllowed: boolean;
11 | }
12 |
13 | export interface MimeType {
14 | uuid: string;
15 | mimeType: string;
16 | extensions: string;
17 | enable: boolean;
18 | creationDate: number;
19 | modificationDate: number;
20 | }
21 |
--------------------------------------------------------------------------------
/src/modules/configuration/pages/welcome-messages/composables/readme.md:
--------------------------------------------------------------------------------
1 | This directory is to store the files that declare the composable methods of configuration/welcome-messages module
--------------------------------------------------------------------------------
/src/modules/configuration/pages/welcome-messages/types/WelcomeMessages.ts:
--------------------------------------------------------------------------------
1 | export default interface WelcomeMessage {
2 | uuid: string;
3 | creationDate?: number;
4 | name: string;
5 | modificationDate?: number;
6 | description?: string;
7 | domain?: {
8 | uuid: string;
9 | name: string;
10 | };
11 | entries: Record;
12 | assignedToCurrentDomain?: boolean;
13 | readOnly?: boolean;
14 | }
15 |
16 | export const EMPTY_WELCOME_MESSAGE: WelcomeMessage = {
17 | uuid: '',
18 | name: '',
19 | entries: {
20 | VIETNAMESE: '',
21 | ENGLISH: '',
22 | FRENCH: '',
23 | RUSSIAN: '',
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/src/modules/design-system/pages/data-entry-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/modules/design-system/pages/feedback-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
20 |
--------------------------------------------------------------------------------
/src/modules/design-system/pages/general-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/modules/design-system/pages/index-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/modules/design-system/pages/navigation-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/modules/design-system/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import DesignSystemPage from '../pages/index-page.vue';
3 |
4 | export const DesignSystemRoutes: RouteRecordRaw[] = [
5 | {
6 | name: 'DesignSystem',
7 | path: 'design-system',
8 | component: DesignSystemPage,
9 | meta: {
10 | requiresAuth: false,
11 | },
12 | children: [
13 | {
14 | name: 'DataEntryPage',
15 | path: 'data-entry',
16 | component: () => import('../pages/data-entry-page.vue'),
17 | },
18 | {
19 | name: 'FeedbackPage',
20 | path: 'feedback',
21 | component: () => import('../pages/feedback-page.vue'),
22 | },
23 | {
24 | name: 'FormPage',
25 | path: 'form',
26 | component: () => import('../pages/form-page.vue'),
27 | },
28 | {
29 | name: 'GeneralPage',
30 | path: 'general',
31 | component: () => import('../pages/general-page.vue'),
32 | },
33 | {
34 | name: 'NavigationPage',
35 | path: 'navigation',
36 | component: () => import('../pages/navigation-page.vue'),
37 | },
38 | {
39 | name: 'DomainSelected',
40 | path: 'domains/:domainUuid/quota',
41 | component: () => import('../pages/navigation-page.vue'),
42 | },
43 | ],
44 | },
45 | ];
46 |
--------------------------------------------------------------------------------
/src/modules/domain/components/domain-associated-list-modal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ $t('GENERAL.OK') }}
6 |
7 |
8 |
9 |
10 |
11 |
12 | {{ item.name }}
13 |
14 |
15 | {{ $t(`DOMAIN.TYPES.${item.type}`) }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
34 |
35 |
44 |
--------------------------------------------------------------------------------
/src/modules/domain/hooks/useAssociatedDomainsModal.ts:
--------------------------------------------------------------------------------
1 | import { reactive, ref, UnwrapRef, watchEffect } from 'vue';
2 | import Domain from '../types/Domain';
3 |
4 | export interface AssociatedDomainModalState {
5 | loading: boolean;
6 | visible: boolean;
7 | list: Domain[];
8 | }
9 |
10 | type UsableAssociatedDomainsModal = {
11 | hide: () => void;
12 | show: (uuid: string) => void;
13 | modal: UnwrapRef<{ loading: boolean; visible: boolean; list: Domain[] }>;
14 | };
15 |
16 | export default function useAssociatedDomainsModal(
17 | fetcher: (uuid: string) => Promise
18 | ): UsableAssociatedDomainsModal {
19 | const targetUuid = ref('');
20 | const modal = reactive({
21 | loading: false,
22 | visible: false,
23 | list: [],
24 | });
25 |
26 | watchEffect(() => {
27 | if (!targetUuid.value) return;
28 |
29 | modal.loading = true;
30 | fetcher(targetUuid.value)
31 | .then((domains) => {
32 | modal.list = domains;
33 | })
34 | .finally(() => {
35 | modal.loading = false;
36 | });
37 | });
38 |
39 | function show(uuid: string) {
40 | targetUuid.value = uuid;
41 | modal.visible = true;
42 | }
43 |
44 | function hide() {
45 | modal.visible = false;
46 | }
47 |
48 | return {
49 | hide,
50 | show,
51 | modal,
52 | };
53 | }
54 |
--------------------------------------------------------------------------------
/src/modules/domain/hooks/useFunctionalities.ts:
--------------------------------------------------------------------------------
1 | import { computed, ComputedRef, Ref } from 'vue';
2 | import { useI18n } from 'vue-i18n';
3 | import { Functionality } from '@/core/types/Functionality';
4 |
5 | type UsableFunctionalities = {
6 | getTranslatedText: (functionality: Functionality, key: string) => string;
7 | };
8 |
9 | export default function useFunctionalities(): UsableFunctionalities {
10 | const { t } = useI18n();
11 |
12 | function getTranslatedText(functionality: Functionality, key: string): string {
13 | const i18nKey = `FUNCTIONALITIES.DETAILS.${functionality.identifier}.${key}`;
14 | const i18nValue = t(i18nKey);
15 |
16 | return i18nValue === i18nKey ? t(`FUNCTIONALITIES.DEFAULT.${key}`) : i18nValue;
17 | }
18 |
19 | return {
20 | getTranslatedText,
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/src/modules/domain/pages/domain-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/modules/domain/pages/domain-providers-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
19 |
--------------------------------------------------------------------------------
/src/modules/domain/router/requiresDomainAccessibility.ts:
--------------------------------------------------------------------------------
1 | import { storeToRefs } from 'pinia';
2 | import { Router } from 'vue-router';
3 | import { useDomainStore } from '@/modules/domain/store';
4 | import { useAuthStore } from '@/modules/auth/store';
5 | import { findDomainPage, canAccessPage } from '@/core/services/configuration-pages';
6 |
7 | export const requiresDomainAccessibility = (router: Router): void => {
8 | router.beforeEach((to) => {
9 | if (!to.name || !to.fullPath.includes('/configuration')) {
10 | return;
11 | }
12 | const domainStore = useDomainStore();
13 | const authStore = useAuthStore();
14 | const { currentDomain } = storeToRefs(domainStore);
15 | const { loggedUser } = storeToRefs(authStore);
16 | const page = findDomainPage(to.name);
17 |
18 | if (page && !canAccessPage(page, loggedUser.value?.role, currentDomain.value.type) && !to.meta?.noAccessibility) {
19 | return '/';
20 | }
21 | });
22 | };
23 |
--------------------------------------------------------------------------------
/src/modules/domain/router/requiresDomainUpdate.ts:
--------------------------------------------------------------------------------
1 | import { Router } from 'vue-router';
2 | import { storeToRefs } from 'pinia';
3 | import { useAppStore } from '@/core/store';
4 | import { useDomainStore } from '@/modules/domain/store';
5 | /**
6 | * This guard will detect if a domain uuid is present in the url
7 | * and therefore set the current domain uuid accordingly.
8 | *
9 | * It should be registered before requiresAuthGuard where the
10 | * hydration is triggered.
11 | */
12 | export const requiresDomainUpdate = (router: Router): void => {
13 | router.beforeEach((to, from) => {
14 | const domainStore = useDomainStore();
15 | const appStore = useAppStore();
16 | const domainUuid = to.params.domainUuid as string;
17 | const { currentDomain } = storeToRefs(domainStore);
18 | const hydrated = appStore.hydrated;
19 |
20 | if (!domainUuid || domainUuid === currentDomain.value.uuid) {
21 | return;
22 | }
23 |
24 | domainStore.setCurrentDomainUuid(domainUuid);
25 |
26 | if (hydrated && !from.path.includes('/configuration')) {
27 | domainStore.fetchDomain();
28 | }
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/src/modules/domain/services/domain-api.ts:
--------------------------------------------------------------------------------
1 | import { AxiosRequestConfig } from 'axios';
2 | import api from '@/api';
3 | import apiv4 from '@/apiv4';
4 |
5 | import Domain from '@/modules/domain/types/Domain';
6 | import DomainTreeNode from '../types/DomainTreeNode';
7 | import { PaginatedList } from '@/core/types/PaginatedList';
8 |
9 | async function listDomainsR2(config?: AxiosRequestConfig): Promise> {
10 | return api.get('domains/r2', config);
11 | }
12 |
13 | async function getDomains(config?: AxiosRequestConfig): Promise {
14 | return await api.get('domains', config);
15 | }
16 | async function getDomainsV4(config?: AxiosRequestConfig): Promise {
17 | return await apiv4.get('domains', config);
18 | }
19 |
20 | async function getDomain(uuid: string, configs?: AxiosRequestConfig): Promise {
21 | return await api.get(`domains/${uuid}`, configs);
22 | }
23 |
24 | async function updateDomain(domain: Domain): Promise {
25 | return await api.put(`domains/${domain.uuid}`, domain);
26 | }
27 |
28 | async function createDomain(domain: Omit, dedicatedDomainPolicy = false): Promise {
29 | return await api.post('domains', domain, {
30 | params: { dedicatedDomainPolicy },
31 | });
32 | }
33 |
34 | async function deleteDomain(domain: Domain): Promise {
35 | return await api.delete(`domains/${domain.uuid}`);
36 | }
37 |
38 | export { createDomain, getDomainsV4, deleteDomain, getDomain, getDomains, listDomainsR2, updateDomain };
39 |
--------------------------------------------------------------------------------
/src/modules/domain/types/Domain.ts:
--------------------------------------------------------------------------------
1 | export enum DOMAIN_TYPE {
2 | ROOT = 'ROOTDOMAIN',
3 | TOP = 'TOPDOMAIN',
4 | SUB = 'SUBDOMAIN',
5 | GUEST = 'GUESTDOMAIN',
6 | }
7 |
8 | export default interface Domain {
9 | uuid: string;
10 | name: string;
11 | description?: string;
12 | language?: 'RUSSIAN' | 'ENGLISH' | 'FRENCH' | 'VIETNAMESE';
13 | creationDate?: number;
14 | modificationDate?: number;
15 | defaultEmailLanguage?: string;
16 | defaultUserRole?: string;
17 | type?: DOMAIN_TYPE;
18 | parent?: Partial;
19 | domainPolicy?: {
20 | name: string;
21 | uuid: string;
22 | };
23 | mailConfiguration?: {
24 | name: string;
25 | uuid: string;
26 | };
27 | mimePolicy?: {
28 | name: string;
29 | uuid: string;
30 | };
31 | welcomeMessage?: {
32 | name: string;
33 | uuid: string;
34 | };
35 | }
36 |
37 | export const EMPTY_DOMAIN: Domain = {
38 | uuid: '',
39 | name: '',
40 | };
41 |
--------------------------------------------------------------------------------
/src/modules/domain/types/DomainTreeNode.ts:
--------------------------------------------------------------------------------
1 | import { DOMAIN_TYPE } from './Domain';
2 |
3 | export default interface DomainTreeNode {
4 | uuid: string;
5 | name: string;
6 | type?: DOMAIN_TYPE;
7 | children?: DomainTreeNode[];
8 | checked?: boolean;
9 | }
10 |
11 | export const EMPTY_DOMAIN_NODE: DomainTreeNode = {
12 | uuid: '',
13 | name: '',
14 | };
15 |
--------------------------------------------------------------------------------
/src/modules/inconsistent-users/pages/entries-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
--------------------------------------------------------------------------------
/src/modules/inconsistent-users/pages/inconsistent-users-entries-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
24 |
--------------------------------------------------------------------------------
/src/modules/inconsistent-users/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 |
3 | export const INCONSISTENT_USERS_ROUTE_NAMES = {
4 | ENTRIES: 'InconsistentUsers',
5 | DIAGNOSIC: 'InconsistentUsersDiagnostic',
6 | INCONSISTENT_LIST: 'InconsistentUserList',
7 | };
8 |
9 | export const InconsistentUsersRoutes: Array = [
10 | {
11 | name: INCONSISTENT_USERS_ROUTE_NAMES.ENTRIES,
12 | path: 'inconsistent-users',
13 | component: () => import('../pages/inconsistent-users-entries-page.vue'),
14 | meta: {
15 | parentRoute: 'AdministrationEntries',
16 | label: 'INCONSISTENT_USERS_ROUTE_NAMES.ENTRIES',
17 | requiresAuth: true,
18 | },
19 | children: [
20 | {
21 | name: INCONSISTENT_USERS_ROUTE_NAMES.DIAGNOSIC,
22 | path: 'diagnostic',
23 | component: () => import('../pages/manage-diagnostic-users.vue'),
24 | meta: {
25 | label: 'ADMINISTRATION.NAVIGATOR.DIAGNOSIC',
26 | requiresAuth: true,
27 | },
28 | },
29 | {
30 | name: INCONSISTENT_USERS_ROUTE_NAMES.INCONSISTENT_LIST,
31 | path: 'inconsistent',
32 | component: () => import('../pages/manage-inconsistent-users.vue'),
33 | meta: {
34 | label: 'ADMINISTRATION.NAVIGATOR.INCONSISTENT_USERS',
35 | requiresAuth: true,
36 | },
37 | },
38 | ],
39 | },
40 | ];
41 |
--------------------------------------------------------------------------------
/src/modules/inconsistent-users/store/index.ts:
--------------------------------------------------------------------------------
1 | import Domain from '@/modules/domain/types/Domain';
2 | import dayjs, { Dayjs } from 'dayjs';
3 | import { defineStore } from 'pinia';
4 |
5 | export type ReportingCategory = 'WHOLE_DOMAIN' | 'SHARED_SPACE' | 'MY_SPACE';
6 |
7 | interface ReportingStore {
8 | domains: Domain[];
9 | category: ReportingCategory;
10 | beginDate: Dayjs | null;
11 | endDate: Dayjs | null;
12 | }
13 |
14 | export const useReportingStore = defineStore('reportingStore', {
15 | state: (): ReportingStore => ({
16 | domains: [],
17 | category: 'WHOLE_DOMAIN',
18 | beginDate: dayjs().subtract(7, 'days'),
19 | endDate: dayjs(),
20 | }),
21 | });
22 |
--------------------------------------------------------------------------------
/src/modules/inconsistent-users/types/InconsistentUsers.ts:
--------------------------------------------------------------------------------
1 | import Filters from '@/core/types/Filters';
2 | import { SORT_ORDER } from '@/core/types/Sort';
3 | export interface InconsistentUsers {
4 | creationDate?: number;
5 | domain: string;
6 | domainName: string;
7 | externalMailLocale: string;
8 | locale: string;
9 | modificationDate: number;
10 | uuid: string;
11 | accountType: string;
12 | canCreateGuest: boolean;
13 | canUpload: boolean;
14 | firstName: string;
15 | lastName: string;
16 | mail: string;
17 | role: string;
18 | }
19 |
20 | export interface InconsistentUsersListFilters extends Filters {
21 | domains?: string;
22 | firstName?: string;
23 | lastName?: string;
24 | email?: string;
25 | }
26 |
27 | export interface InconsistentUsersListParameters {
28 | domainId?: string;
29 | firstName?: string;
30 | lastName?: string;
31 | mail?: string;
32 | page?: number;
33 | size?: number;
34 | sortOrder?: SORT_ORDER;
35 | sortField?: string;
36 | }
37 |
--------------------------------------------------------------------------------
/src/modules/password/router/index.ts:
--------------------------------------------------------------------------------
1 | import { NavigationGuard, RouteRecordRaw } from 'vue-router';
2 | import { useAuthStore } from '@/modules/auth/store';
3 | const checkCredentials: NavigationGuard = (to) => {
4 | if (!to.params.email || !to.params.password) {
5 | return '/login';
6 | }
7 | };
8 |
9 | const checkLoggedIn: NavigationGuard = (to) => {
10 | const authStore = useAuthStore();
11 | if (authStore.loggedUser) {
12 | return '/administration';
13 | }
14 | };
15 |
16 | export const LoginRoutes: Array = [
17 | {
18 | name: 'Login',
19 | path: '/login',
20 | props: true,
21 | component: () => import('../pages/login-page.vue'),
22 | beforeEnter: [checkLoggedIn],
23 | },
24 | {
25 | name: 'LoginUsingSecondFactorAuthentication',
26 | path: '/login/2fa',
27 | component: () => import('../pages/login-second-factor.vue'),
28 | props: true,
29 | beforeEnter: [checkCredentials],
30 | },
31 | {
32 | name: 'OIDCCallback',
33 | path: '/oidc/callback',
34 | component: () => import('../components/oidc-callback.vue'),
35 | },
36 | ];
37 |
38 | export const ManageSecondFactorAuthenticationRoute: RouteRecordRaw = {
39 | name: 'ManageSecondFactorAuthentication',
40 | path: '/second_factor_authentication',
41 | component: () => import('../pages/manage-second-factor-authentication.vue'),
42 | meta: {
43 | requiresAuth: true,
44 | },
45 | };
46 |
--------------------------------------------------------------------------------
/src/modules/reporting/components/reporting-page.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
23 |
--------------------------------------------------------------------------------
/src/modules/reporting/components/reporting-statistic-most-uploaded.vue:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
20 |
21 |
22 |
29 |
30 |
31 |
32 |
40 |
--------------------------------------------------------------------------------
/src/modules/reporting/constants/human-mime-type-color.ts:
--------------------------------------------------------------------------------
1 | export const HUMAN_MIME_TYPE_COLOR: Record = {
2 | archive: '#ea3c3c',
3 | audio: '#30cd60',
4 | document: '#007aff',
5 | encrypted: '#ff008a',
6 | image: '#ffa940',
7 | pdf: '#007aff',
8 | text: '#30cd60',
9 | video: '#ffa940',
10 | others: '#007aff',
11 | };
12 |
--------------------------------------------------------------------------------
/src/modules/reporting/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 |
3 | export const ReportingRoute: RouteRecordRaw = {
4 | name: 'Reporting',
5 | path: 'reporting',
6 | component: () => import('../components/reporting-page.vue'),
7 | meta: {
8 | requiresAuth: true,
9 | uiBeta: true,
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/src/modules/reporting/store/index.ts:
--------------------------------------------------------------------------------
1 | import Domain from '@/modules/domain/types/Domain';
2 | import dayjs, { Dayjs } from 'dayjs';
3 | import { defineStore } from 'pinia';
4 |
5 | export type ReportingCategory = 'WHOLE_DOMAIN' | 'SHARED_SPACE' | 'MY_SPACE';
6 |
7 | interface ReportingStorageStore {
8 | domains: Domain[];
9 | category: ReportingCategory;
10 | beginDate: Dayjs | null;
11 | endDate: Dayjs | null;
12 | }
13 |
14 | interface ReportingSharesStore {
15 | domains: Domain[];
16 | beginDate: Dayjs | null;
17 | endDate: Dayjs | null;
18 | top: number;
19 | }
20 |
21 | export const useReportingStore = defineStore('reportingStore', {
22 | state: (): ReportingStorageStore => ({
23 | domains: [],
24 | category: 'WHOLE_DOMAIN',
25 | beginDate: dayjs().subtract(7, 'days'),
26 | endDate: dayjs(),
27 | }),
28 | });
29 |
30 | export const useReportingSharesStore = defineStore('reportingSharesStore', {
31 | state: (): ReportingSharesStore => ({
32 | domains: [],
33 | beginDate: dayjs().subtract(1, 'days'),
34 | endDate: dayjs(),
35 | top: 50,
36 | }),
37 | });
38 |
--------------------------------------------------------------------------------
/src/modules/reporting/types/AccountQuotaStatistic.ts:
--------------------------------------------------------------------------------
1 | export interface AccountQuotaStatistic {
2 | uuid: string;
3 | creationDate: number;
4 | statisticDate: number;
5 | domain: {
6 | uuid: string;
7 | name: string;
8 | };
9 | account: {
10 | uuid: string;
11 | name: string;
12 | email: string;
13 | };
14 | parentDomain: {
15 | uuid: string;
16 | name: string;
17 | };
18 | quota: number;
19 | quotaOverride: boolean;
20 | usedSpace: number;
21 | yesterdayUsedSpace: number;
22 | maintenance: boolean;
23 | batchModificationDate: number;
24 | domainShared: boolean;
25 | domainSharedOverride: boolean;
26 | maxFileSize: number;
27 | maxFileSizeOverride: boolean;
28 | }
29 |
--------------------------------------------------------------------------------
/src/modules/reporting/types/MimeTypeStatistic.ts:
--------------------------------------------------------------------------------
1 | export interface MimeTypeStatistic {
2 | uuid: string;
3 | value: number;
4 | totalSize: number;
5 | domainUuid: string;
6 | type: 'DAILY';
7 | mimeType: string;
8 | humanMimeType: HumanMimeType;
9 | creationDate: number;
10 | statisticDate: number;
11 | }
12 |
13 | export type HumanMimeType =
14 | | 'audio'
15 | | 'video'
16 | | 'text'
17 | | 'image'
18 | | 'pdf'
19 | | 'archive'
20 | | 'encrypted'
21 | | 'document'
22 | | 'others';
23 |
24 | export type StatisticByHumanMimeType = Record<
25 | HumanMimeType,
26 | {
27 | totalSize: number;
28 | totalCount: number;
29 | }
30 | >;
31 |
32 | export type StatisticByMimeType = Record<
33 | string,
34 | {
35 | humanMimeType: HumanMimeType;
36 | totalSize: number;
37 | totalCount: number;
38 | }
39 | >;
40 |
--------------------------------------------------------------------------------
/src/modules/reporting/types/StorageConsumptionStatistic.ts:
--------------------------------------------------------------------------------
1 | export type StorageConsumptionStatisticByDate = Record<
2 | string,
3 | {
4 | countOfAddedFiles: number;
5 | countOfDeletedFiles: number;
6 | countOfFiles: number;
7 | sumOfAddedFiles: number;
8 | sumOfDeletedFiles: number;
9 | diffOperationSum: number;
10 | actualOperationSum: number;
11 | }
12 | >;
13 |
14 | export type StorageConsumtptionStatisticType =
15 | | 'USER_DAILY_STAT'
16 | | 'USER_WEEKLY_STAT'
17 | | 'USER_MONTHLY_STAT'
18 | | 'WORK_GROUP_DAILY_STAT'
19 | | 'WORK_GROUP_WEEKLY_STAT'
20 | | 'WORK_GROUP_MONTHLY_STAT'
21 | | 'DOMAIN_DAILY_STAT'
22 | | 'DOMAIN_WEEKLY_STAT'
23 | | 'DOMAIN_MONTHLY_STAT';
24 |
25 | export interface StorageConsumptionStatistic {
26 | creationDate: number;
27 | statisticDate: number;
28 | domain: {
29 | uuid: string;
30 | name: string;
31 | };
32 | statisticType: StorageConsumtptionStatisticType;
33 | countOfAddedFiles: number;
34 | countOfDeletedFiles: number;
35 | countOfFiles: number;
36 | sumOfAddedFiles: number;
37 | sumOfDeletedFiles: number;
38 | diffOperationSum: number;
39 | actualOperationSum: number;
40 | account: {
41 | uuid: string;
42 | name: string;
43 | };
44 | }
45 |
--------------------------------------------------------------------------------
/src/modules/reporting/types/TopSharesFileCount.ts:
--------------------------------------------------------------------------------
1 | export interface TopSharesFileCountItem {
2 | recipientType: string;
3 | recipientUuid: string;
4 | recipientMail: string;
5 | domainUuid: string;
6 | domainLabel: string;
7 | shareCount: number;
8 | shareTotalSize: number;
9 | }
10 |
11 | export interface TopSharesFileCount {
12 | pageNumber: number;
13 | pageSize: number;
14 | pageResponse: {
15 | total: number;
16 | totalPages: number;
17 | content: TopSharesFileCountItem[];
18 | first: boolean;
19 | last: boolean;
20 | };
21 | total: number;
22 | data: TopSharesFileCountItem[];
23 | defaultPageRequest: {
24 | sort: {
25 | empty: boolean;
26 | sorted: boolean;
27 | unsorted: boolean;
28 | };
29 | offset: number;
30 | pageNumber: number;
31 | pageSize: number;
32 | paged: boolean;
33 | unpaged: boolean;
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/src/modules/reporting/types/TopSharesFileSize.ts:
--------------------------------------------------------------------------------
1 | export interface TopSharesFileSizeItem {
2 | recipientType: string;
3 | recipientUuid: string;
4 | recipientMail: string;
5 | domainUuid: string;
6 | domainLabel: string;
7 | shareCount: number;
8 | shareTotalSize: number;
9 | }
10 |
11 | export interface TopSharesFileSize {
12 | pageNumber: number;
13 | pageSize: number;
14 | pageResponse: {
15 | total: number;
16 | totalPages: number;
17 | content: TopSharesFileSizeItem[];
18 | first: boolean;
19 | last: boolean;
20 | };
21 | total: number;
22 | data: TopSharesFileSizeItem[];
23 | defaultPageRequest: {
24 | sort: {
25 | empty: boolean;
26 | sorted: boolean;
27 | unsorted: boolean;
28 | };
29 | offset: number;
30 | pageNumber: number;
31 | pageSize: number;
32 | paged: boolean;
33 | unpaged: boolean;
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/src/modules/shared-spaces/pages/entries-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
--------------------------------------------------------------------------------
/src/modules/shared-spaces/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import SharedSpacesListEntries from '@/modules/shared-spaces/pages/entries-page.vue';
3 |
4 | export const MY_SHARED_SPACES_ROUTE_NAMES = {
5 | ENTRIES: 'AdministrationSharedSpacesListEntries',
6 | SHARE_SPACES_LIST: 'AdministrationSharedSpacesList',
7 | SHARE_SPACES_DETAIL: 'AdministrationSharedSpaceDetails',
8 | };
9 | export const SharedSpacesRoutes: Array = [
10 | {
11 | name: MY_SHARED_SPACES_ROUTE_NAMES.ENTRIES,
12 | path: 'sharedspaces',
13 | component: SharedSpacesListEntries,
14 | meta: {
15 | requiresAuth: true,
16 | parentRoute: 'AdministrationEntries',
17 | label: 'NAVIGATOR.ADMINISTRATION_CONTACT_LIST',
18 | },
19 | children: [
20 | {
21 | name: MY_SHARED_SPACES_ROUTE_NAMES.SHARE_SPACES_LIST,
22 | path: '',
23 | component: () => import('../pages/manage-shared-spaces.vue'),
24 | meta: {
25 | label: 'NAVIGATOR.MY_SHARED_SPACES',
26 | parentRoute: 'AdministrationEntries',
27 | requiresAuth: true,
28 | },
29 | },
30 | {
31 | name: MY_SHARED_SPACES_ROUTE_NAMES.SHARE_SPACES_DETAIL,
32 | path: ':id',
33 | component: () => import('../components/shared-space-details.vue'),
34 | meta: {
35 | label: 'NAVIGATOR.SHARED_SPACE_DETAILS',
36 | parentRoute: MY_SHARED_SPACES_ROUTE_NAMES.SHARE_SPACES_LIST,
37 | requiresAuth: true,
38 | },
39 | },
40 | ],
41 | },
42 | ];
43 |
--------------------------------------------------------------------------------
/src/modules/shared-spaces/store/index.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia';
2 | import { getSharedSpaceRoles } from '../services/shared-space-api';
3 | import { SHARED_SPACE_TYPE } from '../types/SharedSpace';
4 | import type SharedSpaceRole from '../types/SharedSpaceRole';
5 |
6 | export interface SharedSpaceState {
7 | roles: SharedSpaceRole[];
8 | }
9 |
10 | export const useSharedSpacesStore = defineStore('sharedSpacesStore', {
11 | state: (): SharedSpaceState => ({
12 | roles: [],
13 | }),
14 | getters: {
15 | getRolesByType:
16 | (state) =>
17 | (type: SHARED_SPACE_TYPE): SharedSpaceRole[] =>
18 | state.roles.filter((role) => role.type === type),
19 | },
20 | actions: {
21 | async fetchRoles() {
22 | try {
23 | const workgroupRoles = await getSharedSpaceRoles(SHARED_SPACE_TYPE.WORKGROUP);
24 | const workspaceRoles = await getSharedSpaceRoles(SHARED_SPACE_TYPE.WORKSPACE);
25 |
26 | this.roles = [...workgroupRoles, ...workspaceRoles];
27 | } catch {
28 | this.roles = [];
29 | }
30 | },
31 | },
32 | });
33 |
--------------------------------------------------------------------------------
/src/modules/shared-spaces/types/ShareSpaceList.ts:
--------------------------------------------------------------------------------
1 | import { SORT_ORDER } from '@/core/types/Sort';
2 | import Filters from '@/core/types/Filters';
3 |
4 | export interface SharedSpaceListFilters extends Filters {
5 | name?: string;
6 | account?: string;
7 | nodeType?: string;
8 | domains?: string;
9 | }
10 |
11 | export interface SharedSpaceListParameters {
12 | name?: string;
13 | account?: string;
14 | nodeType?: string;
15 | domains?: string;
16 | page?: number;
17 | size?: number;
18 | sortOrder?: SORT_ORDER;
19 | sortField?: string;
20 | }
21 |
--------------------------------------------------------------------------------
/src/modules/shared-spaces/types/SharedSpace.ts:
--------------------------------------------------------------------------------
1 | export enum SHARED_SPACE_TYPE {
2 | WORKGROUP = 'WORK_GROUP',
3 | WORKSPACE = 'WORK_SPACE',
4 | }
5 | export default interface SharedSpace {
6 | uuid: string;
7 | name: string;
8 | domainUuid?: string;
9 | parentUuid?: string;
10 | parentName?: string;
11 | creationDate?: number;
12 | modificationDate?: number;
13 | nodeType?: SHARED_SPACE_TYPE;
14 | author?: {
15 | name: string;
16 | mail: string;
17 | uuid: string;
18 | };
19 | }
20 |
21 | export const EMPTY_SHARED_SPACE: SharedSpace = {
22 | uuid: '',
23 | name: '',
24 | };
25 |
--------------------------------------------------------------------------------
/src/modules/shared-spaces/types/SharedSpaceAccount.ts:
--------------------------------------------------------------------------------
1 | export default interface SharedSpaceAccount {
2 | uuid: string;
3 | firstName: string;
4 | lastName: string;
5 | mail: string;
6 | }
7 |
--------------------------------------------------------------------------------
/src/modules/shared-spaces/types/SharedSpaceMember.ts:
--------------------------------------------------------------------------------
1 | import SharedSpace, { SHARED_SPACE_TYPE } from './SharedSpace';
2 | import SharedSpaceAccount from './SharedSpaceAccount';
3 | import SharedSpaceRole from './SharedSpaceRole';
4 | import { SORT_ORDER } from '@/core/types/Sort';
5 | import Filters from '@/core/types/Filters';
6 |
7 | export interface SharedSpaceMember {
8 | uuid: string;
9 | type?: SHARED_SPACE_TYPE;
10 | nested?: boolean;
11 | node: Partial;
12 | nestedRole?: Omit;
13 | role: Omit;
14 | account: SharedSpaceAccount;
15 | creationDate?: number;
16 | modificationDate?: number;
17 | }
18 |
19 | export interface SharedSpaceMembersListParameter {
20 | pattern?: string;
21 | type?: string;
22 | roles?: string;
23 | accountUuid?: string;
24 | page?: number;
25 | size?: number;
26 | sortOrder?: SORT_ORDER;
27 | sortField?: string;
28 | }
29 |
30 | export interface MemberListFilters extends Filters {
31 | pattern?: string;
32 | type?: string;
33 | role?: string;
34 | accountUuid?: string;
35 | }
36 |
37 | export const EMPTY_SHARED_SPACE_MEMBER: SharedSpaceMember = {
38 | uuid: '',
39 | node: {},
40 | role: {
41 | name: '',
42 | type: 'WORK_GROUP',
43 | uuid: '',
44 | },
45 | account: {
46 | firstName: '',
47 | lastName: '',
48 | mail: '',
49 | uuid: '',
50 | },
51 | };
52 |
--------------------------------------------------------------------------------
/src/modules/shared-spaces/types/SharedSpaceRole.ts:
--------------------------------------------------------------------------------
1 | export default interface SharedSpaceRole {
2 | uuid: string;
3 | name: string;
4 | enabled?: boolean;
5 | type: 'WORK_SPACE' | 'WORK_GROUP';
6 | }
7 |
--------------------------------------------------------------------------------
/src/modules/upgrades/components/upgrade-list-actions.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {{ $t('GENERAL.REFRESH') }}
17 |
18 |
19 |
20 |
21 |
32 |
57 |
--------------------------------------------------------------------------------
/src/modules/upgrades/services/upgrade-task-api.ts:
--------------------------------------------------------------------------------
1 | import apiv4 from '@/apiv4';
2 | import { UpgradeTask, ConsoleInfos } from '../types/UpgradeTask';
3 |
4 | async function getUpgradeTaskList(): Promise {
5 | return await apiv4.get(`upgrade_tasks`);
6 | }
7 | async function getUpgradeTaskDetail(uuid: string): Promise {
8 | return await apiv4.get(`upgrade_tasks/${uuid}/async_tasks`);
9 | }
10 |
11 | async function upgradeTaskinformations(taskIdentifier: string | string[]): Promise {
12 | return await apiv4.get(`upgrade_tasks/${taskIdentifier}`);
13 | }
14 |
15 | async function upgradeTaskRetry(taskIdentifier: string): Promise {
16 | return await apiv4.put(`upgrade_tasks/${taskIdentifier}?force=true`);
17 | }
18 |
19 | async function getConsoleInformations(
20 | taskIdentifier: string | string[],
21 | uuid: string | string[]
22 | ): Promise {
23 | return await apiv4.get(`upgrade_tasks/${taskIdentifier}/async_tasks/${uuid}/console`);
24 | }
25 |
26 | export { getUpgradeTaskList, getUpgradeTaskDetail, getConsoleInformations, upgradeTaskRetry, upgradeTaskinformations };
27 |
--------------------------------------------------------------------------------
/src/modules/upgrades/types/UpgradeTask.ts:
--------------------------------------------------------------------------------
1 | export interface UpgradeTask {
2 | identifier: string;
3 | taskGroup: string;
4 | parentIdentifier: string;
5 | taskOrder: number;
6 | status: string;
7 | priority: string;
8 | creationDate: number;
9 | modificationDate: number;
10 | asyncTaskUuid: string;
11 | }
12 | export interface ConsoleInfos {
13 | message: string;
14 | criticity: string;
15 | asyncTask: string;
16 | upgradeTask: string;
17 | creationDate: number;
18 | }
19 | export interface AsyncTask {
20 | uuid: string;
21 | status: string;
22 | errorMsg: string;
23 | errorName: string;
24 | errorCode: string;
25 | frequency: string;
26 | fileName: string;
27 | resourceUuid: string;
28 | creationDate: number;
29 | modificationDate: number;
30 | transfertDuration: number;
31 | waitingDuration: number;
32 | processingDuration: number;
33 | }
34 |
--------------------------------------------------------------------------------
/src/modules/user/components/account-autocomplete-item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ data.firstName[0] }}
5 |
6 |
7 | {{ data.firstName }} {{ data.lastName }}
8 | {{ data.mail }}
9 |
10 |
11 |
12 |
13 |
26 |
27 |
62 |
--------------------------------------------------------------------------------
/src/modules/user/hooks/useGuest.ts:
--------------------------------------------------------------------------------
1 | import { addTime, isAfter, isBefore, isValid } from '@/core/utils/date';
2 | import { getMaximumParameter } from '@/core/utils/functionality';
3 | import { storeToRefs } from 'pinia';
4 | import { useAuthStore } from '@/modules/auth/store';
5 | import User from '../types/User';
6 |
7 | type UsableGuest = {
8 | getMaxExpirationDate: (user: User) => Date;
9 | isValidExpirationDate: (user: User, date: Date) => boolean;
10 | };
11 |
12 | export function useGuest(): UsableGuest {
13 | const authStore = useAuthStore();
14 | const { functionalities } = storeToRefs(authStore);
15 |
16 | function getMaxExpirationDate(guest: User): Date {
17 | const max = getMaximumParameter(functionalities.value.GUESTS__EXPIRATION);
18 |
19 | if (max?.type !== 'UNIT_TIME') {
20 | return new Date(NaN);
21 | }
22 |
23 | return addTime(guest.creationDate, max.value, max.unit);
24 | }
25 |
26 | function isValidExpirationDate(guest: User, date: Date | number): boolean {
27 | const maxExpirationDate = getMaxExpirationDate(guest);
28 |
29 | if (isBefore(date, new Date())) {
30 | return false;
31 | }
32 |
33 | if (maxExpirationDate && isValid(maxExpirationDate) && isAfter(date, maxExpirationDate)) {
34 | return false;
35 | }
36 |
37 | return true;
38 | }
39 |
40 | return {
41 | getMaxExpirationDate,
42 | isValidExpirationDate,
43 | };
44 | }
45 |
--------------------------------------------------------------------------------
/src/modules/user/pages/entries-page.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
--------------------------------------------------------------------------------
/src/modules/user/router/index.ts:
--------------------------------------------------------------------------------
1 | import { RouteRecordRaw } from 'vue-router';
2 | import UserListsEntries from '@/modules/user/pages/entries-page.vue';
3 |
4 | export const MY_USERS_ROUTE_NAMES = {
5 | ENTRIES: 'AdministrationUserListsEntries',
6 | USER_LIST: 'UsersList',
7 | USER_DETAIL: 'UserDetail',
8 | };
9 | export const UserRoutes: Array = [
10 | {
11 | name: MY_USERS_ROUTE_NAMES.ENTRIES,
12 | path: 'users',
13 | component: UserListsEntries,
14 | meta: {
15 | requiresAuth: true,
16 | parentRoute: 'AdministrationEntries',
17 | label: 'NAVIGATOR.ADMINISTRATION_CONTACT_LIST',
18 | },
19 | children: [
20 | {
21 | name: MY_USERS_ROUTE_NAMES.USER_LIST,
22 | path: '',
23 | component: () => import('../pages/manage-users.vue'),
24 | meta: {
25 | parentRoute: 'AdministrationEntries',
26 | label: 'NAVIGATOR.MANAGE_USERS',
27 | requiresAuth: true,
28 | },
29 | },
30 | {
31 | name: MY_USERS_ROUTE_NAMES.USER_DETAIL,
32 | path: ':id',
33 | component: () => import('../pages/user-detail.vue'),
34 | meta: {
35 | parentRoute: 'UsersList',
36 | label: 'NAVIGATOR.USER_DETAILS',
37 | requiresAuth: true,
38 | },
39 | },
40 | ],
41 | },
42 | ];
43 |
--------------------------------------------------------------------------------
/src/modules/user/services/guest-api.ts:
--------------------------------------------------------------------------------
1 | import api from '@/api';
2 | import GuestModerator from '../types/GuestModerator';
3 |
4 | async function listGuestModerators(guestUuid: string): Promise {
5 | return await api.get(`guests/${guestUuid}/moderators`);
6 | }
7 |
8 | async function createGuestModerator(guestUuid: string, moderator: GuestModerator): Promise {
9 | return await api.post(`guests/${guestUuid}/moderators`, moderator);
10 | }
11 |
12 | async function removeGuestModerator(guestUuid: string, moderator: GuestModerator): Promise {
13 | return await api.delete(`guests/${guestUuid}/moderators/${moderator.uuid}`, { data: moderator });
14 | }
15 |
16 | async function updateGuestModerator(guestUuid: string, moderator: GuestModerator): Promise {
17 | return await api.put(`guests/${guestUuid}/moderators/${moderator.uuid}`, moderator);
18 | }
19 |
20 | export { createGuestModerator, listGuestModerators, removeGuestModerator, updateGuestModerator };
21 |
--------------------------------------------------------------------------------
/src/modules/user/services/user-utils.ts:
--------------------------------------------------------------------------------
1 | import User from '../types/User';
2 |
3 | export function getUserFullName(user: User): string {
4 | return `${user.firstName || ''} ${user.lastName || ''}`;
5 | }
6 |
--------------------------------------------------------------------------------
/src/modules/user/types/GuestList.ts:
--------------------------------------------------------------------------------
1 | import { SORT_ORDER } from '@/core/types/Sort';
2 | import Filters from '@/core/types/Filters';
3 |
4 | export interface GuestListFilters extends Filters {
5 | firstName?: string;
6 | pattern?: string;
7 | role?: string;
8 | }
9 |
10 | export interface GuestListParameters {
11 | uuid?: string;
12 | pattern?: string;
13 | role?: string;
14 | page?: number;
15 | size?: number;
16 | sortOrder?: SORT_ORDER;
17 | sortField?: string;
18 | }
19 |
20 | export interface Guest {
21 | canUpload: boolean;
22 | comment: string;
23 | creationDate: number;
24 | domain: string;
25 | expirationDate: number;
26 | externalMailLocale: string;
27 | firstName: string;
28 | lastName: string;
29 | locale: string;
30 | mail: string;
31 | modificationDate: number;
32 | restricted: boolean;
33 | uuid: string;
34 | }
35 |
--------------------------------------------------------------------------------
/src/modules/user/types/GuestModerator.ts:
--------------------------------------------------------------------------------
1 | export enum GUEST_MODERATOR_ROLE {
2 | ADMIN = 'ADMIN',
3 | SIMPLE = 'SIMPLE',
4 | }
5 |
6 | export default interface GuestModerator {
7 | uuid: string;
8 | role: GUEST_MODERATOR_ROLE;
9 | creationDate?: number;
10 | modificationDate?: number;
11 | account: {
12 | uuid: string;
13 | name?: string;
14 | email?: string;
15 | domain?: {
16 | uuid: string;
17 | name: string;
18 | };
19 | };
20 | guest: {
21 | uuid: string;
22 | name?: string;
23 | email?: string;
24 | domain?: {
25 | uuid: string;
26 | name: string;
27 | };
28 | };
29 | }
30 |
--------------------------------------------------------------------------------
/src/modules/user/types/RestrictedContact.ts:
--------------------------------------------------------------------------------
1 | export default interface RestrictedContact {
2 | uuid: string;
3 | firstName: string;
4 | lastName: string;
5 | mail: string;
6 | domain: {
7 | uuid: string;
8 | name: string;
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/src/modules/user/types/User.ts:
--------------------------------------------------------------------------------
1 | export enum ACCOUNT_ROLE {
2 | SIMPLE = 'SIMPLE',
3 | ADMIN = 'ADMIN',
4 | SYSTEM = 'SYSTEM',
5 | SUPERADMIN = 'SUPERADMIN',
6 | DELEGATION = 'DELEGATION',
7 | UPLOAD_REQUEST = 'UPLOAD_REQUEST',
8 | SAFE = 'SAFE',
9 | ANONYMOUS = 'ANONYMOUS',
10 | }
11 |
12 | export default interface User {
13 | uuid: string;
14 | mail: string;
15 | firstName: string;
16 | lastName: string;
17 | locked: boolean;
18 | canUpload: boolean;
19 | canCreateGuest: boolean;
20 | comment: string;
21 | externalMailLocale: string;
22 | creationDate: number;
23 | modificationDate: number;
24 | expirationDate?: number;
25 | secondFAUuid: string;
26 | secondFAEnabled: boolean;
27 | quotaUuid: string;
28 | author: {
29 | uuid: string;
30 | email: string;
31 | name: string;
32 | };
33 | domain: {
34 | name: string;
35 | uuid: string;
36 | label?: string;
37 | };
38 | accountType: 'INTERNAL' | 'GUEST' | 'TECHNICAL_ACCOUNT' | 'THREAD' | 'ROOT' | 'SYSTEM';
39 | role: ACCOUNT_ROLE;
40 | restricted: boolean;
41 | authWithOIDC: boolean;
42 | name?: string;
43 | }
44 |
--------------------------------------------------------------------------------
/src/modules/user/types/UserQuota.ts:
--------------------------------------------------------------------------------
1 | import User from './User';
2 |
3 | export default interface UserQuota {
4 | account: Partial;
5 | creationDate: number;
6 | defaultMaxFileSize: number;
7 | defaultQuota: number;
8 | maintenance: boolean;
9 | maxFileSize: number;
10 | modificationDate: number;
11 | realTimeUsedSpace: number;
12 | quota: number;
13 | uuid: string;
14 | usedSpace: number;
15 | yersterdayUsedSpace: number;
16 | }
17 |
--------------------------------------------------------------------------------
/src/modules/user/types/UsersList.ts:
--------------------------------------------------------------------------------
1 | import Filters from '@/core/types/Filters';
2 | import { SORT_ORDER } from '@/core/types/Sort';
3 |
4 | export interface UsersListFilters extends Filters {
5 | domain?: string;
6 | firstName?: string;
7 | lastName?: string;
8 | mail?: string;
9 | role?: string;
10 | type?: string;
11 | restricted?: boolean;
12 | canCreateGuest?: boolean;
13 | canUpload?: boolean;
14 | }
15 |
16 | export interface UsersListParameters {
17 | domain?: string;
18 | firstName?: string;
19 | lastName?: string;
20 | mail?: string;
21 | role?: string;
22 | type?: string;
23 | restricted?: boolean;
24 | canCreateGuest?: boolean;
25 | canUpload?: boolean;
26 | page?: number;
27 | size?: number;
28 | sortOrder?: SORT_ORDER;
29 | sortField?: string;
30 | }
31 |
32 | export interface ModeratorsListParameters {
33 | pattern?: string;
34 | accountType?: string;
35 | domain?: string;
36 | }
37 |
--------------------------------------------------------------------------------
/src/router.d.ts:
--------------------------------------------------------------------------------
1 | import 'vue-router';
2 |
3 | declare module 'vue-router' {
4 | interface RouteMeta {
5 | requiresAuth?: boolean;
6 | uiBeta?: boolean; // Use a different background color
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import type { DefineComponent } from 'vue';
3 | const component: DefineComponent<{}, {}, any>; // eslint-disable-line
4 | export default component;
5 | }
6 |
--------------------------------------------------------------------------------
/src/window.d.ts:
--------------------------------------------------------------------------------
1 | import AppConfiguration from './core/types/AppConfiguration';
2 |
3 | declare global {
4 | interface Window {
5 | APP_CONFIGURATION: AppConfiguration;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "esnext",
5 | "strict": true,
6 | "jsx": "preserve",
7 | "importHelpers": true,
8 | "moduleResolution": "node",
9 | "skipLibCheck": true,
10 | "esModuleInterop": true,
11 | "allowSyntheticDefaultImports": true,
12 | "resolveJsonModule": true,
13 | "sourceMap": true,
14 | "baseUrl": ".",
15 | "paths": {
16 | "@/*": [
17 | "src/*"
18 | ]
19 | },
20 | "lib": [
21 | "esnext",
22 | "dom",
23 | "dom.iterable",
24 | "scripthost"
25 | ]
26 | },
27 | "include": [
28 | "src/**/*.ts",
29 | "src/**/*.tsx",
30 | "src/**/*.vue",
31 | "tests/**/*.ts",
32 | "tests/**/*.tsx"
33 | ],
34 | "exclude": [
35 | "node_modules"
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import vue from '@vitejs/plugin-vue';
3 | import path from 'path';
4 |
5 | export default defineConfig({
6 | plugins: [vue()],
7 | base: './',
8 | resolve: {
9 | alias: [
10 | { find: '@', replacement: path.resolve(__dirname, 'src') },
11 | { find: /^~/, replacement: '' },
12 | ],
13 | },
14 | css: {
15 | preprocessorOptions: {
16 | less: {
17 | additionalData: '@import "@/core/styles/variables.less";',
18 | javascriptEnabled: true,
19 | },
20 | },
21 | },
22 | server: {
23 | port: 20082,
24 | proxy: {
25 | '^/linshare': {
26 | target: process.env.BACKEND_API_URL || 'http://localhost:28080',
27 | changeOrigin: true,
28 | secure: false,
29 | },
30 | },
31 | },
32 | });
33 |
--------------------------------------------------------------------------------