Skip to content

Commit

Permalink
Make erroneous mail accounts not selectable in composer modal
Browse files Browse the repository at this point in the history
Signed-off-by: hamza221 <[email protected]>
  • Loading branch information
hamza221 committed Sep 11, 2023
1 parent 372c9ae commit dc3396b
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 7 deletions.
5 changes: 5 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@
'url' => '/api/accounts/{id}/quota',
'verb' => 'GET'
],
[
'name' => 'accounts#testAccountConnection',
'url' => '/api/accounts/{id}/test',
'verb' => 'GET'
],
[
'name' => 'autoConfig#queryIspdb',
'url' => '/api/autoconfig/ispdb/{email}',
Expand Down
15 changes: 15 additions & 0 deletions lib/Controller/AccountsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -501,4 +501,19 @@ public function updateSmimeCertificate(int $id, ?int $smimeCertificateId = null)
$this->accountService->update($account);
return MailJsonResponse::success();
}

/**
* @NoAdminRequired
*
* @param int $id Account id
* @return JSONResponse
*
* @throws ClientException
*/
public function testAccountConnection(int $id) {
return new JSONResponse([
'data' => $this->accountService->testAccountConnection($this->currentUserId, $id),
]);
}

}
17 changes: 17 additions & 0 deletions lib/Service/AccountService.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,21 @@ public function updateSignature(int $id, string $uid, string $signature = null):
public function getAllAcounts(): array {
return $this->mapper->getAllAccounts();
}


/**
* @param string $currentUserId
* @param int $accountId
* @return bool
*/

public function testAccountConnection(string $currentUserId, int $accountId) :bool {
$account = $this->find($currentUserId, $accountId);
try {
$account->getImapConnection();
return true;
} catch (ServiceException $e) {
return false;
}
}
}
46 changes: 40 additions & 6 deletions src/components/Composer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,27 @@
{{ t('mail', 'From') }}
</label>
<div class="composer-fields--custom">
<Multiselect
<Select
id="from"
:value="selectedAlias"
:options="aliases"
label="name"
track-by="selectId"
:searchable="false"
:custom-label="formatAliases"
:placeholder="t('mail', 'Select account')"
:clear-on-select="false"
@select="onAliasChange" />
:append-to-body="false"
:selectable="(option)=> {
return option.selectable}"
@option:selected="onAliasChange">
<template slot="option" slot-scope="option">
{{ formatAliases(option) }}
</template>

