Validador

// Código: verificar_acesso.gs const SPREADSHEET_ID = "1sAMUEDOqmzR3yAPpriWMp1xj-zAP7jTHsTlgWlVUaTY"; const SHEET_NAME = "COMPRA COMPLETA"; // nome da aba function doGet(e) { // Parâmetros esperados: permissao (email), produto const email = (e.parameter.permissao || "").trim(); const produto = (e.parameter.produto || "").trim(); // cabeçalhos anti-cache const headers = { "Cache-Control": "no-cache, no-store, must-revalidate", "Pragma": "no-cache", "Expires": "0" }; if (!email || !produto) { return ContentService .createTextOutput(JSON.stringify({ error: "Parâmetros 'permissao' (email) e 'produto' são obrigatórios." })) .setMimeType(ContentService.MimeType.JSON) .setHeaders(headers); } try { const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME); if (!sheet) { throw new Error("Aba '" + SHEET_NAME + "' não encontrada."); } const data = sheet.getDataRange().getValues(); if (data.length < 2) { return jsonResponse({ error: "Planilha sem dados." }, headers); } const header = data[0].map(h => (h || "").toString().trim()); // localizar colunas por nome const colIndex = {}; ["Produto","SKU/ID","Email","Nome","Sobrenome","Telefone","Endereço","Cidade","Estado","CEP","País","Valor","Moeda","Parcelas","Status","Data","Transação"].forEach(name=>{ const idx = header.indexOf(name); if (idx >= 0) colIndex[name] = idx; }); if (!colIndex["Email"] || !colIndex["Produto"] || !colIndex["Data"] || !colIndex["Status"] || !colIndex["Transação"]) { // se algum não foi encontrado, tenta relaxado // use índices já mesmos se már suceder } // coleta linhas que batem com email+produto const matchedRows = []; for (let i = 1; i < data.length; i++) { const row = data[i]; const rowProduto = (row[colIndex["Produto"]] || "").toString().trim(); const rowEmail = (row[colIndex["Email"]] || "").toString().trim(); const rowDataStr = (row[colIndex["Data"]] || "").toString().trim(); const rowStatus = (row[colIndex["Status"]] || "").toString().trim(); const rowTransacao = (row[colIndex["Transação"]] || "").toString().trim(); if (rowEmail.toLowerCase() === email.toLowerCase() && rowProduto === produto) { const parsedDate = parseBrazilDateTime(rowDataStr); matchedRows.push({ produto: rowProduto, sku: (row[colIndex["SKU/ID"]]||"").toString(), email: rowEmail, status: rowStatus, dataStr: rowDataStr, dateObj: parsedDate, transacao: rowTransacao }); } } if (matchedRows.length === 0) { return jsonResponse({ pode_usar: false, mensagem: "Nenhuma compra encontrada para esse e-mail e produto." }, headers); } // Agrupar por transacao e pegar o último status (data maior) por transação const groups = {}; matchedRows.forEach(r=>{ const t = r.transacao || ("__no_tx__:" + r.dataStr); if (!groups[t]) groups[t] = []; groups[t].push(r); }); const transacoesResumo = []; for (const tx in groups) { const items = groups[tx]; items.sort((a,b)=> b.dateObj - a.dateObj); // mais recente primeiro const last = items[0]; transacoesResumo.push({ transacao: tx, ultimo_status: last.status, ultimo_data: last.dataStr, ultimo_data_obj: last.dateObj.getTime() }); } // escolher a transacao com ultimo_data_obj mais recente transacoesResumo.sort((a,b)=> b.ultimo_data_obj - a.ultimo_data_obj); const maisRecente = transacoesResumo[0]; // Mensagens por status const status = (maisRecente.ultimo_status || "").toUpperCase(); const mensagensPorStatus = { "COMPLETED": "Acesso liberado. Transação finalizada.", "APPROVED": "Pagamento aprovado, mas verifique se foi finalizado (status final não é COMPLETED).", "BILLET_PRINTED": "Boleto impresso — aguardando pagamento.", "CANCELED": "Compra cancelada — acesso negado.", "DELAYED": "Pagamento atrasado/diferido — acesso negado.", "DISPUTE": "Compra em disputa — acesso negado.", "EXPIRED": "Compra expirada — acesso negado." }; const podeUsar = (status === "COMPLETED"); const mensagem = mensagensPorStatus[status] || ("Status: " + status); const resp = { pode_usar: podeUsar, transacao: maisRecente.transacao, status_final: status, mensagem: mensagem, detalhes: transacoesResumo.map(t=>({ transacao: t.transacao, ultimo_status: t.ultimo_status, ultimo_data: t.ultimo_data })) }; return jsonResponse(resp, headers); } catch (err) { return jsonResponse({ error: err.message }, headers); } } function jsonResponse(obj, headers) { const out = ContentService.createTextOutput(JSON.stringify(obj)).setMimeType(ContentService.MimeType.JSON); if (headers) { // Apps Script ContentService não permite setHeaders diretamente no returned object, // mas podemos setar Cache-Control via HtmlService? Como alternativa, incluímos header via meta no cliente e confiamos no fetch no lado cliente (no-cache). // Ainda assim retornamos o JSON normalmente. } return out; } function parseBrazilDateTime(s) { // espera "dd/mm/yyyy HH:MM:SS" ou "dd/mm/yyyy" if (!s) return new Date(0); s = s.trim(); const parts = s.split(' '); const datePart = parts[0]; const timePart = parts[1] || "00:00:00"; const d = datePart.split('/'); if (d.length !== 3) return new Date(s); // fallback const dd = pad(d[0],2); const mm = pad(d[1],2); const yyyy = d[2]; // construir string ISO evitando timezone issues const iso = `${yyyy}-${mm}-${dd}T${timePart}`; const dt = new Date(iso); // se inválido, tentar trocar ":" por ":" já ok — fallback final: if (isNaN(dt.getTime())) return new Date(0); return dt; } function pad(s, n) { s = s.toString(); while (s.length < n) s = '0' + s; return s; }

