1072 lines
29 KiB
Vue
1072 lines
29 KiB
Vue
<template>
|
|
<div>
|
|
<a-card class="panel-content">
|
|
<a-form :label-col="labelCol" :wrapper-col="wrapperCol" :labelWrap="true">
|
|
<a-form-item
|
|
:label="$t('components.admin.domains.mailstorage.settings.Type')"
|
|
>
|
|
<a-select v-model:value="page.new.Type" @change="getNew">
|
|
<a-select-option value="pgStorage">PostgreSQL</a-select-option>
|
|
<a-select-option value="maildirStorage">Maildir</a-select-option>
|
|
</a-select>
|
|
</a-form-item>
|
|
|
|
<a-collapse
|
|
:collapsible="!page.contentLoaded ? 'disabled' : undefined"
|
|
v-model:activeKey="page.openPanel"
|
|
accordion
|
|
>
|
|
<a-collapse-panel
|
|
key="1"
|
|
:header="
|
|
$t('components.admin.domains.mailstorage.settings.panel_connect')
|
|
"
|
|
>
|
|
<template v-if="page.new.Type === 'pgStorage'">
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.multi_storage.col_access_key'
|
|
)
|
|
"
|
|
>
|
|
<a-flex gap="small" justify="space-between">
|
|
<a-input disabled v-model:value="page.new.Settings.AccessKey">
|
|
</a-input>
|
|
<a-button
|
|
:disabled="page.old.Type != page.new.Type"
|
|
@click="showEditAccessKey(page.new.Settings.AccessKey)"
|
|
>
|
|
<EditOutlined />
|
|
</a-button>
|
|
</a-flex>
|
|
</a-form-item>
|
|
<a-form-item
|
|
:label="
|
|
$t('components.admin.domains.mailstorage.settings.Host')
|
|
"
|
|
>
|
|
<a-input v-model:value="page.new.Settings.Host"> </a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t('components.admin.domains.mailstorage.settings.Port')
|
|
"
|
|
>
|
|
<a-input-number
|
|
class="form-input-number"
|
|
v-model:value="page.new.Settings.Port"
|
|
>
|
|
</a-input-number>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t('components.admin.domains.mailstorage.settings.MboxesDb')
|
|
"
|
|
>
|
|
<a-input v-model:value="page.new.Settings.MboxesDb"> </a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t('components.admin.domains.mailstorage.settings.User')
|
|
"
|
|
>
|
|
<a-input v-model:value="page.new.Settings.User"> </a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t('components.admin.domains.mailstorage.settings.Pass')
|
|
"
|
|
>
|
|
<a-input-password
|
|
autocomplete="off"
|
|
v-model:value="page.new.Settings.Pass"
|
|
>
|
|
</a-input-password>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t('components.admin.domains.mailstorage.settings.MaxConn')
|
|
"
|
|
>
|
|
<a-input-number
|
|
:min="1"
|
|
class="form-input-number"
|
|
v-model:value="page.new.Settings.MaxConn"
|
|
>
|
|
</a-input-number>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.multi_storage.mailbox_distribution_pattern'
|
|
)
|
|
"
|
|
>
|
|
<a-input
|
|
v-model:value="page.new.Settings.MailboxDistributionPattern"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-collapse
|
|
:collapsible="!page.contentLoaded ? 'disabled' : undefined"
|
|
accordion
|
|
>
|
|
<a-collapse-panel
|
|
:header="
|
|
page.renderMulti
|
|
? $t(
|
|
'components.admin.domains.mailstorage.settings.panel_multi'
|
|
) +
|
|
` (` +
|
|
page.new.Settings.MultiStorageConnects.length +
|
|
` ` +
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.multi_storage.conns_nums'
|
|
) +
|
|
`)`
|
|
: ''
|
|
"
|
|
>
|
|
<a-flex gap="middle" vertical>
|
|
<a-table
|
|
:columns="multiStorageColumns"
|
|
:data-source="page.new.Settings.MultiStorageConnects"
|
|
bordered
|
|
size="small"
|
|
:pagination="false"
|
|
>
|
|
<template #bodyCell="{ column, record }">
|
|
<template v-if="column.key === 'action'">
|
|
<a-space>
|
|
<a-button
|
|
@click="editMultiConnect(record.AccessKey)"
|
|
>
|
|
<EditOutlined />
|
|
{{
|
|
$t(
|
|
"components.admin.domains.mailstorage.settings.multi_storage.edit_action"
|
|
)
|
|
}}
|
|
</a-button>
|
|
<a-popconfirm
|
|
:title="t('common.misc.delete') + '?'"
|
|
:ok-text="t('common.misc.ok')"
|
|
:cancel-text="t('common.misc.cancel')"
|
|
@confirm="deleteMultiConnect(record.AccessKey)"
|
|
>
|
|
<a-button danger>
|
|
<DeleteOutlined />
|
|
{{
|
|
$t(
|
|
"components.admin.domains.mailstorage.settings.multi_storage.delete_action"
|
|
)
|
|
}}
|
|
</a-button>
|
|
</a-popconfirm>
|
|
</a-space>
|
|
</template>
|
|
<template v-if="column.key === 'hostport'">
|
|
{{ record.Host + ":" + record.Port }}
|
|
</template>
|
|
</template>
|
|
</a-table>
|
|
<a-button @click="showAddMultiStorageConnect">
|
|
<PlusOutlined />
|
|
{{
|
|
$t(
|
|
"components.admin.domains.mailstorage.settings.multi_storage.add_connect"
|
|
)
|
|
}}
|
|
</a-button>
|
|
</a-flex>
|
|
</a-collapse-panel>
|
|
</a-collapse>
|
|
</template>
|
|
|
|
<template v-if="page.new.Type === 'maildirStorage'">
|
|
<a-form-item
|
|
style="margin-bottom: -14px"
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.MailDirRoot'
|
|
)
|
|
"
|
|
>
|
|
<a-input v-model:value="page.new.Settings.MailDirRoot">
|
|
</a-input>
|
|
</a-form-item>
|
|
</template>
|
|
</a-collapse-panel>
|
|
|
|
<a-collapse-panel
|
|
key="2"
|
|
:header="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.panel_additional'
|
|
)
|
|
"
|
|
>
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.IMAPDefaultFolders.Archive'
|
|
)
|
|
"
|
|
>
|
|
<a-input
|
|
v-model:value="page.new.Settings.IMAPDefaultFolders.Archive"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.IMAPDefaultFolders.Drafts'
|
|
)
|
|
"
|
|
>
|
|
<a-input
|
|
v-model:value="page.new.Settings.IMAPDefaultFolders.Drafts"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.IMAPDefaultFolders.Junk'
|
|
)
|
|
"
|
|
>
|
|
<a-input
|
|
v-model:value="page.new.Settings.IMAPDefaultFolders.Junk"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.IMAPDefaultFolders.Sent'
|
|
)
|
|
"
|
|
>
|
|
<a-input
|
|
v-model:value="page.new.Settings.IMAPDefaultFolders.Sent"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.IMAPDefaultFolders.Trash'
|
|
)
|
|
"
|
|
>
|
|
<a-input
|
|
v-model:value="page.new.Settings.IMAPDefaultFolders.Trash"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<template v-if="page.new.Type === 'pgStorage'">
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.IMAPDefaultFolders.SharedRoot'
|
|
)
|
|
"
|
|
>
|
|
<a-input
|
|
v-model:value="
|
|
page.new.Settings.IMAPDefaultFolders.SharedRoot
|
|
"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.IMAPDefaultFolders.Recovery'
|
|
)
|
|
"
|
|
>
|
|
<a-input
|
|
disabled
|
|
v-model:value="page.new.Settings.IMAPDefaultFolders.Recovery"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.RecoveryEnabled'
|
|
)
|
|
"
|
|
>
|
|
<a-switch v-model:checked="page.new.Settings.RecoveryEnabled">
|
|
</a-switch>
|
|
</a-form-item>
|
|
</template>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t('components.admin.domains.mailstorage.settings.SmartHost')
|
|
"
|
|
>
|
|
<a-input
|
|
:placeholder="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.SmartHostFormat'
|
|
)
|
|
"
|
|
v-model:value="page.new.Settings.rawSmartHost"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.DefaultUserQuota'
|
|
)
|
|
"
|
|
>
|
|
<a-input-number
|
|
class="form-input-number"
|
|
:addon-after="$t('common.suffixes.mb')"
|
|
v-model:value="page.new.Settings.DefaultUserQuota"
|
|
>
|
|
</a-input-number>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.TrashAdditionalQuota'
|
|
)
|
|
"
|
|
>
|
|
<a-input-number
|
|
:addon-after="$t('common.suffixes.mb')"
|
|
class="form-input-number"
|
|
v-model:value="page.new.Settings.TrashAdditionalQuota"
|
|
>
|
|
</a-input-number>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
style="margin-bottom: -14px"
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.QuotaNotifyThreshold'
|
|
)
|
|
"
|
|
>
|
|
<a-input-number
|
|
:min="0"
|
|
:max="100"
|
|
addon-after="%"
|
|
class="form-input-number"
|
|
v-model:value="page.new.Settings.QuotaNotifyThreshold"
|
|
>
|
|
</a-input-number>
|
|
</a-form-item>
|
|
</a-collapse-panel>
|
|
</a-collapse>
|
|
<br />
|
|
<a-space style="display: flex; justify-content: center">
|
|
<a-button
|
|
class="save-button"
|
|
:loading="page.checkLoading"
|
|
size="large"
|
|
@click="check"
|
|
>
|
|
{{ $t("components.admin.domains.mailstorage.settings.check") }}
|
|
</a-button>
|
|
|
|
<a-button
|
|
:disabled="!page.new.Type || !page.contentLoaded"
|
|
type="primary"
|
|
size="large"
|
|
class="save-button"
|
|
style="width: fit-content"
|
|
@click="save"
|
|
>
|
|
{{
|
|
page.old.Type != page.new.Type
|
|
? $t("components.admin.domains.mailstorage.settings.change")
|
|
: $t("components.admin.domains.mailstorage.settings.save")
|
|
}}
|
|
</a-button>
|
|
</a-space>
|
|
</a-form>
|
|
</a-card>
|
|
<a-modal
|
|
v-model:open="page.showAddEditMultiStorageModal"
|
|
:title="
|
|
page.multiStorageEdit
|
|
? $t(
|
|
`components.admin.domains.mailstorage.settings.multi_storage.edit_connect`
|
|
)
|
|
: $t(
|
|
`components.admin.domains.mailstorage.settings.multi_storage.add_connect`
|
|
)
|
|
"
|
|
>
|
|
<a-divider></a-divider>
|
|
<a-form :label-col="labelCol" :wrapper-col="wrapperCol" :labelWrap="true">
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.multi_storage.col_access_key'
|
|
)
|
|
"
|
|
>
|
|
<a-flex gap="small" justify="space-between">
|
|
<a-input
|
|
:disabled="page.multiStorageEdit"
|
|
v-model:value="page.addEditMultistorageConnect.AccessKey"
|
|
>
|
|
</a-input>
|
|
<a-button
|
|
v-if="page.multiStorageEdit"
|
|
@click="
|
|
showEditAccessKey(page.addEditMultistorageConnect.AccessKey)
|
|
"
|
|
>
|
|
<EditOutlined />
|
|
</a-button>
|
|
</a-flex>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="$t('components.admin.domains.mailstorage.settings.Host')"
|
|
>
|
|
<a-input v-model:value="page.addEditMultistorageConnect.Host">
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="$t('components.admin.domains.mailstorage.settings.Port')"
|
|
>
|
|
<a-input-number
|
|
class="form-input-number"
|
|
v-model:value="page.addEditMultistorageConnect.Port"
|
|
>
|
|
</a-input-number>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="$t('components.admin.domains.mailstorage.settings.MboxesDb')"
|
|
>
|
|
<a-input v-model:value="page.addEditMultistorageConnect.MboxesDb">
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="$t('components.admin.domains.mailstorage.settings.User')"
|
|
>
|
|
<a-input v-model:value="page.addEditMultistorageConnect.User">
|
|
</a-input>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="$t('components.admin.domains.mailstorage.settings.Pass')"
|
|
>
|
|
<a-input-password
|
|
autocomplete="off"
|
|
v-model:value="page.addEditMultistorageConnect.Pass"
|
|
>
|
|
</a-input-password>
|
|
</a-form-item>
|
|
|
|
<a-form-item
|
|
:label="$t('components.admin.domains.mailstorage.settings.MaxConn')"
|
|
>
|
|
<a-input-number
|
|
:min="1"
|
|
class="form-input-number"
|
|
v-model:value="page.addEditMultistorageConnect.MaxConn"
|
|
>
|
|
</a-input-number>
|
|
</a-form-item>
|
|
<a-form-item
|
|
:label="
|
|
$t(
|
|
'components.admin.domains.mailstorage.settings.multi_storage.mailbox_distribution_pattern'
|
|
)
|
|
"
|
|
>
|
|
<a-input
|
|
v-model:value="
|
|
page.addEditMultistorageConnect.MailboxDistributionPattern
|
|
"
|
|
>
|
|
</a-input>
|
|
</a-form-item>
|
|
</a-form>
|
|
|
|
<template #footer>
|
|
<div style="display: flex; justify-content: center">
|
|
<a-button
|
|
v-if="page.renderMulti"
|
|
key="submit"
|
|
size="large"
|
|
@click="saveMultiConnect"
|
|
>{{
|
|
$t(
|
|
`components.admin.domains.mailstorage.settings.multi_storage.save_connect`
|
|
)
|
|
}}</a-button
|
|
>
|
|
</div>
|
|
</template>
|
|
</a-modal>
|
|
<a-modal
|
|
v-model:open="page.editAccessKey.show"
|
|
:title="
|
|
$t(
|
|
`components.admin.domains.mailstorage.settings.multi_storage.edit_access_key`
|
|
)
|
|
"
|
|
style="width: 350px"
|
|
>
|
|
<a-input v-model:value="page.editAccessKey.new"> </a-input>
|
|
|
|
<template #footer>
|
|
<div>
|
|
<a-button
|
|
type="primary"
|
|
:loading="page.editAccessKey.loading"
|
|
@click="saveNewAccessKey"
|
|
>{{
|
|
$t(
|
|
`components.admin.domains.mailstorage.settings.multi_storage.save`
|
|
)
|
|
}}</a-button
|
|
>
|
|
</div>
|
|
</template>
|
|
</a-modal>
|
|
</div>
|
|
</template>
|
|
<script setup lang="ts">
|
|
import { notifyError, notifySuccess } from "@/composables/alert";
|
|
import { apiFetch } from "@/composables/apiFetch";
|
|
import {
|
|
DeleteOutlined,
|
|
EditOutlined,
|
|
ExclamationCircleOutlined,
|
|
PlusOutlined,
|
|
} from "@ant-design/icons-vue";
|
|
import { Modal } from "ant-design-vue";
|
|
import { createVNode, nextTick, onMounted, reactive } from "vue";
|
|
import { saveAndRestart } from "@/composables/restart";
|
|
import { message } from "ant-design-vue";
|
|
import { useI18n } from "vue-i18n";
|
|
import { useRoute } from "vue-router";
|
|
import router from "@/router";
|
|
import type { ColumnType } from "ant-design-vue/es/table";
|
|
import { RouteAdminDashboard } from "@/router/consts";
|
|
import { genRandomString } from "@/composables/misc";
|
|
const route = useRoute();
|
|
|
|
const { t } = useI18n();
|
|
|
|
const multiStorageColumns: ColumnType<any>[] = [
|
|
{
|
|
title: t(
|
|
"components.admin.domains.mailstorage.settings.multi_storage.col_access_key"
|
|
),
|
|
dataIndex: "AccessKey",
|
|
},
|
|
{
|
|
title: t(
|
|
"components.admin.domains.mailstorage.settings.multi_storage.col_hostport"
|
|
),
|
|
key: "hostport",
|
|
},
|
|
{
|
|
key: "action",
|
|
align: "right",
|
|
},
|
|
];
|
|
|
|
interface SmartHost {
|
|
Host: string;
|
|
Port: number;
|
|
User: string;
|
|
Pass: string;
|
|
}
|
|
|
|
interface MultiStorageConnect {
|
|
AccessKey: string;
|
|
MailboxDistributionPattern: string;
|
|
Host: string;
|
|
Port: number;
|
|
User: string;
|
|
Pass: string;
|
|
MaxConn: number;
|
|
MboxesDb: string;
|
|
}
|
|
|
|
interface Settings {
|
|
AccessKey: string;
|
|
MailboxDistributionPattern: string;
|
|
Host: string;
|
|
Port: number;
|
|
MboxesDb: string;
|
|
User: string;
|
|
Pass: string;
|
|
MaxConn: number;
|
|
IMAPDefaultFolders: {
|
|
Archive: string;
|
|
Drafts: string;
|
|
Junk: string;
|
|
Sent: string;
|
|
Trash: string;
|
|
SharedRoot: string;
|
|
Recovery: string;
|
|
};
|
|
MailDirRoot: string;
|
|
MaildirInboxPath: string;
|
|
RecoveryEnabled: boolean;
|
|
rawSmartHost: string;
|
|
SmartHost: SmartHost | null;
|
|
DefaultUserQuota: number;
|
|
TrashAdditionalQuota: number;
|
|
QuotaNotifyThreshold: number;
|
|
MultiStorageConnects: MultiStorageConnect[];
|
|
}
|
|
|
|
function getEmptySettings(): Settings {
|
|
return {
|
|
AccessKey: "",
|
|
MailboxDistributionPattern: "",
|
|
Host: "",
|
|
Port: 0,
|
|
MboxesDb: "",
|
|
User: "",
|
|
Pass: "",
|
|
MaxConn: 0,
|
|
IMAPDefaultFolders: {
|
|
Archive: "",
|
|
Drafts: "",
|
|
Junk: "",
|
|
Sent: "",
|
|
Trash: "",
|
|
SharedRoot: "",
|
|
Recovery: "",
|
|
},
|
|
MailDirRoot: "",
|
|
MaildirInboxPath: "",
|
|
RecoveryEnabled: false,
|
|
rawSmartHost: "",
|
|
SmartHost: {
|
|
Host: "",
|
|
Port: 0,
|
|
User: "",
|
|
Pass: "",
|
|
},
|
|
DefaultUserQuota: 0,
|
|
TrashAdditionalQuota: 0,
|
|
QuotaNotifyThreshold: 0,
|
|
MultiStorageConnects: [],
|
|
};
|
|
}
|
|
|
|
function getEmptyMultiStorageConnect(): MultiStorageConnect {
|
|
return {
|
|
AccessKey: "",
|
|
MailboxDistributionPattern: "*",
|
|
Host: "",
|
|
Port: 0,
|
|
MboxesDb: "",
|
|
User: "",
|
|
Pass: "",
|
|
MaxConn: 0,
|
|
};
|
|
}
|
|
|
|
const page = reactive<{
|
|
renderMulti: boolean;
|
|
showAddEditMultiStorageModal: boolean;
|
|
multiStorageEdit: boolean;
|
|
addEditMultistorageConnect: MultiStorageConnect;
|
|
openPanel: any;
|
|
domain: string;
|
|
contentLoaded: boolean;
|
|
checkLoading: boolean;
|
|
new: {
|
|
Type: string;
|
|
Settings: Settings;
|
|
};
|
|
old: {
|
|
Type: string;
|
|
Settings: Settings;
|
|
};
|
|
editAccessKey: {
|
|
show: boolean;
|
|
old: string;
|
|
new: string;
|
|
loading: boolean;
|
|
};
|
|
}>({
|
|
renderMulti: true,
|
|
showAddEditMultiStorageModal: false,
|
|
multiStorageEdit: false,
|
|
addEditMultistorageConnect: getEmptyMultiStorageConnect(),
|
|
openPanel: ["1"],
|
|
domain: "",
|
|
contentLoaded: false,
|
|
checkLoading: false,
|
|
new: {
|
|
Type: "",
|
|
Settings: getEmptySettings(),
|
|
},
|
|
old: {
|
|
Type: "",
|
|
Settings: getEmptySettings(),
|
|
},
|
|
editAccessKey: {
|
|
show: false,
|
|
old: "",
|
|
new: "",
|
|
loading: false,
|
|
},
|
|
});
|
|
|
|
const labelCol = { span: 16, style: { "text-align": "left" } };
|
|
const wrapperCol = { span: 8 };
|
|
|
|
onMounted(() => {
|
|
page.domain = route.params.domain as string;
|
|
get();
|
|
});
|
|
|
|
function marshalSmarthost(sh: SmartHost | null): string {
|
|
if (!sh) {
|
|
return "";
|
|
}
|
|
|
|
let res = "";
|
|
if (sh.User != "") {
|
|
res = sh.User + ":" + sh.Pass + "@";
|
|
}
|
|
|
|
return res + sh.Host + ":" + sh.Port;
|
|
}
|
|
|
|
function unmarshalSmarthost(sh: string): SmartHost {
|
|
let res: SmartHost = {
|
|
Host: "",
|
|
Port: 0,
|
|
User: "",
|
|
Pass: "",
|
|
};
|
|
|
|
if (!sh) {
|
|
return res;
|
|
}
|
|
|
|
let parts = sh.split("@");
|
|
|
|
if (parts.length == 2) {
|
|
let auth = parts[0].split(":");
|
|
if (auth.length == 2) {
|
|
res.User = auth[0];
|
|
res.Pass = auth[1];
|
|
} else {
|
|
throw "Unknown smarthost format";
|
|
}
|
|
|
|
parts[0] = parts[1];
|
|
}
|
|
|
|
let main = parts[0].split(":");
|
|
if (main.length == 2) {
|
|
res.Host = main[0];
|
|
res.Port = Number(main[1]);
|
|
} else {
|
|
throw "Unknown smarthost format";
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
async function get() {
|
|
const res = await apiFetch(
|
|
`/admin/domains/${page.domain}/mailstorage/settings`
|
|
);
|
|
|
|
if (res.error) {
|
|
notifyError(res.error);
|
|
return;
|
|
}
|
|
|
|
res.data.Settings.rawSmartHost = marshalSmarthost(
|
|
res.data.Settings.SmartHost
|
|
);
|
|
|
|
if (res.data.Settings.MultiStorageConnects === undefined) {
|
|
res.data.Settings.MultiStorageConnects = [];
|
|
}
|
|
|
|
page.new = { ...res.data };
|
|
page.old = { ...res.data };
|
|
|
|
page.contentLoaded = true;
|
|
|
|
return;
|
|
}
|
|
|
|
async function getNew() {
|
|
if (page.new.Type === page.old.Type) {
|
|
page.new = { ...page.old };
|
|
return;
|
|
}
|
|
|
|
const res = await apiFetch(
|
|
`/admin/domains/${page.domain}/mailstorage/settings/new?type=${page.new.Type}`
|
|
);
|
|
|
|
if (res.error) {
|
|
notifyError(res.error);
|
|
return;
|
|
}
|
|
|
|
page.contentLoaded = true;
|
|
|
|
if (res.data.Settings.MultiStorageConnects === undefined) {
|
|
res.data.Settings.MultiStorageConnects = [];
|
|
}
|
|
|
|
page.new = res.data;
|
|
|
|
return;
|
|
}
|
|
|
|
async function save() {
|
|
try {
|
|
page.new.Settings.SmartHost = unmarshalSmarthost(
|
|
page.new.Settings.rawSmartHost
|
|
);
|
|
} catch {
|
|
notifyError("Unknown smarthost format");
|
|
return;
|
|
}
|
|
|
|
const res = await apiFetch(
|
|
`/admin/domains/${page.domain}/mailstorage/settings`,
|
|
{
|
|
method: "POST",
|
|
body: page.new,
|
|
}
|
|
);
|
|
|
|
if (res.error) {
|
|
notifyError(res.error);
|
|
return;
|
|
}
|
|
|
|
notifySuccess(
|
|
t("components.admin.domains.mailstorage.settings.save_success")
|
|
);
|
|
|
|
router.go(0);
|
|
|
|
return;
|
|
}
|
|
|
|
async function check() {
|
|
page.checkLoading = true;
|
|
const res = await apiFetch(
|
|
`/admin/domains/${page.domain}/mailstorage/settings/check`,
|
|
{
|
|
method: "POST",
|
|
body: page.new,
|
|
}
|
|
);
|
|
page.checkLoading = false;
|
|
if (res.error) {
|
|
notifyError(
|
|
t("components.admin.domains.mailstorage.settings.check_error") + res.error
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
notifySuccess(
|
|
t("components.admin.domains.mailstorage.settings.check_success")
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
function deleteMultiConnect(accessKey: string) {
|
|
let newConnects: MultiStorageConnect[];
|
|
newConnects = [];
|
|
page.new.Settings.MultiStorageConnects.forEach((msc) => {
|
|
if (msc.AccessKey !== accessKey) {
|
|
newConnects.push(msc);
|
|
}
|
|
});
|
|
|
|
page.new.Settings.MultiStorageConnects = newConnects;
|
|
page.renderMulti = false;
|
|
nextTick(() => {
|
|
page.renderMulti = true;
|
|
});
|
|
}
|
|
|
|
function editMultiConnect(accessKey: string) {
|
|
for (let i = 0; i < page.new.Settings.MultiStorageConnects.length; i++) {
|
|
const el = page.new.Settings.MultiStorageConnects[i];
|
|
if (el.AccessKey === accessKey) {
|
|
page.addEditMultistorageConnect = {
|
|
...page.new.Settings.MultiStorageConnects[i],
|
|
};
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
page.multiStorageEdit = true;
|
|
page.showAddEditMultiStorageModal = true;
|
|
}
|
|
|
|
function saveMultiConnect() {
|
|
if (page.multiStorageEdit) {
|
|
for (let i = 0; i < page.new.Settings.MultiStorageConnects.length; i++) {
|
|
const el = page.new.Settings.MultiStorageConnects[i];
|
|
if (el.AccessKey === page.addEditMultistorageConnect.AccessKey) {
|
|
page.new.Settings.MultiStorageConnects[i] =
|
|
page.addEditMultistorageConnect;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
let allAccessKeys = [...page.new.Settings.AccessKey];
|
|
|
|
for (let i = 0; i < page.new.Settings.MultiStorageConnects.length; i++) {
|
|
allAccessKeys.push(page.new.Settings.MultiStorageConnects[i].AccessKey);
|
|
}
|
|
|
|
for (let i = 0; i < allAccessKeys.length; i++) {
|
|
if (allAccessKeys[i] === page.addEditMultistorageConnect.AccessKey) {
|
|
notifyError("Key must be unique");
|
|
return;
|
|
}
|
|
}
|
|
|
|
page.new.Settings.MultiStorageConnects.push(
|
|
page.addEditMultistorageConnect
|
|
);
|
|
}
|
|
page.showAddEditMultiStorageModal = false;
|
|
page.renderMulti = false;
|
|
nextTick(() => {
|
|
page.renderMulti = true;
|
|
});
|
|
}
|
|
|
|
async function showAddMultiStorageConnect() {
|
|
page.addEditMultistorageConnect = getEmptyMultiStorageConnect();
|
|
|
|
const res = await apiFetch(
|
|
`/admin/domains/${page.domain}/mailstorage/settings/new?type=${page.new.Type}`
|
|
);
|
|
|
|
if (res.error) {
|
|
notifyError(res.error);
|
|
return;
|
|
}
|
|
|
|
page.addEditMultistorageConnect.Host = res.data.Settings.Host;
|
|
page.addEditMultistorageConnect.Port = res.data.Settings.Port;
|
|
page.addEditMultistorageConnect.User = res.data.Settings.User;
|
|
page.addEditMultistorageConnect.Pass = res.data.Settings.Pass;
|
|
page.addEditMultistorageConnect.MaxConn = res.data.Settings.MaxConn;
|
|
page.addEditMultistorageConnect.MboxesDb = res.data.Settings.MboxesDb;
|
|
page.addEditMultistorageConnect.MailboxDistributionPattern =
|
|
res.data.Settings.MailboxDistributionPattern;
|
|
page.addEditMultistorageConnect.AccessKey = res.data.Settings.AccessKey;
|
|
|
|
page.multiStorageEdit = false;
|
|
page.showAddEditMultiStorageModal = true;
|
|
}
|
|
|
|
async function showEditAccessKey(old: string) {
|
|
page.editAccessKey.old = old;
|
|
page.editAccessKey.new = old;
|
|
page.editAccessKey.show = true;
|
|
}
|
|
|
|
async function saveNewAccessKey() {
|
|
page.editAccessKey.loading = true;
|
|
const res = await apiFetch(
|
|
`/admin/domains/${page.domain}/mailstorage/settings/change_access_key`,
|
|
{
|
|
method: "POST",
|
|
body: {
|
|
old: page.editAccessKey.old,
|
|
new: page.editAccessKey.new,
|
|
},
|
|
}
|
|
);
|
|
page.editAccessKey.loading = false;
|
|
if (res.error) {
|
|
notifyError(res.error);
|
|
return;
|
|
}
|
|
|
|
page.editAccessKey.show = false;
|
|
|
|
notifySuccess(
|
|
t("components.admin.domains.mailstorage.settings.save_success")
|
|
);
|
|
|
|
router.go(0);
|
|
return;
|
|
}
|
|
|
|
// function generateNewAccessKey(): string {
|
|
// let key = "";
|
|
// while (key === "") {
|
|
// key = genRandomString(8);
|
|
// console.log(page.new.Settings.MultiStorageConnects);
|
|
// page.new.Settings.MultiStorageConnects.forEach((msc) => {
|
|
// if (msc.AccessKey === key) {
|
|
// key = "";
|
|
// }
|
|
// });
|
|
// }
|
|
// return key;
|
|
// }
|
|
</script>
|
|
|
|
<style scoped>
|
|
.panel-content {
|
|
min-width: 600px;
|
|
max-width: 60%;
|
|
margin: auto;
|
|
}
|
|
.input-number {
|
|
width: 50%;
|
|
}
|
|
.save-button {
|
|
}
|
|
</style>
|