<template slot="selected-option" slot-scope="option">
{{ formatAliases(option) }}
</template>
</Select>
</div>
</div>
<div class="composer-fields">
Expand Down Expand Up @@ -419,7 +429,7 @@ import trimStart from 'lodash/fp/trimCharsStart'
import Autosize from 'vue-autosize'
import debouncePromise from 'debounce-promise'
import { NcActions as Actions, NcActionButton as ActionButton, NcActionCheckbox as ActionCheckbox, NcActionInput as ActionInput, NcActionRadio as ActionRadio, NcButton as ButtonVue, NcMultiselect as Multiselect, NcListItemIcon as ListItemIcon } from '@nextcloud/vue'
import { NcActions as Actions, NcActionButton as ActionButton, NcActionCheckbox as ActionCheckbox, NcActionInput as ActionInput, NcActionRadio as ActionRadio, NcButton as ButtonVue, NcMultiselect as Multiselect, NcSelect as Select, NcListItemIcon as ListItemIcon } from '@nextcloud/vue'
import ChevronLeft from 'vue-material-design-icons/ChevronLeft'
import Delete from 'vue-material-design-icons/Delete'
import ComposerAttachments from './ComposerAttachments'
Expand Down Expand Up @@ -480,6 +490,7 @@ export default {
IconPublic,
IconLinkPicker,
Multiselect,
Select,
TextEditor,
ListItemIcon,
RecipientListItem,
Expand Down Expand Up @@ -587,6 +598,10 @@ export default {
type: Boolean,
default: false,
},
accounts: {
type: Array,
required: true,
},
},
data() {
// Set default custom date time picker value to now + 1 hour
Expand Down Expand Up @@ -649,7 +664,7 @@ export default {
},
aliases() {
let cnt = 0
const accounts = this.$store.getters.accounts.filter((a) => !a.isUnified)
const accounts = this.accounts.filter((a) => !a.isUnified)
const aliases = accounts.flatMap((account) => [
{
id: account.id,
Expand All @@ -661,6 +676,7 @@ export default {
emailAddress: account.emailAddress,
signatureAboveQuote: account.signatureAboveQuote,
smimeCertificateId: account.smimeCertificateId,
selectable: account.connectionStatus,
},
account.aliases.map((alias) => {
return {
Expand All @@ -673,6 +689,7 @@ export default {
emailAddress: alias.alias,
signatureAboveQuote: account.signatureAboveQuote,
smimeCertificateId: alias.smimeCertificateId,
selectable: account.connectionStatus,
}
}),
])
Expand Down Expand Up @@ -1530,7 +1547,7 @@ export default {
min-height: 100px;
}
:deep(.multiselect .multiselect__tags), .subject {
:deep(.multiselect .multiselect__tags),:deep( .vs__dropdown-toggle),:deep(.vs__dropdown-menu), .subject {
border: none !important;
}
:deep([data-select="create"] .avatardiv--unknown) {
Expand All @@ -1540,6 +1557,23 @@ export default {
flex-wrap: wrap;
}
#from{
width: 100%;
cursor: pointer;
}
:deep(.vs__actions){
display: none;
}
:deep(.vs__dropdown-menu){
border: 1px solid var(--color-border) !important;
padding: 0 !important;
border-radius: 0 !important;
}
:deep(.vs__dropdown-option){
border-radius: 0 !important;
}
.submit-message.send.primary.icon-confirm-white {
color: var(--color-main-background);
}
Expand Down
7 changes: 7 additions & 0 deletions src/components/NewMessageModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
:smime-encrypt="composerData.smimeEncrypt"
:is-first-open="modalFirstOpen"
:request-mdn="composerData.requestMdn"
:accounts="accounts"
@update:from-account="patchComposerData({ accountId: $event })"
@update:from-alias="patchComposerData({ aliasId: $event })"
@update:to="patchComposerData({ to: $event })"
Expand Down Expand Up @@ -130,6 +131,12 @@ export default {
NcActionButton,
MinimizeIcon,
},
props: {
accounts: {
type: Array,
required: true,
},
},
data() {
return {
toolbarElements: undefined,
Expand Down
9 changes: 9 additions & 0 deletions src/service/AccountService.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,12 @@ export const updateSmimeCertificate = async (id, smimeCertificateId) => {
const response = await axios.put(url, { smimeCertificateId })
return response.data.data
}

export const testAccountConnection = async (id) => {
const url = generateUrl('/apps/mail/api/accounts/{id}/test', {
id,
})

const resp = await axios.get(url)
return resp.data.data
}
80 changes: 80 additions & 0 deletions src/tests/unit/components/Composer.vue.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ describe('Composer', () => {
propsData: {
inReplyToMessageId: 'abc123',
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
store,
localVue,
Expand All @@ -83,6 +91,14 @@ describe('Composer', () => {
propsData: {
inReplyToMessageId: 'abc123',
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
store,
localVue,
Expand All @@ -101,6 +117,14 @@ describe('Composer', () => {
{ label: 'test', email: '[email protected]' },
],
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
store,
localVue,
Expand All @@ -115,6 +139,14 @@ describe('Composer', () => {
const view = shallowMount(Composer, {
propsData: {
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
computed: {
smimeCertificateForCurrentAlias() {
Expand All @@ -136,6 +168,14 @@ describe('Composer', () => {
const view = shallowMount(Composer, {
propsData: {
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
computed: {
smimeCertificateForCurrentAlias() {
Expand All @@ -157,6 +197,14 @@ describe('Composer', () => {
const view = shallowMount(Composer, {
propsData: {
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
computed: {
smimeCertificateForCurrentAlias() {
Expand All @@ -178,6 +226,14 @@ describe('Composer', () => {
const view = shallowMount(Composer, {
propsData: {
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
computed: {
smimeCertificateForCurrentAlias() {
Expand All @@ -202,6 +258,14 @@ describe('Composer', () => {
const view = shallowMount(Composer, {
propsData: {
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
computed: {
smimeCertificateForCurrentAlias() {
Expand All @@ -226,6 +290,14 @@ describe('Composer', () => {
const view = shallowMount(Composer, {
propsData: {
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
store,
localVue,
Expand All @@ -248,6 +320,14 @@ describe('Composer', () => {
const view = shallowMount(Composer, {
propsData: {
isFirstOpen: true,
accounts: [
{
id: 123,
editorMode: 'plaintext',
isUnified: false,
aliases: [],
},
],
},
store,
localVue,
Expand Down
12 changes: 11 additions & 1 deletion src/views/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<template v-if="hasComposerSession">
<ComposerSessionIndicator @close="onCloseMessageModal" />
<NewMessageModal ref="newMessageModal" />
<NewMessageModal ref="newMessageModal" :accounts="accounts" />
</template>
</Content>
</template>
Expand All @@ -20,6 +20,7 @@ import isMobile from '@nextcloud/vue/dist/Mixins/isMobile'
import '../../css/mail.scss'
import '../../css/mobile.scss'
import { testAccountConnection } from '../service/AccountService'
import logger from '../logger'
import MailboxThread from '../components/MailboxThread'
import Navigation from '../components/Navigation'
Expand All @@ -41,6 +42,7 @@ export default {
data() {
return {
hasComposerSession: false,
accounts: null,
}
},
computed: {
Expand Down Expand Up @@ -74,6 +76,14 @@ export default {
this.hasComposerSession = true
},
},
async beforeMount() {
const accounts = this.$store.getters.accounts.filter((a) => !a.isUnified)
this.accounts = await Promise.all(
accounts.map(async (account) => {
return { ...account, connectionStatus: await testAccountConnection(account.id) }
}))
},
created() {
const accounts = this.$store.getters.accounts
let startMailboxId = this.$store.getters.getPreference('start-mailbox-id')
Expand Down

0 comments on commit dc3396b

Please sign in to comment.