Formulário de contato

Nome

E-mail *

Mensagem *

Este blog é um complemento do nosso canal no YouTube. Clique em @CanalQb para seguir e acompanhar nossos vídeos!
Imagem

Como configurar pasta compartilhada no Ubuntu 18.04 Server via Samba

@CanalQb

Configurando Pasta Compartilhada no Ubuntu 18.04 Server via Samba


Este tutorial detalha o passo a passo para instalar e configurar o Samba no Ubuntu 18.04 Server, permitindo compartilhar pastas em rede com computadores Windows. O Samba é fundamental para ambientes mistos Linux e Windows, possibilitando o acesso fácil a arquivos em rede de forma segura e eficiente.

Recursos e vídeos de apoio para acompanhar o tutorial completo

Aplicativos recomendados para administração remota e edição

Passo a passo para instalar e configurar o Samba no Ubuntu 18.04 Server

Primeiramente, precisamos atualizar os repositórios do Ubuntu para garantir que todos os pacotes estejam atualizados. Para isso, abra o Putty e conecte-se ao seu servidor Ubuntu:

sudo apt update

Em seguida, instale o Samba utilizando o comando:

sudo apt install samba -y

Após a instalação, é importante testar se a máquina está acessível pela rede utilizando o caminho da rede. No Windows, acesse:

\\192.168.0.2

Agora, vamos configurar o Samba para compartilhar uma pasta. Edite o arquivo de configuração do Samba:

sudo nano /etc/samba/smb.conf

Ao final do arquivo, adicione a seguinte configuração para a pasta compartilhada:

[Compartilhada]
   path = /srv/compartilhada
   writable = yes
   browsable = yes
   guest ok = yes
   read only = no

Salve e saia do editor.

Em seguida, crie a pasta compartilhada e dê permissões:

sudo mkdir -p /srv/compartilhada
sudo chmod -R 0777 /srv/compartilhada

Reinicie o serviço Samba para aplicar as mudanças:

sudo systemctl restart smbd

Agora a pasta estará acessível na rede para qualquer usuário.

Configuração de usuário Samba

Se desejar restringir o acesso, é possível criar um usuário Samba com senha:

sudo smbpasswd -a seu_usuario

Depois configure no smb.conf o compartilhamento para exigir login:

[Compartilhada]
   path = /srv/compartilhada
   valid users = seu_usuario
   writable = yes
   browsable = yes
   guest ok = no
   read only = no

Reinicie o Samba:

sudo systemctl restart smbd

Agora a pasta só estará disponível para o usuário autorizado.

---

Gostou do tutorial? Deixe seu comentário e compartilhe! Para mais conteúdos como este, acesse o canal do YouTube @CanalQb.

Comentários