import { defineComponent, onMounted, ref, computed, watch, onUnmounted, nextTick } from 'vue' import { CTitleBanner } from '../../../components/CTitleBanner' import { CDateTime } from '../../../components/CDateTime' import { CMyFieldDb } from '../../../components/CMyFieldDb' import { useQuasar } from 'quasar' import { useI18n } from '@/boot/i18n' import { useUserStore } from '@store/UserStore' import { useGlobalStore } from '@store/globalStore' import { useCircuitStore } from '@store/CircuitStore' import { tools } from '@store/Modules/tools' import { costanti } from '@costanti' import { shared_consts } from '@src/common/shared_vuejs' export default defineComponent({ name: 'server', components: { CTitleBanner, CDateTime, CMyFieldDb }, props: {}, setup() { const $q = useQuasar() const { t } = useI18n() const circuitStore = useCircuitStore() const userStore = useUserStore() const messages = ref('') const input = ref('') const scriptName = ref('') const inputRequired = ref(false) const inputPrompt = ref('') const statusWs = ref('') const rischeckDNS = ref('') const errorDNS = ref(false) let ws: any = null; const ris = ref('') const riga = ref(0) const numpersone = ref(7) const date_start = ref(new Date()) const col = ref(0) const placca = ref('') const valmin = ref(200) const circuitId = ref('') const valmax = ref(400) const defmin = ref(shared_consts.CIRCUIT_PARAMS.SCOPERTO_MIN_GRP) const defmax = ref(shared_consts.CIRCUIT_PARAMS.SCOPERTO_MAX_GRP) const defpersmin = ref(100) const defpersmax = ref(200) const search_username = ref('') const replace_username = ref('') const incaricamento = ref(false) const myarrscript = ref([]) const myarroptionsdir = ref([]) const myarrdir = ref([]) const mydir = ref('') const scrollArea = ref(null) const globalStore = useGlobalStore() const selectedApi = ref(''); const dnsPageActive = ref(false) const dnsCheckMySite = ref(false) const optionsApi = ref([]) const arrZones = ref([]) const arrDNS = ref([]) const arrEmails = ref([]) const optZones = ref([]) const selected = ref([]) const selZoneId = ref('') const showNewEmail = ref(false) const showchangePwd = ref(false) const newEmail = ref('') const newPassword = ref('') const changeEmail = ref('') const changePassword = ref('') const isPwd = ref(true) const emailSel = ref('') const isFormValid = computed(() => { return newEmail.value && newEmail.value.includes('@') && newPassword.value.length >= 8 }) const isFormValidChange = computed(() => { return emailSel.value && emailSel.value.includes('@') && changePassword.value.length >= 8 }) const columnsZones = [ { name: 'id', align: 'right', label: 'ID', field: 'id', visible: true }, { name: 'name', required: true, label: 'Nome', align: 'left', field: 'name', sortable: true, visible: true }, { name: 'status', align: 'center', label: 'Status', field: 'status', sortable: true, visible: true }, { name: 'proxied', align: 'center', label: 'Proxy', field: 'proxied', sortable: true, visible: true }, { name: 'type', required: true, label: 'Tipo', align: 'left', field: 'type', sortable: true, visible: true }, ]; const columnsDNS = [ { name: 'id', required: false, label: 'Id', align: 'left', field: 'id', sortable: false, visible: false }, { name: 'name', required: true, label: 'Nome', align: 'left', field: 'name', sortable: true, visible: true }, { name: 'type', required: true, label: 'Tipo', align: 'left', field: 'type', sortable: true, visible: true }, { name: 'proxied', required: true, align: 'center', label: 'Proxy', field: 'proxied', sortable: true, visible: true }, { name: 'priority', required: true, align: 'center', label: 'Pri', field: 'priority', sortable: true, visible: true }, { name: 'ttl', required: true, align: 'center', label: 'TTL', field: 'ttl', sortable: false, visible: true }, { name: 'content', required: true, label: 'Valore', align: 'left', field: 'content', sortable: true, visible: true }, { name: 'delete', required: true, label: 'Azioni', align: 'left', field: 'delete', sortable: true, visible: true }, ]; const viscolumnsDNS = [ { name: 'name', required: true, label: 'Nome', align: 'left', field: 'name', sortable: true, visible: true, editable: true }, { name: 'type', required: true, label: 'Tipo', align: 'left', field: 'type', sortable: true, visible: true, editable: true }, { name: 'proxied', required: true, align: 'center', label: 'Proxy', field: 'proxied', sortable: true, visible: true, editable: true }, { name: 'priority', required: true, align: 'center', label: 'Pri', field: 'priority', sortable: true, visible: true }, { name: 'ttl', required: true, align: 'center', label: 'TTL', field: 'ttl', sortable: false, visible: true }, { name: 'content', required: true, label: 'Valore', align: 'left', field: 'content', sortable: true, visible: true, editable: true }, { name: 'delete', required: true, label: 'Azioni', align: 'left', field: 'delete', sortable: true, visible: true }, ]; const pagination = { rowsPerPage: 20, } watch(() => selectedApi.value, async (to: any, from: any) => { if (selectedApi.value) { incaricamento.value = true tools.setCookie('CF_API_SEL', selectedApi.value) arrZones.value = await globalStore.getCloudFlareTok("getzones", selectedApi.value, "") incaricamento.value = false selZoneId.value = tools.getCookie('CF_API_ZONE_ID_' + selectedApi.value, '') optZones.value = [] for (let i = 0; i < arrZones.value.length; i++) { optZones.value.push({ label: arrZones.value[i].name, value: arrZones.value[i].id }) } } }) watch(() => mydir.value, async (to: any, from: any) => { // ... // console.log('Watching ' + mydir.value) myarrscript.value = [] optionsApi.value = [] dnsPageActive.value = (mydir.value === '2_DNS') incaricamento.value = true tools.setCookie('CF_API_DIR', mydir.value) if (dnsPageActive.value) { // get the Tokens optionsApi.value = await globalStore.getCloudFlareTok("gettok", selectedApi.value, "") } else { if (mydir.value) myarrscript.value = await getArrayByScript('ls "admin_scripts/' + mydir.value + '/"', 'sh') } incaricamento.value = false }) async function updateArrDns() { arrDNS.value = [] arrDNS.value = await globalStore.getCloudFlareTok("getDNS", selectedApi.value, selZoneId.value) } async function getEmails() { arrEmails.value = [] arrEmails.value = await globalStore.getMailInABox("getEmails", { domain: tools.getDomainSite() }) } async function addEmailServer(email: string, pwd: string) { incaricamento.value = true const ris = await globalStore.getMailInABox("addEmail", { domain: tools.getDomainSite(), email, pwd }) if (ris) tools.showPositiveNotif($q, ris) else { tools.showNegativeNotif($q, t('miab.err_addemail')) } await checkDNSSite() incaricamento.value = false } async function setMailUserPassword(email: string, pwd: string) { incaricamento.value = true const ris = await globalStore.getMailInABox("setMailUserPassword", { domain: tools.getDomainSite(), email, pwd }) if (ris) tools.showPositiveNotif($q, ris) else { tools.showNegativeNotif($q, t('miab.err_setmailuserpwd')) } await checkDNSSite() incaricamento.value = false } async function removeEmails(email: String) { $q.dialog({ message: t('miab.deleteemail') + email + ' ?', ok: { label: t('dialog.yes'), push: true, }, cancel: { label: t('dialog.cancel'), }, title: 'Funzione:', }).onOk(async () => { incaricamento.value = true const ris = await globalStore.getMailInABox("removeEmails", { domain: tools.getDomainSite(), email }) if (ris) tools.showPositiveNotif($q, ris) else { tools.showNegativeNotif($q, t('miab.err_removed')) } await checkDNSSite() incaricamento.value = false }) } watch(() => selZoneId.value, async (to: any, from: any) => { if (selZoneId.value) { incaricamento.value = true await updateArrDns() const checksiteprec = dnsCheckMySite.value dnsCheckMySite.value = dnsPageActive.value && (getNameBySelZoneinId() === tools.getDomainSite()) if (dnsCheckMySite.value && !checksiteprec) { await checkDNSSite() } incaricamento.value = false tools.setCookie('CF_API_ZONE_ID_' + selectedApi.value, selZoneId.value) /*optDNS.value = [] for (let i = 0; i < arrZones.value.length; i++) { optDNS.value.push({ label: arrZones.value[i].name, value: arrZones.value[i].id }) }*/ } }) watch(() => messages.value, async (to: any, from: any) => { await nextTick(); // Aspetta che il DOM si aggiorni scrollToBottom(); }); async function eseguiScriptSenzaConferma(script: string, ritornaout: boolean, dir: string, listafiles: boolean, extfiles: string, withinput: boolean) { // console.log('eseguiScriptSenzaConferma ' + script) const mydata = { script, dir, tokcheck: "php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz", listafiles, extfiles, withinput } incaricamento.value = true const risfunz = await globalStore.execScript({ mydata }) incaricamento.value = false if (ritornaout) { if (listafiles) { return risfunz.arrout } else { return risfunz.stdout } } else { return risfunz } } async function getArrayByScript(script: string, extfiles: string) { let mystr = 'admin_scripts/' if (mydir.value) { mystr += mydir.value } return await eseguiScriptSenzaConferma(script, true, mystr, true, extfiles, false) } async function mounted() { myarrdir.value = await getArrayByScript('cd admin_scripts; ls -d */', '') myarroptionsdir.value = [] if (myarrdir.value) { for (let i = 0; i < myarrdir.value.length; i++) { const opt = { label: myarrdir.value[i].label, value: myarrdir.value[i].value } myarroptionsdir.value.push(opt) } } if (myarrdir.value && myarrdir.value.length > 0) { mydir.value = myarrdir.value[0].value } connectWebSocket() scrollToBottom() mydir.value = tools.getCookie('CF_API_DIR') selectedApi.value = tools.getCookie('CF_API_SEL', '') } const scrollToBottom = () => { nextTick(() => { if (scrollArea.value) { const el = scrollArea.value.$el; let scrollHeight = el.scrollHeight if (el) { // Use el.scrollIntoView() to instantly scroll to the element scrollArea.value.setScrollPosition('vertical', 10000) } } }) }; onUnmounted(() => { if (ws) { ws.close(); statusWs.value = 'CLOSE'; } }); function EseguiScript(script: string) { const userStore = useUserStore() $q.dialog({ message: t('dialog.continue') + ' ' + script + ' ?', ok: { label: t('dialog.yes'), push: true, }, cancel: { label: t('dialog.cancel'), }, title: 'Funzione:', }).onOk(async () => { incaricamento.value = true $q.loading.show({ message: t('otherpages.update') }) const risfunz = await eseguiScriptSenzaConferma(script, false, '', false, '', true) $q.loading.hide() // await globalStore.loadSite() incaricamento.value = false console.log('EseguiScript', risfunz) //write the string of the time now let timenowstr = '✅ Eseguito alle ' + tools.getstrTimeAll(Date.now()) + ' -> ' + '
' if (risfunz.stderr) ris.value = timenowstr + '' + 'ERRORE: ' + risfunz.stderr + '
' + ris.value if (risfunz.stdout) ris.value = timenowstr + risfunz.stdout + '
' + ris.value }) } const connectWebSocket = () => { let myurlws = tools.getWssUrl() ws = new WebSocket(myurlws) const input = ref(''); console.log('connectWebSocket ... ' + myurlws) ws.onmessage = (event: any) => { const data = JSON.parse(event.data); if (data.type === 'output' || data.type === 'error') { messages.value += data.data; scrollToBottom() } else if (data.type === 'input_required') { inputRequired.value = true; inputPrompt.value = data.prompt; } else if (data.type === 'close') { messages.value += '\n' + data.data } }; ws.onclose = () => { statusWs.value = 'CLOSE'; messages.value += '\nConnessione chiusa. Riconnessione...' setTimeout(connectWebSocket, 5000); }; }; const startScript = (scriptName: string) => { if (ws && ws.readyState === WebSocket.OPEN && scriptName) { // ('Start Script ', ws) statusWs.value = 'OPEN' // messages.value = '' // Pulisce i messaggi precedenti inputRequired.value = false; let timenowstr = '
✅ Eseguito alle ' + tools.getstrTimeAll(Date.now()) + ' -> ' + '
' messages.value += timenowstr ws.send(JSON.stringify({ user_id: userStore.my._id, type: 'start_script', scriptName, dir: mydir.value })); } }; const sendInput = () => { if (ws && ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'input', data: input.value })); // messages.value.push(input.value + '\n') input.value = ''; inputRequired.value = false; } }; // get the label of the selectedApi (value) const getLabelSelApi = () => { const myrec = optionsApi.value.find((opt: any) => opt.value === selectedApi.value) return myrec ? myrec.label : '' } const getNameBySelZoneinId = () => { if (arrZones.value) { const myrec = arrZones.value.find((zone: any) => zone.id === selZoneId.value) return myrec ? myrec.name : '' } else { return '' } } const getSelectedString = () => { return selected.value.length === 0 ? '' : `${selected.value[0].name} selezionata.` } const toggleSelect = (row: any) => { if (selected.value.length > 0 && selected.value[0].id === row.id) { selected.value = []; } else { selected.value = [row]; } } const saveContentDNS = async (content: string, initialValue: string) => { console.log('record da salvare su CF:', content) if (selected.value && selected.value.length > 0 && selected.value[0].id) { const indrec = arrDNS.value.findIndex((rec: any) => rec.id === selected.value[0].id) arrDNS.value[indrec].content = content await saveRecordDNS(arrDNS.value[indrec]) } } const saveNameDNS = async (name: string, initialValue: string) => { if (selected.value && selected.value.length > 0 && selected.value[0].id) { const indrec = arrDNS.value.findIndex((rec: any) => rec.id === selected.value[0].id) arrDNS.value[indrec].name = name await saveRecordDNS(arrDNS.value[indrec]) } } const saveTTLDNS = async (ttl: string, initialValue: string) => { if (selected.value && selected.value.length > 0 && selected.value[0].id) { const indrec = arrDNS.value.findIndex((rec: any) => rec.id === selected.value[0].id) arrDNS.value[indrec].ttl = ttl await saveRecordDNS(arrDNS.value[indrec]) } } const savePriorityDNS = async (priority: string, initialValue: string) => { if (selected.value && selected.value.length > 0 && selected.value[0].id) { const indrec = arrDNS.value.findIndex((rec: any) => rec.id === selected.value[0].id) arrDNS.value[indrec].priority = priority await saveRecordDNS(arrDNS.value[indrec]) } } const saveTypeDNS = async (type: string, initialValue: string) => { if (selected.value && selected.value.length > 0 && selected.value[0].id) { const indrec = arrDNS.value.findIndex((rec: any) => rec.id === selected.value[0].id) arrDNS.value[indrec].type = type await saveRecordDNS(arrDNS.value[indrec]) } } const setCorrectIpsOnDNS = async () => { incaricamento.value = true let myrecord = { name: tools.getDomainSite() } await globalStore.getCloudFlareTok("setCorrectIpsOnDNS", selectedApi.value, selZoneId.value, null, myrecord) await checkDNSSite() incaricamento.value = false } const saveRecordDNS = async (row: any) => { console.log('record da salvare su CF:', row) const recupdated = await globalStore.getCloudFlareTok("setRecordDNS", selectedApi.value, selZoneId.value, row.id, row) if (recupdated) { const indrec = arrDNS.value.findIndex((rec: any) => rec.id === recupdated.id) // update record arrDNS.value[indrec] = recupdated tools.showPositiveNotif($q, t('db.recupdated')) } else { tools.showNegativeNotif($q, t('db.recfailed')) } } const delRecordDNS = async (row: any) => { $q.dialog({ message: t('db.deletetherecord') + ' type = ' + row.type + ' ?', ok: { label: t('dialog.yes'), push: true, }, cancel: { label: t('dialog.cancel'), }, title: 'Funzione:', }).onOk(async () => { const recupdated = await globalStore.getCloudFlareTok("delRecordDNS", selectedApi.value, selZoneId.value, row.id, null) if (recupdated) { // update record updateArrDns() tools.showPositiveNotif($q, t('db.deletedrecord')) } else { tools.showNegativeNotif($q, t('db.recfailed')) } }) } function getResultCheckDnsParam(title: string, recordReal: any, paramReal: string, strExpected: string) { let mystr = '' try { if (recordReal) { const contentReal = recordReal[paramReal] if (strExpected !== contentReal) { errorDNS.value = true mystr += `${title}: NO
👉🏻 🔴 Attuale__: ${contentReal}
👉🏻 🔵 Aspettato: ${strExpected}
` } else { mystr += `${title}: 🟢 OK (${contentReal})
` } } else { errorDNS.value = true mystr += `${title}: 🔴 N/A
` } } catch (error) { mystr += `${title}: 🔴 N/A Errore nell\'estrazione del parametro ...
` } return mystr } async function checkDNSSite() { incaricamento.value = true await updateArrDns() await globalStore.loadSite() rischeckDNS.value = '
' errorDNS.value = false const domainSite = tools.getDomainSite(); const domainsData = [ { url: domainSite, expected: globalStore.site.host_ip, type: 'A' }, { url: 'api.' + domainSite, expected: globalStore.site.host_api_ip, type: 'A' }, { url: 'test.' + domainSite, expected: globalStore.site.host_test_ip, type: 'A' }, { url: 'testapi.' + domainSite, expected: globalStore.site.host_testapi_ip, type: 'A' }, { url: 'www.' + domainSite, expected: domainSite, type: 'CNAME' } ]; // Controllo DNS if (dnsPageActive.value) { let checkDomainA1 = ''; for (let i = 0; i < domainsData.length; i++) { let ris = tools.getHostPuntamento(arrDNS.value, domainsData[i].url, domainsData[i].expected!, domainsData[i].type); checkDomainA1 += ris.text; if (!ris.ok) { errorDNS.value = true; } } let checkServerMailEnabled = '
'; if (globalStore.site.enable_servermail) { // Controlla type MX const mxRecord = arrDNS.value.find((record: any) => record.type === 'MX' && record.name === domainSite); checkServerMailEnabled += getResultCheckDnsParam('Server mail enabled', mxRecord, 'content', globalStore.site.servermail!) // *** Controlla type TXT spf1 *** let contentTXTspf1Expected = `v=spf1 a mx:${globalStore.site.servermail} ip4:${globalStore.site.servermailip} ~all`; const mxRecordTXTspf1 = arrDNS.value.find((record: any) => record.type === 'TXT' && record.name === domainSite && (record.content.indexOf('v=spf1') > -1)) checkServerMailEnabled += getResultCheckDnsParam('TXT spf1 RECORD', mxRecordTXTspf1, 'content', contentTXTspf1Expected) let nameDkimtoFind = `mail._domainkey.${domainSite}`; // Controllo DKIM: const mxRecordTXTDKIM = arrDNS.value.find((record: any) => record.type === 'TXT' && record.name === nameDkimtoFind) let contentTXTDKIMExpected = `v=DKIM1; h=sha256; k=rsa; s=email; p=${globalStore.site.dkim}` checkServerMailEnabled += getResultCheckDnsParam('DKIM1', mxRecordTXTDKIM, 'content', contentTXTDKIMExpected) // Controllo DMARC: const mxRecordTXTDMARC = arrDNS.value.find((record: any) => record.type === 'TXT' && record.name === `_dmarc.${domainSite}`) let contentTXTMARCExpected = `v=DMARC1; p=quarantine; ruf=mailto:dmarc@${domainSite};`; checkServerMailEnabled += getResultCheckDnsParam('DMARC RECORD', mxRecordTXTDMARC, 'content', contentTXTMARCExpected) // Controlla autoconfig const recAutoConfig = arrDNS.value.find((record: any) => record.type === 'CNAME' && record.name === `autoconfig.${domainSite}`); checkServerMailEnabled += getResultCheckDnsParam('AutoConfig CNAME', recAutoConfig, 'content', globalStore.site.servermail!) // Controlla autodiscover const recAutoDiscover = arrDNS.value.find((record: any) => record.type === 'CNAME' && record.name === `autodiscover.${domainSite}`); checkServerMailEnabled += getResultCheckDnsParam('AutoDiscover CNAME', recAutoDiscover, 'content', globalStore.site.servermail!) await getEmails() } rischeckDNS.value = checkDomainA1 + checkServerMailEnabled incaricamento.value = false } } async function addEmail() { // Implementa qui la logica per aggiungere la nuova email console.log('Aggiunta nuova email:', newEmail.value) await addEmailServer(newEmail.value, newPassword.value) // Resetta i campi e chiudi il dialog newEmail.value = '' newPassword.value = '' showNewEmail.value = false } async function setMailUserPwd() { // Implementa qui la logica per aggiungere la nuova email await setMailUserPassword(emailSel.value, changePassword.value) // Resetta i campi e chiudi il dialog emailSel.value = '' changePassword.value = '' showchangePwd.value = false } onMounted(mounted) return { EseguiScript, tools, costanti, search_username, replace_username, valmin, valmax, defmin, defmax, defpersmin, defpersmax, circuitId, circuitStore, incaricamento, ris, myarrscript, mydir, myarrdir, myarroptionsdir, messages, input, scriptName, startScript, sendInput, inputRequired, inputPrompt, statusWs, scrollArea, selectedApi, dnsPageActive, optionsApi, arrZones, getLabelSelApi, columnsZones, pagination, selected, getSelectedString, toggleSelect, optZones, selZoneId, arrDNS, columnsDNS, getNameBySelZoneinId, viscolumnsDNS, saveRecordDNS, saveContentDNS, saveNameDNS, saveTypeDNS, saveTTLDNS, savePriorityDNS, dnsCheckMySite, checkDNSSite, rischeckDNS, globalStore, setCorrectIpsOnDNS, errorDNS, delRecordDNS, arrEmails, removeEmails, addEmail, newEmail, newPassword, changeEmail, changePassword, showNewEmail, showchangePwd, isFormValid, isPwd, setMailUserPwd, emailSel, isFormValidChange, } }, })