797 lines
21 KiB
JavaScript
797 lines
21 KiB
JavaScript
import './Setup.js'
|
|
|
|
import {computed, onUnmounted, reactive, ref} from 'vue'
|
|
|
|
import {ElMessage} from 'element-plus'
|
|
|
|
import lang from '../../i18n/i18n';
|
|
|
|
import axios from 'axios'
|
|
|
|
import {Plus} from '@element-plus/icons-vue'
|
|
|
|
import {http} from "@/utils/axios";
|
|
|
|
import {buildFinalURL as buildSetupFinalURL, probeService} from './SetupNavigation.js'
|
|
|
|
let setupBootstrapPromise = null
|
|
|
|
const ensureSetupSession = () => {
|
|
if (!import.meta.env.DEV) {
|
|
return Promise.resolve()
|
|
}
|
|
|
|
if (!setupBootstrapPromise) {
|
|
setupBootstrapPromise = http.get("/__smail_setup_bootstrap").catch((error) => {
|
|
setupBootstrapPromise = null
|
|
if (error?.response?.status === 500 || !error?.response) {
|
|
throw new Error(lang.setup_service_unavailable)
|
|
}
|
|
throw error
|
|
})
|
|
}
|
|
|
|
return setupBootstrapPromise
|
|
}
|
|
|
|
const setupRequest = (payload) => ensureSetupSession().then(() => http.post("/api/v1/setup", payload)).then((response) => {
|
|
if (!response || typeof response.errorNo !== "number") {
|
|
throw new Error(lang.setup_failed)
|
|
}
|
|
return response
|
|
})
|
|
|
|
const getSetupErrorMessage = (error, fallback = lang.setup_failed) => {
|
|
const message = typeof error?.message === "string" ? error.message.trim() : ""
|
|
if (message && message !== "Network Error" && !/^timeout of \d+ms exceeded$/i.test(message)) {
|
|
return message
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
const showSetupError = (error, fallback = lang.setup_failed) => {
|
|
const message = getSetupErrorMessage(error, fallback)
|
|
ElMessage.error(message)
|
|
return message
|
|
}
|
|
|
|
const assertSetupSuccess = (response, fallback = lang.setup_failed) => {
|
|
if (response.errorNo !== 0) {
|
|
throw new Error(response.errorMsg || fallback)
|
|
}
|
|
return response
|
|
}
|
|
|
|
export function usePage() {
|
|
const waitDesc = ref(lang.wait_desc);
|
|
|
|
const adminSettings = reactive({
|
|
"account": "",
|
|
"password": "",
|
|
"password2": "",
|
|
"hadSeted": false
|
|
})
|
|
|
|
const dbSettings = reactive({
|
|
"type": "sqlite",
|
|
"dsn": "./data/smail.db",
|
|
"mode": "fields",
|
|
"user": "",
|
|
"host": "127.0.0.1",
|
|
"port": "3306",
|
|
"password": "",
|
|
"name": "smail"
|
|
})
|
|
|
|
const domainSettings = reactive({
|
|
"web_domain": "",
|
|
"smtp_domain": "",
|
|
"public_https_port": "",
|
|
"multi_domain": []
|
|
})
|
|
|
|
const sslSettings = reactive({
|
|
"type": "0",
|
|
"challenge": "",
|
|
"key_path": "./data/ssl/private.key",
|
|
"crt_path": "./data/ssl/public.crt",
|
|
"paramsList": [],
|
|
})
|
|
|
|
const active = ref(0)
|
|
|
|
const fullscreenLoading = ref(false)
|
|
|
|
const databaseLoading = ref(false)
|
|
const stepLoading = ref(false)
|
|
|
|
const databaseError = ref("")
|
|
|
|
const getDatabaseErrorMessage = (error) => {
|
|
const message = typeof error?.message === "string" ? error.message.trim() : ""
|
|
if (message && !/^network error$/i.test(message) && !/^timeout of \d+ms exceeded$/i.test(message) && !/^request failed with status code \d+$/i.test(message)) {
|
|
return message
|
|
}
|
|
return lang.db_request_failed
|
|
}
|
|
|
|
const dnsChecking = ref(false)
|
|
const dnsChallengeNotice = ref("")
|
|
|
|
const dnsInfos = ref({})
|
|
const dnsMailIPv4 = ref('')
|
|
const dnsAppliedIPv4 = ref('')
|
|
const dnsLoading = ref(false)
|
|
const dnsError = ref('')
|
|
const dnsInputPending = computed(() => dnsMailIPv4.value.trim() !== dnsAppliedIPv4.value)
|
|
const hasUnavailableDNS = computed(() => Object.values(dnsInfos.value).some((records) =>
|
|
records.some((record) => record.unavailableReason || !record.value)
|
|
))
|
|
|
|
const hasDNSIPv6 = computed(() => Object.values(dnsInfos.value).some((records) =>
|
|
records.some((record) => record.type === 'AAAA')
|
|
))
|
|
|
|
const port = ref(80)
|
|
const sslRuntime = ref({})
|
|
const proxyHTTPS = computed(() => sslRuntime.value.tlsMode === 'proxy')
|
|
|
|
const addDomain = () => {
|
|
domainSettings.multi_domain.push([])
|
|
}
|
|
|
|
const setPassword = () => {
|
|
if (adminSettings.hadSeted) {
|
|
return getDomainConfig().then((response) => {
|
|
if (response) {
|
|
active.value++
|
|
}
|
|
})
|
|
}
|
|
|
|
const passwordSize = new TextEncoder().encode(adminSettings.password).length
|
|
if (!adminSettings.account.trim()) {
|
|
ElMessage.error(lang.err_account_required)
|
|
return
|
|
}
|
|
if (!adminSettings.password) {
|
|
ElMessage.error(lang.err_required_pwd)
|
|
return
|
|
}
|
|
if (passwordSize < 8 || passwordSize > 12) {
|
|
ElMessage.error(lang.err_admin_pwd_length)
|
|
return
|
|
}
|
|
if (adminSettings.password !== adminSettings.password2) {
|
|
ElMessage.error(lang.err_pwd_diff)
|
|
return
|
|
}
|
|
|
|
return setupRequest({
|
|
"action": "set",
|
|
"step": "password",
|
|
"account": adminSettings.account,
|
|
"password": adminSettings.password
|
|
}).then((res) => {
|
|
assertSetupSuccess(res)
|
|
return getDomainConfig().then((response) => {
|
|
if (response) {
|
|
active.value++
|
|
}
|
|
})
|
|
}).catch((error) => {
|
|
showSetupError(error)
|
|
})
|
|
}
|
|
const getPassword = () => setupRequest({"action": "get", "step": "password"}).then((res) => {
|
|
assertSetupSuccess(res, lang.db_init_failed)
|
|
adminSettings.hadSeted = res.data != ""
|
|
if (adminSettings.hadSeted) {
|
|
adminSettings.account = res.data
|
|
adminSettings.password = "*******"
|
|
adminSettings.password2 = "*******"
|
|
}
|
|
return res
|
|
})
|
|
|
|
const getDbConfig = () => {
|
|
return setupRequest({"action": "get", "step": "database"}).then((res) => {
|
|
assertSetupSuccess(res, lang.db_request_failed)
|
|
dbSettings.type = res.data.db_type;
|
|
dbSettings.mode = res.data.db_mode || "dsn";
|
|
dbSettings.dsn = res.data.db_dsn || "";
|
|
dbSettings.user = res.data.db_user || "";
|
|
dbSettings.host = res.data.db_host || "127.0.0.1";
|
|
dbSettings.port = res.data.db_port || (dbSettings.type === "postgres" ? "5432" : "3306");
|
|
dbSettings.password = "";
|
|
dbSettings.name = res.data.db_name || "smail";
|
|
return res
|
|
}).catch((error) => {
|
|
databaseError.value = getDatabaseErrorMessage(error)
|
|
ElMessage.error(databaseError.value)
|
|
return null
|
|
})
|
|
}
|
|
const getDomainConfig = () => {
|
|
return setupRequest({"action": "get", "step": "domain"}).then((res) => {
|
|
assertSetupSuccess(res)
|
|
domainSettings.web_domain = res.data.web_domain;
|
|
domainSettings.smtp_domain = res.data.smtp_domain;
|
|
domainSettings.public_https_port = String(res.data.public_https_port || "")
|
|
domainSettings.multi_domain = Array.isArray(res.data.domains) ? res.data.domains : []
|
|
return res
|
|
}).catch((error) => {
|
|
showSetupError(error)
|
|
return null
|
|
})
|
|
}
|
|
|
|
const setDbConfig = () => {
|
|
if (databaseLoading.value) {
|
|
return
|
|
}
|
|
databaseError.value = ""
|
|
|
|
if (dbSettings.type === "sqlite" && !dbSettings.dsn) {
|
|
dbSettings.dsn = "./data/smail.db";
|
|
}
|
|
|
|
const usesStructuredFields = dbSettings.type === "mysql" || dbSettings.type === "postgres"
|
|
if (usesStructuredFields) {
|
|
if (!dbSettings.user.trim()) {
|
|
ElMessage.error(lang.db_user_required)
|
|
return
|
|
}
|
|
if (!dbSettings.host.trim()) {
|
|
ElMessage.error(lang.db_host_required)
|
|
return
|
|
}
|
|
if (!dbSettings.port.trim()) {
|
|
ElMessage.error(lang.db_port_required)
|
|
return
|
|
}
|
|
if (!/^\d+$/.test(dbSettings.port.trim()) || Number(dbSettings.port) < 1 || Number(dbSettings.port) > 65535) {
|
|
ElMessage.error("数据库端口必须是 1 到 65535 之间的数字")
|
|
return
|
|
}
|
|
if (!dbSettings.name.trim()) {
|
|
ElMessage.error(lang.db_name_required)
|
|
return
|
|
}
|
|
} else if (!dbSettings.dsn.trim()) {
|
|
ElMessage.error(lang.err_db_dsn_empty)
|
|
return
|
|
}
|
|
|
|
databaseLoading.value = true
|
|
const payload = {
|
|
"action": "set",
|
|
"step": "database",
|
|
"db_type": dbSettings.type,
|
|
"db_dsn": dbSettings.dsn,
|
|
"db_mode": usesStructuredFields ? "fields" : "dsn",
|
|
"db_user": dbSettings.user,
|
|
"db_host": dbSettings.host,
|
|
"db_port": dbSettings.port,
|
|
"db_password": dbSettings.password,
|
|
"db_name": dbSettings.name
|
|
}
|
|
|
|
return setupRequest(payload).then((res) => {
|
|
assertSetupSuccess(res, lang.db_init_failed)
|
|
return getPassword().then(() => {
|
|
ElMessage.success(lang.db_init_success)
|
|
active.value++
|
|
}).catch((error) => {
|
|
databaseError.value = getDatabaseErrorMessage(error)
|
|
ElMessage.error(databaseError.value)
|
|
})
|
|
}).catch((error) => {
|
|
databaseError.value = getDatabaseErrorMessage(error)
|
|
ElMessage.error(databaseError.value)
|
|
}).finally(() => {
|
|
databaseLoading.value = false
|
|
})
|
|
}
|
|
|
|
const handleDbTypeChange = (type) => {
|
|
databaseError.value = ""
|
|
dbSettings.dsn = ""
|
|
dbSettings.password = ""
|
|
if (type === "mysql" || type === "postgres") {
|
|
dbSettings.mode = "fields"
|
|
dbSettings.host = "127.0.0.1"
|
|
dbSettings.port = type === "postgres" ? "5432" : "3306"
|
|
dbSettings.name = "smail"
|
|
} else {
|
|
dbSettings.mode = "dsn"
|
|
dbSettings.dsn = "./data/smail.db"
|
|
dbSettings.host = "127.0.0.1"
|
|
dbSettings.port = ""
|
|
dbSettings.name = ""
|
|
}
|
|
}
|
|
|
|
const getDNSConfig = async () => {
|
|
if (dnsLoading.value) return null
|
|
dnsLoading.value = true
|
|
dnsError.value = ''
|
|
const mailIPv4 = dnsMailIPv4.value.trim()
|
|
try {
|
|
const res = await setupRequest({action: 'get', step: 'dns', mail_ipv4: mailIPv4})
|
|
assertSetupSuccess(res)
|
|
dnsInfos.value = res.data
|
|
dnsAppliedIPv4.value = mailIPv4
|
|
return res
|
|
} catch (error) {
|
|
dnsInfos.value = {}
|
|
dnsError.value = showSetupError(error)
|
|
return null
|
|
} finally {
|
|
dnsLoading.value = false
|
|
}
|
|
}
|
|
|
|
const detectDNSConfig = () => {
|
|
dnsMailIPv4.value = ''
|
|
return getDNSConfig()
|
|
}
|
|
|
|
const copyDNSRecord = (record) => {
|
|
if (dnsLoading.value || dnsInputPending.value || record.unavailableReason || !record.value) return
|
|
return copyDNSValue(record.value)
|
|
}
|
|
|
|
const copyDNSValue = async (value) => {
|
|
try {
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
await navigator.clipboard.writeText(value)
|
|
} else {
|
|
const input = document.createElement('textarea')
|
|
input.value = value
|
|
input.setAttribute('readonly', '')
|
|
input.style.position = 'fixed'
|
|
input.style.opacity = '0'
|
|
document.body.appendChild(input)
|
|
input.select()
|
|
document.execCommand('copy')
|
|
document.body.removeChild(input)
|
|
}
|
|
ElMessage.success(lang.dns_copy_success)
|
|
} catch (error) {
|
|
ElMessage.error(lang.dns_copy_failed)
|
|
}
|
|
}
|
|
|
|
const clearDatabaseError = () => {
|
|
databaseError.value = ""
|
|
}
|
|
|
|
const formatDNSRecordTTL = (ttl) => {
|
|
if (ttl >= 3600 && ttl % 3600 === 0) {
|
|
return `${ttl / 3600}${lang.dns_ttl_hour}`
|
|
}
|
|
if (ttl >= 60 && ttl % 60 === 0) {
|
|
return `${ttl / 60}${lang.dns_ttl_minute}`
|
|
}
|
|
return `${ttl}${lang.dns_ttl_second}`
|
|
}
|
|
|
|
const getSSLConfig = () => {
|
|
return setupRequest({"action": "get", "step": "ssl"}).then((res) => {
|
|
assertSetupSuccess(res)
|
|
sslSettings.type = res.data.tlsMode === 'proxy' ? '1' : res.data.type
|
|
if (sslSettings.type === "2") {
|
|
sslSettings.type = "0"
|
|
sslSettings.challenge = "dns"
|
|
}
|
|
if (sslSettings.type === "0") {
|
|
sslSettings.challenge = sslSettings.challenge || "http"
|
|
}
|
|
sslRuntime.value = res.data || {}
|
|
port.value = res.data?.port || res.data?.httpPort || 80
|
|
return res
|
|
}).catch((error) => {
|
|
showSetupError(error)
|
|
return null
|
|
})
|
|
}
|
|
|
|
const setSSLConfig = () => {
|
|
fullscreenLoading.value = true;
|
|
|
|
let sslType = proxyHTTPS.value ? '1' : sslSettings.type;
|
|
if (sslType === "0" && sslSettings.challenge === "dns") {
|
|
sslType = "2"
|
|
}
|
|
|
|
return setupRequest({
|
|
"action": "set",
|
|
"step": "ssl",
|
|
"ssl_type": sslType,
|
|
"key_path": sslSettings.key_path,
|
|
"crt_path": sslSettings.crt_path
|
|
}).then((res) => {
|
|
assertSetupSuccess(res)
|
|
if (sslType === "2") {
|
|
fullscreenLoading.value = false
|
|
dnsChecking.value = true
|
|
dnsChallengeNotice.value = ""
|
|
return getSSLDNSParams()
|
|
}
|
|
if (sslType === "1") {
|
|
window.location.href = buildFinalURL(sslRuntime.value)
|
|
return res
|
|
}
|
|
checkStatus()
|
|
return res
|
|
}).catch((error) => {
|
|
fullscreenLoading.value = false
|
|
showSetupError(error)
|
|
return null
|
|
})
|
|
}
|
|
const buildFinalURL = (sslData) => buildSetupFinalURL(sslData, domainSettings.web_domain)
|
|
|
|
let statusTimer = null
|
|
let dnsParamsTimer = null
|
|
let setupViewUnmounted = false
|
|
let statusCheckRunning = false
|
|
let statusCheckStartedAt = 0
|
|
const statusCheckTimeout = 10 * 60 * 1000
|
|
const dnsVerificationTimeout = 30 * 60 * 1000
|
|
const dnsChallengeTimerDelay = 30 * 60 * 1000
|
|
|
|
const stopStatusCheck = () => {
|
|
if (statusTimer !== null) {
|
|
window.clearTimeout(statusTimer)
|
|
statusTimer = null
|
|
}
|
|
statusCheckRunning = false
|
|
statusCheckStartedAt = 0
|
|
}
|
|
|
|
const stopDNSParamsPolling = () => {
|
|
if (dnsParamsTimer !== null) {
|
|
window.clearTimeout(dnsParamsTimer)
|
|
dnsParamsTimer = null
|
|
}
|
|
}
|
|
|
|
let dnsChallengeTimer = null
|
|
|
|
const stopDNSChallengeTimer = () => {
|
|
if (dnsChallengeTimer !== null) {
|
|
window.clearTimeout(dnsChallengeTimer)
|
|
dnsChallengeTimer = null
|
|
}
|
|
}
|
|
|
|
onUnmounted(() => {
|
|
setupViewUnmounted = true
|
|
stopStatusCheck()
|
|
stopDNSParamsPolling()
|
|
stopDNSChallengeTimer()
|
|
})
|
|
|
|
const navigateToFormalService = (sslData) => {
|
|
stopStatusCheck()
|
|
stopDNSChallengeTimer()
|
|
fullscreenLoading.value = false
|
|
const target = buildFinalURL(sslData)
|
|
if (target && target !== window.location.href) {
|
|
window.location.href = target
|
|
}
|
|
}
|
|
|
|
const scheduleStatusCheck = () => {
|
|
if (statusTimer !== null) {
|
|
window.clearTimeout(statusTimer)
|
|
}
|
|
statusTimer = window.setTimeout(() => {
|
|
statusTimer = null
|
|
checkStatus()
|
|
}, 1000)
|
|
}
|
|
|
|
const checkStatus = async () => {
|
|
if (statusCheckRunning) {
|
|
return
|
|
}
|
|
if (!statusCheckStartedAt) {
|
|
statusCheckStartedAt = Date.now()
|
|
}
|
|
const currentStatusCheckTimeout = dnsChecking.value && sslSettings.challenge === "dns"
|
|
? dnsVerificationTimeout
|
|
: statusCheckTimeout
|
|
if (Date.now() - statusCheckStartedAt > currentStatusCheckTimeout) {
|
|
stopStatusCheck()
|
|
fullscreenLoading.value = false
|
|
if (dnsChecking.value && sslSettings.challenge === "dns") {
|
|
refreshDNSChallenge()
|
|
} else {
|
|
ElMessage.error(lang.setup_failed)
|
|
}
|
|
return
|
|
}
|
|
|
|
statusCheckRunning = true
|
|
let sslData = sslRuntime.value || {}
|
|
try {
|
|
const response = await setupRequest({"action": "get", "step": "ssl"})
|
|
if (response.errorNo === 0) {
|
|
sslData = response.data || sslData
|
|
sslRuntime.value = sslData
|
|
if (sslData.ready) {
|
|
navigateToFormalService(sslData)
|
|
return
|
|
}
|
|
}
|
|
} catch (error) {
|
|
// 服务切换期间失败属于预期状态。
|
|
} finally {
|
|
statusCheckRunning = false
|
|
}
|
|
|
|
if (await probeService(sslData, domainSettings.web_domain)) {
|
|
navigateToFormalService(sslData)
|
|
return
|
|
}
|
|
scheduleStatusCheck()
|
|
}
|
|
|
|
const setDomainConfig = () => {
|
|
const publicHTTPSPort = String(domainSettings.public_https_port || "").trim()
|
|
if (publicHTTPSPort && (!/^[1-9]\d{0,4}$/.test(publicHTTPSPort) || Number(publicHTTPSPort) > 65535)) {
|
|
ElMessage.error("公网 HTTPS 端口必须是 1 到 65535 的整数")
|
|
return
|
|
}
|
|
return setupRequest({
|
|
"action": "set",
|
|
"step": "domain",
|
|
"web_domain": domainSettings.web_domain,
|
|
"public_https_port": publicHTTPSPort,
|
|
"smtp_domain": domainSettings.smtp_domain,
|
|
"multi_domain": domainSettings.multi_domain.join(",")
|
|
}).then((res) => {
|
|
assertSetupSuccess(res)
|
|
return getDNSConfig().then((response) => {
|
|
if (response) {
|
|
active.value++
|
|
}
|
|
})
|
|
}).catch((error) => {
|
|
showSetupError(error)
|
|
})
|
|
}
|
|
|
|
const getSSLDNSParams = () => {
|
|
return setupRequest({"action": "getParams", "step": "ssl"}).then((res) => {
|
|
assertSetupSuccess(res)
|
|
sslSettings.paramsList = Array.isArray(res.data) ? res.data : []
|
|
if (!setupViewUnmounted && dnsChecking.value && sslSettings.paramsList.length === 0) {
|
|
stopDNSParamsPolling()
|
|
dnsParamsTimer = window.setTimeout(() => {
|
|
dnsParamsTimer = null
|
|
getSSLDNSParams()
|
|
}, 1000)
|
|
} else if (sslSettings.paramsList.length > 0 || !dnsChecking.value) {
|
|
stopDNSParamsPolling()
|
|
if (sslSettings.paramsList.length > 0 && dnsChecking.value) {
|
|
scheduleDNSChallengeRefresh()
|
|
}
|
|
}
|
|
return res
|
|
}).catch((error) => {
|
|
stopDNSParamsPolling()
|
|
showSetupError(error)
|
|
return null
|
|
})
|
|
}
|
|
|
|
const scheduleDNSChallengeRefresh = () => {
|
|
stopDNSChallengeTimer()
|
|
if (setupViewUnmounted || !dnsChecking.value) {
|
|
return
|
|
}
|
|
|
|
dnsChallengeTimer = window.setTimeout(() => {
|
|
dnsChallengeTimer = null
|
|
refreshDNSChallenge()
|
|
}, dnsChallengeTimerDelay)
|
|
}
|
|
|
|
const getDNSRefreshNotice = () => `${lang.ssl_dns_ready}(记录已刷新,请使用最新记录。)`
|
|
|
|
const refreshDNSChallenge = () => {
|
|
if (setupViewUnmounted || !dnsChecking.value || fullscreenLoading.value) {
|
|
return
|
|
}
|
|
|
|
stopStatusCheck()
|
|
stopDNSChallengeTimer()
|
|
stopDNSParamsPolling()
|
|
fullscreenLoading.value = true
|
|
|
|
return setupRequest({
|
|
"action": "set",
|
|
"step": "ssl",
|
|
"ssl_type": "2",
|
|
"key_path": sslSettings.key_path,
|
|
"crt_path": sslSettings.crt_path
|
|
}).then((res) => {
|
|
assertSetupSuccess(res)
|
|
sslSettings.paramsList = []
|
|
dnsChallengeNotice.value = getDNSRefreshNotice()
|
|
return getSSLDNSParams()
|
|
}).then((res) => {
|
|
ElMessage.warning(getDNSRefreshNotice())
|
|
return res
|
|
}).catch((error) => {
|
|
showSetupError(error)
|
|
return null
|
|
}).finally(() => {
|
|
fullscreenLoading.value = false
|
|
})
|
|
}
|
|
|
|
const resetDNSChallenge = () => {
|
|
stopStatusCheck()
|
|
stopDNSChallengeTimer()
|
|
stopDNSParamsPolling()
|
|
dnsChecking.value = false
|
|
dnsChallengeNotice.value = ""
|
|
sslSettings.paramsList = []
|
|
fullscreenLoading.value = false
|
|
}
|
|
|
|
const handleSSLTypeChange = () => {
|
|
if (proxyHTTPS.value) {
|
|
sslSettings.type = '1'
|
|
}
|
|
if (dnsChecking.value) {
|
|
resetDNSChallenge()
|
|
}
|
|
if (sslSettings.type === "0") {
|
|
sslSettings.challenge = ""
|
|
}
|
|
}
|
|
|
|
const handleSSLChallengeChange = (challenge) => {
|
|
if (fullscreenLoading.value || proxyHTTPS.value) {
|
|
return
|
|
}
|
|
|
|
if (challenge === "dns") {
|
|
dnsChallengeNotice.value = ""
|
|
return setSSLConfig()
|
|
}
|
|
|
|
if (dnsChecking.value) {
|
|
resetDNSChallenge()
|
|
}
|
|
}
|
|
|
|
const runStep = (action) => {
|
|
if (stepLoading.value) {
|
|
return
|
|
}
|
|
stepLoading.value = true
|
|
return Promise.resolve()
|
|
.then(action)
|
|
.finally(() => {
|
|
stepLoading.value = false
|
|
})
|
|
}
|
|
|
|
const next = () => {
|
|
if (databaseLoading.value || stepLoading.value || fullscreenLoading.value) {
|
|
return
|
|
}
|
|
|
|
switch (active.value) {
|
|
case 0:
|
|
runStep(() => getDbConfig().then((response) => {
|
|
if (response) {
|
|
active.value++
|
|
}
|
|
}))
|
|
break
|
|
case 1:
|
|
setDbConfig()
|
|
break
|
|
case 2:
|
|
runStep(setPassword)
|
|
break
|
|
case 3:
|
|
runStep(setDomainConfig)
|
|
break
|
|
case 4:
|
|
runStep(() => getSSLConfig().then((response) => {
|
|
if (response) {
|
|
active.value++
|
|
}
|
|
}))
|
|
break
|
|
case 5:
|
|
if (dnsChecking.value) {
|
|
stopDNSChallengeTimer()
|
|
fullscreenLoading.value = true
|
|
waitDesc.value = lang.dns_challenge_wait
|
|
checkStatus()
|
|
} else {
|
|
runStep(setSSLConfig)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
const previous = () => {
|
|
if (active.value > 0) {
|
|
if (active.value === 5) {
|
|
stopStatusCheck()
|
|
stopDNSChallengeTimer()
|
|
stopDNSParamsPolling()
|
|
dnsChecking.value = false
|
|
dnsChallengeNotice.value = ""
|
|
sslSettings.paramsList = []
|
|
fullscreenLoading.value = false
|
|
}
|
|
active.value--
|
|
}
|
|
}
|
|
|
|
return {
|
|
reactive,
|
|
ref,
|
|
ElMessage,
|
|
lang,
|
|
axios,
|
|
Plus,
|
|
http,
|
|
waitDesc,
|
|
adminSettings,
|
|
dbSettings,
|
|
databaseLoading,
|
|
stepLoading,
|
|
databaseError,
|
|
domainSettings,
|
|
sslSettings,
|
|
active,
|
|
fullscreenLoading,
|
|
dnsChecking,
|
|
dnsChallengeNotice,
|
|
port,
|
|
proxyHTTPS,
|
|
dnsInfos,
|
|
dnsMailIPv4,
|
|
dnsAppliedIPv4,
|
|
dnsLoading,
|
|
dnsError,
|
|
dnsInputPending,
|
|
hasUnavailableDNS,
|
|
detectDNSConfig,
|
|
hasDNSIPv6,
|
|
addDomain,
|
|
setPassword,
|
|
getPassword,
|
|
getDbConfig,
|
|
getDomainConfig,
|
|
setDbConfig,
|
|
handleDbTypeChange,
|
|
handleSSLTypeChange,
|
|
clearDatabaseError,
|
|
getDNSConfig,
|
|
formatDNSRecordTTL,
|
|
copyDNSRecord,
|
|
copyDNSValue,
|
|
getSSLConfig,
|
|
setSSLConfig,
|
|
checkStatus,
|
|
setDomainConfig,
|
|
getSSLDNSParams,
|
|
handleSSLChallengeChange,
|
|
next,
|
|
previous
|
|
}
|
|
}
|