diff --git a/frontend/src/api/credentials.js b/frontend/src/api/credentials.js deleted file mode 100644 index b8f0f7e1a..000000000 --- a/frontend/src/api/credentials.js +++ /dev/null @@ -1,7 +0,0 @@ -import repository from './repository' - -export default { - getCredentials (id) { - return repository.get(`credentials/${id}/`) - } -} diff --git a/frontend/src/components/identities/IdentityList.vue b/frontend/src/components/identities/IdentityList.vue index 657d1a951..910c8bf97 100644 --- a/frontend/src/components/identities/IdentityList.vue +++ b/frontend/src/components/identities/IdentityList.vue @@ -83,9 +83,9 @@ import { bus } from '@/main' import identities from '@/api/identities' import accounts from '@/api/accounts' import aliases from '@/api/aliases' -import credentials from '@/api/credentials' import ConfirmDialog from '@/components/layout/ConfirmDialog' import MenuItems from '@/components/tools/MenuItems' +import repository from '@/api/repository' export default { components: { @@ -205,35 +205,58 @@ export default { this.selected = [] }) }, + downloadFile (options) { + repository.get(options.url).then(resp => { + const url = window.URL.createObjectURL( + new Blob([resp.data], { type: options.content_type })) + const link = document.createElement('a') + link.style.display = 'none' + link.href = url + link.download = options.filename + document.body.appendChild(link) + link.click() + window.URL.revokeObjectURL(link.href) + document.body.removeChild(link) + }) + }, getMenuItems (item) { const result = [] if (item.type === 'account') { item.possible_actions.forEach(element => { result.push({ - label: this.$gettext(element.label), + label: element.label, icon: element.icon, onClick: () => { - if (element.body.type === 'pdfcredentials') { - credentials.getCredentials(item.pk) - .then((response) => { - const blob = new Blob([response.data], { - type: 'application/pdf' - }) - const _url = window.URL.createObjectURL(blob) - window.open(_url, '_blank').focus() - }).catch((err) => { - console.log(err) - }) - this.fetchIdentities() + if (element.type === 'download') { + this.downloadFile(element) } + this.fetchIdentities() } }) }) - result.push({ label: this.$gettext('Edit'), icon: 'mdi-circle-edit-outline', onClick: this.editAccount }) - result.push({ label: this.$gettext('Delete'), icon: 'mdi-delete-outline', onClick: this.deleteAccount, color: 'red' }) + result.push({ + label: this.$gettext('Edit'), + icon: 'mdi-circle-edit-outline', + onClick: this.editAccount + }) + result.push({ + label: this.$gettext('Delete'), + icon: 'mdi-delete-outline', + onClick: this.deleteAccount, + color: 'red' + }) } else if (item.type === 'alias') { - result.push({ label: this.$gettext('Edit'), icon: 'mdi-circle-edit-outline', onClick: this.editAlias }) - result.push({ label: this.$gettext('Delete'), icon: 'mdi-delete-outline', onClick: this.deleteAlias, color: 'red' }) + result.push({ + label: this.$gettext('Edit'), + icon: 'mdi-circle-edit-outline', + onClick: this.editAlias + }) + result.push({ + label: this.$gettext('Delete'), + icon: 'mdi-delete-outline', + onClick: this.deleteAlias, + color: 'red' + }) } return result }, diff --git a/modoboa/admin/api/v2/serializers.py b/modoboa/admin/api/v2/serializers.py index 7f943e67f..3f7759f88 100644 --- a/modoboa/admin/api/v2/serializers.py +++ b/modoboa/admin/api/v2/serializers.py @@ -291,7 +291,10 @@ class IdPossibleActionsSerializer(serializers.Serializer): name = serializers.CharField() icon = serializers.CharField() label = serializers.CharField() - body = serializers.DictField() + type = serializers.CharField() + content_type = serializers.CharField(required=False) + url = serializers.CharField(required=False) + filename = serializers.CharField(required=False) class IdentitySerializer(serializers.Serializer): diff --git a/modoboa/pdfcredentials/api/v2/serializers.py b/modoboa/pdfcredentials/api/v2/serializers.py index 8bc0f20e7..7cb219fce 100644 --- a/modoboa/pdfcredentials/api/v2/serializers.py +++ b/modoboa/pdfcredentials/api/v2/serializers.py @@ -66,4 +66,4 @@ class GetAccountCredentialsSerializer(serializers.Serializer): self.context["content"] = decrypt_file(fname) if param_tools.get_global_parameter("delete_first_dl"): os.remove(fname) - self.context["fname"] = fname + self.context["fname"] = os.path.basename(fname) diff --git a/modoboa/pdfcredentials/api/v2/views.py b/modoboa/pdfcredentials/api/v2/views.py index 4dbae2757..08044981d 100644 --- a/modoboa/pdfcredentials/api/v2/views.py +++ b/modoboa/pdfcredentials/api/v2/views.py @@ -1,5 +1,7 @@ """PDF Credentials API v2 views.""" +import os + from django.utils.translation import ugettext as _ from django.http import HttpResponse @@ -26,14 +28,15 @@ class PDFCredentialView(APIView): def get(self, request, *args, **kwargs): """View to download a document.""" data = {"account_id": kwargs["account_id"]} - serializer = GetAccountCredentialsSerializer(data=data, context={'request': request}) + serializer = GetAccountCredentialsSerializer( + data=data, context={'request': request}) serializer.is_valid(raise_exception=True) serializer.save() content = serializer.context["content"] fname = serializer.context["fname"] resp = HttpResponse(content) - resp["Content-Type"] = "application/pdf;base64" + resp["Content-Type"] = "application/pdf" resp["Content-Length"] = len(content) resp["Content-Disposition"] = f"attachment; filename={fname};" return resp diff --git a/modoboa/pdfcredentials/handlers.py b/modoboa/pdfcredentials/handlers.py index ad809b9d2..c364e98e7 100644 --- a/modoboa/pdfcredentials/handlers.py +++ b/modoboa/pdfcredentials/handlers.py @@ -63,9 +63,14 @@ def extra_identities_actions(sender, account, **kwargs): fname = get_creds_filename(account) if not os.path.exists(fname): return [] + url: str = reverse("v2:get-credentials", args=[account.pk]) + url = url.replace("/api/v2", "") return { "name": "get_credentials", - "body": {"type": "pdfcredentials"}, "icon": "mdi-file-download-outline", - "label": _("Download PDF credentials") + "label": _("Download PDF credentials"), + "type": "download", + "content_type": "application/pdf", + "url": url, + "filename": os.path.basename(fname) }