Deck of Cards |
---|
effectDuration | 0.5 |
---|
id | vertentes |
---|
| Card |
---|
id | introducao |
---|
label | Introdução |
---|
title | Introdução |
---|
| Column |
---|
| Propósito O APPLINKER é é uma ferramenta desenvolvida pela TOTVS com o objetivo de permitir a criação geração de Alias alias para bases locais PROTHEUS. O alias é uma chave que conecta o aplicativo com o ambiente PROTHEUS. Essa chave é utilizada no momento de realizar o login nos aplicativos passando as credenciais. Aviso |
---|
Está Esta é uma ferramenta para benefício das que beneficia as equipes de suporte ou desenvolvimento nas análises de ocorrências no aplicativo. Esta solução NÃO não é para geração de Alias alias para ambientes externos, apenas para fins internos. |
Determinados aplicativos necessitam realizar integração com o intermediador (gatewayde um gateway (intermediador), também conhecido como Mingle, para conexão para realizar comunicação com os servers PROTHEUS. Isso se faz necessário para que a URL do servidor não fique exposta ou disponível para todos. Trazendo , trazendo assim estabilidade e segurança para o ambiente. Os aplicativos móveis a seguir necessitam de Alias: - Legal Process
- Legal Task
- Meu Posto de Trabalho
- Meu Protheus
- Minha Prestação de Contas
- Meus Ativos Fixos
- Meus Contratos
- Minha Gestão de Postos
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | funcionalidades-interfaces |
---|
label | Funcionalidades e Interfacesinterfaces |
---|
title | Funcionalidades e Interfacesinterfaces |
---|
| Deck of Cards |
---|
effectDuration | 0.5 |
---|
id | aplicacao |
---|
| Card |
---|
effectDuration | 0.5 |
---|
id | acesso-applinker |
---|
label | Acesso ao AppLinker |
---|
title | Acesso ao AppLinker |
---|
| Primeiro LoginloginPara acessar o APPLINKER, é necessário ter um usuário liberadousuário ativo. Aviso |
---|
Para que o usuário esteja ativo: - Terá que se cadastrar pelo APPLINKER.
- Verificar na caixa de e-mails se recebeu o e-mail de confirmação do APPLINKER.
- Caso tenha recebido, basta confirmar a ativação do usuário clicando no botão de ativação presente no e-mail recebido.
- Caso não tenha recebido entre em contato com a equipe responsável pela ativação.
|
Informe os dados de "Usuário" e "Senha" e clique em "Acessar sistema". Painel |
---|
title | Tenha de AppLinker - Login - AppLinker |
---|
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | novo-usuario |
---|
label | Novo Usuáriousuário |
---|
title | Novo Usuáriousuário |
---|
| Solicitando Nova Credencialnova credencialPara criar um novo usuário clique em "Novo Registro" em seguida informe os dados necessários de "E-mail" e "Senha". Aviso |
---|
Para Apenas TOTVERs ou PARTNERS podem realizar o cadastro, com isso, o uso por outras empresas não é permitido. |
Painel |
---|
title | Cadastro - AppLinker |
---|
| Image Added |
Após o envio das credenciais será necessário ativar o seu usuário. Para que o usuário seja um TOTVER. Outras organizações não são permitidasativado: - Verificar na caixa de e-mails se recebeu o e-mail de confirmação do APPLINKER.
Caso tenha recebido, basta confirmar a ativação do usuário clicando no botão "Ativar" presente no e-mail recebido.
| Cadastro - AppLinker | Image Removed | Image Added |
Aviso |
---|
Caso não tenha recebido entre em contato com a equipe responsável pela ativação. |
Card |
---|
effectDuration | 0.5 |
---|
id | recuperar-senha |
---|
label | Recuperar Senhasenha |
---|
title | Recuperar Senhasenha |
---|
| Resgatar Palavra ChavesenhaPara recuperar as credenciais de acesso, informe o seu "E-mail", confirme no seu . Painel |
---|
title | Recuperação de senha - AppLinker |
---|
| Image Added |
Após o envio, você receberá um e-mail na sua caixa de entrada para confirmar a troca de senha e altere sua senha. Painel |
---|
title | Email para alteração de senha |
---|
| Image Added |
Clicando no botão "Alterar Senha" presente no e-mail, você será redirecionado para uma tela onde você informará senha e a confirmação da senha. Painel |
---|
title | Recuperação Alteração de Senha - AppLinkersenha |
---|
| Image RemovedImage Added |
|
Card |
---|
effectDuration | 0.5 |
---|
id | conexao-server |
---|
label | Conexão com o Serverserver |
---|
title | Conexão com o Serverserver |
---|
| Rest ProtheusPreencher as informações de configuração do REST de seu Preencha os dados de conexão do rest em seu ambiente PROTHEUS local. Porta - Porta que onde o rest está configurado. URL - path onde o rest irá subir Path de acesso ao rest. Painel |
---|
title | Rest Protheus - AppLinker |
---|
|
|
Dica |
---|
Os campos acima devem ser preenchidos de acordo com o seu appserver.ini, exemplo: Painel |
---|
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | escolherselecione-aplicativo |
---|
label | Escolher Selecione o aplicativo |
---|
title | Escolher Selecione o aplicativo |
---|
| AplicativoApós clicar em conectar, se a conexão for bem sucedida você será redirecionado a seguinte página. Nesta pagina será necessário escolher o APP que serão realizados os testes. De acordo com o APP aplicativo selecionado, exibirá alguns campos personalizadosobrigatórios são exibidos, como por exemplo, empresa e filial, que são campos obrigatórios que serão utilizados para realizar a conexão. Painel |
---|
title | Aplicativo - AppLinker |
---|
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | alias-gerado |
---|
label | Alias Geradogerado |
---|
title | alias-Alias gerado |
---|
| StartApós as etapas de conexão com o server PROTHEUS, e a escolha do aplicativo, na etapa "start" será exibido o alias. Painel |
---|
| Image Added
|
Na tela do aplicativo, você utiliza o usuário e a senha do PROTHEUS configurado no REST e o Alias gerado no APPLINKER. Painel |
---|
| Image Removed Painel |
---|
|
|
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | configuracao-instrucoes-tecnicas |
---|
label | Configuração e Instruções Técnicasinstruções técnicas |
---|
title | Configuração e Instruções Técnicasinstruções técnicas |
---|
| Deck of Cards |
---|
startHidden | false |
---|
effectDuration | 0.5 |
---|
id | desenvolvimento-producao |
---|
| Card |
---|
id | projeto |
---|
label | Projeto |
---|
title | Projeto |
---|
| Deck of Cards |
---|
effectDuration | 0.5 |
---|
id | documentos-tecnicos |
---|
| Card |
---|
id | caso-uso |
---|
label | Caso de Usouso |
---|
title | Caso de Usouso |
---|
| Funcionalidades do UsuáriousuárioOs requisitos de usuário serão exibidos a baixo para maior compreensão das ações que o usuário pode executar no APPLINKER. A seguir você irá visualizar os requisitos de usuário. Painel |
---|
|
|
|
Card |
---|
id | fluxo-usuario |
---|
label | Fluxo do Usuáriousuário |
---|
title | Fluxo do Usuáriousuário |
---|
| Diagrama de UsousoApresentaremos o diagrama com o funcionamento da A seguir você irá visualizar um passo a passo de como funciona a aplicação e todas as entidades presentes. Painel |
---|
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | modelo-conceitual-logico |
---|
label | Modelo Conceitual conceitual e Lógicológico |
---|
title | Modelo Conceitual conceitual e Lógicológico |
---|
| DiagramasA modelagem de dados do APPLINKER é bem "simples". É composta apenas por uma tabela de "Usuários", que guarda o "e-mail", "senha", "permissão" e "data do registro". Painel |
---|
|
|
Painel |
---|
|
|
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | produção |
---|
label | Produção |
---|
title | Produção |
---|
| Deck of Cards |
---|
effectDuration | 0.5 |
---|
id | ambiente-producao |
---|
| Card |
---|
effectDuration | 0.5 |
---|
id | banco-dados |
---|
label | Banco de Dadosdados |
---|
title | Banco de Dadosdados |
---|
| Deck of Cards |
---|
effectDuration | 0.5 |
---|
id | database |
---|
| Card |
---|
effectDuration | 0.5 |
---|
id | criando-ambiente-sql |
---|
label | Criando o Ambiente ambiente SQL |
---|
title | Criando o Ambiente ambiente SQL |
---|
| Persistência de Dados dados Query para a criação da tabela de usuários: Bloco de código |
---|
language | sql |
---|
theme | Confluence |
---|
firstline | 1 |
---|
title | Criando Tabela de Usuários |
---|
| CREATE TABLE public.tb_users
(
id integer NOT NULL DEFAULT nextval('tb_users_seq'::regclass),
email character varying(50) COLLATE pg_catalog."default" NOT NULL,
password character varying(50) COLLATE pg_catalog."default",
enable boolean,
register text COLLATE pg_catalog."default" DEFAULT now()
) |
|
Card |
---|
effectDuration | 0.5 |
---|
id | acesso |
---|
label | Acesso |
---|
title | Acesso |
---|
| Conexão em Produção produção Para acessar Acesse a página de administração do banco de dados acesse o PGADMIN.Acesse usando pelo PGADMIN, utilizando o usuário administrador do banco. Para encontrar a tabela vá em Servers → Applinker → Databases → AppLinker → Schemas → Public → Tables → tb_users Painel |
---|
title | Acessando as tabelas |
---|
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | usuarios |
---|
label | Usuários |
---|
title | Usuários |
---|
| Permissões de UsuáriosusuáriosApós aberta Localize a tabela você poderá clicar de usuários, clique com o botão direito do mouse , clicar sobre e selecione a opção Query Tool. Assim, e em seguida será aberta uma tela para que possa ser criado querys SQL na tabela. área para possibilitar a criação de querys ( itálico ) SQ Painel |
---|
|
Aviso |
---|
Caso o serviço de verificação de e-mails esteja instável ou fora do ar, será necessário alterar a permissão por uma query. |
O campo "enable" é que diz indica se o usuário têm ou não permissãopara entrar no APPLINKER. Para alterar a permissão do usuário execute: Bloco de código |
---|
language | sql |
---|
theme | Confluence |
---|
title | Altorizando usuário |
---|
| UPDATE tb_users SET enable = true WHERE email = '[email protected]'; |
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | administracao-usuarios |
---|
label | Administração de Usuáriosusuários |
---|
title | Administração de Usuáriosusuários |
---|
| Serviço de Ee-mails Aviso |
---|
Por motivos de segurança não será posto nenhum gif ou imagem do processo de manuseio do Google Cloud, pois as ilustrações exibem informações sensiveis. |
O APPLINKER possui um mecanismo para criação de novos usuários e recuperação de senha. O processo para criação de novos usuários se resume em: - Usuário cadastra suas informações informa seus dados pelo cadastro do AppLinker.
- O APPLINKER envia ume-mail de confirmação para criação do o usuário.
- O usuário recebe o e-mail e confirma o cadastro clicando no botão de ativação presente no e-mail recebido.
O processo para recuperação de senha: - Usuário informa o e-mail para recuperação de senha pelo AppLinker.
- O APPLINKER envia um e-mail com o link para recuperação de senha.
- Usuário informa a nova senha e envia as alterações. nova senha e envia as alterações.
- Após o envio, o mesmo receberá um e-mail na sua caixa de entrada para confirmar a troca de senha.
- Clicando no botão "Alterar Senha" presente no e-mail, o usuário será redirecionado para uma tela onde informará senha e a confirmação da senha.
O server do APPLINKER é responsável por todo esse provisionamento do serviço de e-mails. As informações do cadastro do serviço de e-mails com autenticação de dois fatores está no Google Cloud. Aviso | Por motivos de segurança não será posto nenhum gif do processo para acessar as informações presentes no Google Cloud.Para acessar as informações selecione o time "Google Play Android Developer". Na seção "IDs do Cliente OAuth 2.0" clique sobre "App Linker Emails". Neste painel você terá acesso as informações presentes no server do APPLINKER, no arquivo smtp.js. |
Card |
---|
id | provisionamento-aplicação |
---|
label | Provisionamento da Aplicaçãoaplicação |
---|
title | Provisionamento da Aplicaçãoaplicação |
---|
| Deck of Cards |
---|
effectDuration | 0.5 |
---|
id | Acessos |
---|
| Card |
---|
effectDuration | 0.5 |
---|
id | painel-acesso |
---|
label | Painel de Acessoacesso |
---|
title | Painel de Acessoacesso |
---|
| Gestão com RancherRancher é uma plataforma para gestão de aplicações Docker. Por meio do Rancher disponibilizamos e gerenciamos as aplicações Backend e Frontend do APPLINKER. Para acessar os containers Docker: - Acesse o painel de administração do Rancher.
- Informe as credenciais de acesso. (As credenciais são , com o seu usuário e senha de rede).
Após logado você será direcionado para página de "Clusters". Acesse o projeto clicando no cluster "engpro-eks" e em seguida "mobile".
Painel |
---|
title | Rancher - Primeiro Acesso |
---|
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | deploy-restart-aplicacoes |
---|
label | Deploy e Restart restart das Aplicaçõesaplicações |
---|
title | Deploy e Restart restart das Aplicaçõesaplicações |
---|
| Administrando ContainerscontainersEm alguns momentos, as aplicações ficam fora do ar ou apresentam instabilidade. Neste caso será necessário reiniciar as aplicações. alguma instabilidade e, nestes casos, é necessário que as aplicações sejam reiniciadas. Para reiniciá-las, selecione Para reiniciar as aplicações selecione applinker-client e o applinker-server e em seguida clique em "Redeploy". Painel |
---|
title | Rancher - Redeploy/Refresh |
---|
| |
|
Card |
---|
effectDuration | 0.5 |
---|
id | shell |
---|
label | Shell |
---|
title | Shell |
---|
| Terminal e LogslogsEm alguns momentos, as aplicações ficam fora do ar ou apresentam instabilidade, sejam elas Client, Server ou Banco de Dados. Nesses casos é imporante visualizar os logs da aplicação, ou executar comandos via terminal. Para visualizar os logs da aplicação: - Clique sobre a aplicação que deseja visualizar os logs.
- Na seção dos Pods clique sobo valor do campo name com o state = Running.
- Na seção Containers, clique nos 3 pontos, em seguida em View Logs do container desejado para visualizar os logs.
Para executar comandos: - Clique sobre a aplicação que deseja executar os comandos.
- Na seção dos Pods clique sobo valor do campo name com o state = Running.
- Na seção Containers clique nos 3 pontos, em seguida em Execute Shell do container desejado para executar os comandos.
Painel |
---|
title | Rancher - Logs e Terminal |
---|
|
|
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | gerar-alias |
---|
label | Gerar Aliasalias |
---|
title | Gerar Aliasalias |
---|
| EndPoint e Geração geração do AliasA funcionalidade mais importante da aplicação do APPLINKER é a geração de do Alias. Realizamos uma requisição com verbo POST passando filial e empresa. Segue o EndPoint e corpo JSON utilizados para realizar a geração de do Alias. Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | EndPoint |
---|
| https://applinkerserver.applinker.engpro.totvs.com.br/mingle/connect |
Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | Payload |
---|
| {
"app": "dado_sensivel",
"params": [
{
"EMPRESA": "09"
},
{
"FILIAL": "09"
}
],
"socket_id": "dado_sensivel"
} |
Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | Response |
---|
| {"prefix":"APP","sufix":"[email protected]"} |
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | desenvolvimento |
---|
label | Desenvolvimento |
---|
title | Desenvolvimento |
---|
| Deck of Cards |
---|
startHidden | false |
---|
effectDuration | 0.5 |
---|
id | configuracao-tecnica |
---|
| Card |
---|
effectDuration | 0.5 |
---|
id | instalacao |
---|
label | Instalação |
---|
title | Instalação |
---|
| Clone dos Projetos projetos O APPLINKER possui dois repositórios. Um contém o projeto Frontend e o outro o Backend. Segue os links para os repositórios: |
Card |
---|
effectDuration | 0.5 |
---|
id | ambiente-desenvolvimento |
---|
label | Ambiente de Desenvolvimentodesenvolvimento |
---|
title | Ambiente de Desenvolvimentodesenvolvimento |
---|
| Configurar MáquinamáquinaPara subir o client e o server do APPLINKER em uma máquina para fins de desenvolvimento, é necessário instalar algumas dependencias. Segue uma lista de tecnologias que devem estar presentes. Para subir o client: Para subir o server: Instale o Banco de Dados Postgree para PGADMIN para testes locais. As branchs para iniciar o desenvolvimento de qualquer feature devem ser feitas a partir da "develop" (tanto client como server). Aviso |
---|
Antes de desenvolver configure os arquivos dos projetos para que apontem para ambiente local. |
|
Card |
---|
effectDuration | 0.5 |
---|
id | aponte-local |
---|
label | Aponte para Local |
---|
title | Aponte para Local |
---|
| Deck of Cards |
---|
effectDuration | 0.5 |
---|
id | arquivos |
---|
| Card |
---|
effectDuration | 0.5 |
---|
id | frontend |
---|
label | Frontend |
---|
title | Frontend |
---|
| Alterando para LocalHostlocalhost Aviso |
---|
Todas as requisições são feitas para ambiente de produção. Altere os arquivos para que sejam direcionadas para localhost. |
Note a seguir que o client faz todas as suas requisições usando um provider HttpService. Neste HttpService usamos uma constante que possui a URL para onde estamos apontando, para localhost ou produção. Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | AppLinkerClient/app/src/app/providers/http.service.ts |
---|
| import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
const APP_API = environment.api;
@Injectable({
providedIn: 'root'
})
export class HttpService {
constructor(private http: HttpClient) { }
get(endpoint) {
return this.http.get(`${APP_API}/${endpoint}`);
}
post(endpoint, body = {}) {
return this.http.post(`${APP_API}/${endpoint}`, body);
}
} |
No arquivo environment.ts altere o valor do objeto de: Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | AppLinkerClient/app/src/environments/environment.ts |
---|
| export const environment = {
production: true,
api: 'https://applinkerserver.applinker.engpro.totvs.com.br'
}; |
para: Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | AppLinkerClient/app/src/environments/environment.ts |
---|
| export const environment = {
production: false,
api: 'http://localhost:3000'
}; |
Dica |
---|
Visualize o arquivo package.json no atributo scripts para identificar as configurações de porta. |
|
Card |
---|
effectDuration | 0.5 |
---|
id | backend |
---|
label | Backend |
---|
title | Backend |
---|
| Serviço de Ee-mails Aviso |
---|
Todas as requisições são feitas para ambiente de produção. Altere os arquivos para que sejam direcionadas para localhost. |
Para que as funcionalidades "Ativação de Usuários", "Recuperação de Senha" funcionem em ambiente local, altere os dados da configuração do banco e do ambiente de produção. No arquivo config_db.ts altere o valor do objeto de: Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | AppLinkerServer/server/modules/database/config_db.ts |
---|
| export class ConfigDB {
private conn;
public async connectDB() {
const { Pool, Client } = require('pg')
const connectionString = "postgres://applinker:dado_sensivel@postgres:5432/applinker"
const pool = new Pool({
connectionString: connectionString,
})
pool
.connect()
.then( ()=> console.info('conectado com sucesso'))
.catch( () => console.info('falha ao conectar com o banco de dados.'))
return await pool
}
}
|
para: Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | AppLinkerServer/server/modules/database/config_db.ts |
---|
| export class ConfigDB {
private conn;
public async connectDB() {
const { Pool, Client } = require('pg')
const connectionString = "postgres://postgres:123456@localhost:5432/applinker";
const pool = new Pool({
connectionString: connectionString,
})
pool
.connect()
.then( ()=> console.info('conectado com sucesso'))
.catch( () => console.info('falha ao conectar com o banco de dados.'))
return await pool
}
}
|
No arquivo controller.ts altere o código de: Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | AppLinkerServer/server/modules/auth/controller.ts |
---|
| import { ConfigDB } from './../database/config_db';
import { Request, Response } from 'express';
import * as ldap from 'ldapjs';
import * as jwt from 'jsonwebtoken';
import * as nodemailer from 'nodemailer';
import { google } from 'googleapis';
const SMTP_CONFIG = require('./../../config/env/smtp')
const config = require('../../config/env/')();
// declaracao do OAuth2
const OAuth2 = google.auth.OAuth2;
export class AuthController {
protected client;
protected adSuffix = "dc=local";
constructor() {
// this.client = ldap.createClient({
// url: config.activeDirectory.url
// });
// this.client.bind(config.activeDirectory.user, config.activeDirectory.password, err => {
// if (err) {
// throw new Error('user LDAP não autenticado!');
// }
// });
}
public auth(req: Request, res: Response, next: any) {
this.authWithoutAD(req, res, next);
}
// public authWithAD(req: Request, res: Response, next: any) {
// const searchOptions = {
// scope: "sub",
// filter: `(&(objectClass=person)(sAMAccountName=${req.body.user})(!(userAccountControl:1.2.840.113556.1.4.803:=2)))`
// };
// this.client.search(this.adSuffix,searchOptions,(err, response) => {
// console.log('logando...');
// if (err) {
// console.log(`erro ao efetuar as busca ${err}`);
// }
// response.on('searchEntry', entry => {
// console.log('buscando login...');
// this.client.bind(entry.object.dn, req.body.password, (err) => {
// if (err) {
// res.status(400);
// res.send({error: "Unauthorized"});
// } else {
// res.send({
// user: entry.object.sAMAccountName,
// userEmail: entry.object.mail,
// token: jwt.sign({user: entry.object.sAMAccountName}, config.masterKey)
// });
// }
// res.end();
// });
// });
// });
// req.setTimeout(20000);
// }
public async register(req: Request, res: Response, next: any) {
const db = new ConfigDB();
try {
const conn = await db.connectDB();
let result = await conn.query("select * from tb_users where email = $1 ", [req.body.user]);
if (result.rows.length > 0) {
return res.status(400).send({ error: "O email ja esta sendo utilizado." });
}
result = await conn.query("insert into tb_users (email, password,enable) values ($1, md5($2),false)", [req.body.user, req.body.password]);
if (!result.err) {
res.send({
userEmail: req.body.user
});
await this.sentEmail(req.body.user)
} else {
res.status(400).send({ error: "Não foi possivel cadastrar" });
}
conn.end();
} catch (err) {
return res.status(500).send({ error: err.name });
}
}
public async authWithoutAD(req: Request, res: Response, next: any) {
const db = new ConfigDB();
try {
const conn = await db.connectDB();
let result = await conn.query("select email from tb_users where email = $1 and password = md5($2) and enable = true", [req.body.user, req.body.password]);
if (result.rowCount > 0) {
res.send({
user: req.body.user.split("@")[0],
userEmail: req.body.user,
token: jwt.sign({ user: req.body.user }, config.masterKey)
});
} else {
result = await conn.query("select email from tb_users where email = $1 and password = md5($2) and enable = false", [req.body.user, req.body.password]);
if (result.rowCount > 0) {
res.status(401).send({ error: "Usuário aguardando aprovação " });
} else {
res.status(403).send({ error: "Senha ou email incorretos " });
}
}
} catch (err) {
res.status(500).send({ error: err.name });
}
}
// Acrescentando OAuth2 Authentication
public async sentEmail(email: string): Promise<void> {
const emailToken = jwt.sign({ email }, config.masterKey);
const oauth2Client = new OAuth2(SMTP_CONFIG.client_id, SMTP_CONFIG.secret_key, SMTP_CONFIG.redirect_uri);
oauth2Client.setCredentials({
refresh_token: SMTP_CONFIG.refresh_token
})
const accessToken = await oauth2Client.getAccessToken().then((token) => {
return token.token;
})
const transporter = await nodemailer.createTransport({
host: SMTP_CONFIG.host,
port: SMTP_CONFIG.port,
secure: true,
auth: {
type: 'OAuth2',
user: SMTP_CONFIG.user,
clientId: SMTP_CONFIG.client_id,
clientSecret: SMTP_CONFIG.secret_key,
refreshToken: SMTP_CONFIG.refresh_token,
accessToken: accessToken
}
})
await transporter.sendMail({
subject: 'Verificação de acesso ao AppLinker',
from: 'Protheus Mobile' + `<${SMTP_CONFIG.user}>`,
to: `${email}`,
html: `<div>
<div
style="background:#4DBFBF;background-color:#4DBFBF;margin:0px auto;max-width:600px;"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="background:#4DBFBF;background-color:#ffffff;width:100%;"
>
<tbody>
<tr>
<td
style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;vertical-align:top;"
>
<div
class="dys-column-per-100 outlook-group-fix"
style="direction:ltr;display:inline-block;font-size:13px;text-align:left;vertical-align:top;width:100%;"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align:top;"
width="100%"
>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style='color:#0c9abe;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:36px;line-height:1;text-align:center;'
>
Boas Vindas
</div>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style='color:#586a6e;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:16px;line-height:20px;text-align:center;'
>
<br />
Para ativar sua conta no AppLinker clique no botão abaixo:
<br />
<br />
</div>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
vertical-align="middle"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="border-collapse:separate;line-height:100%;width:200px;"
>
<tr>
<td
align="center"
bgcolor="#178F8F"
role="presentation"
style='background-color:#0c9abe; border:"solid 1px red";border-radius:4px;cursor:auto;padding:10px 25px;'
valign="middle"
>
<a
href="https://applinkerserver.applinker.engpro.totvs.com.br/auth/validate/${emailToken}"
style='background-color:#0c9abe; color:white;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:16px;font-weight:bold;line-height:30px;margin:0;text-decoration:none;text-transform:none;'
target="_blank"
>
Ativar
</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style=' color:#586a6e;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:12px;margin-top:10;text-decoration:none;text-transform:none;'
>
Para mais detalhes a respeito do uso da AppLinker <a href="https://tdn.totvs.com/x/KHbQHw">clique aqui!<a/>
</div>
</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
>`
}).catch(error => {
console.log(error)
})
}
public async sentEmailToReset(req: Request, res: Response, next: any): Promise<void> {
try {
const email = req.body.user;
const emailToken = jwt.sign({ email }, config.masterKey);
const oauth2Client = new OAuth2(SMTP_CONFIG.client_id, SMTP_CONFIG.secret_key, SMTP_CONFIG.redirect_uri);
oauth2Client.setCredentials({
refresh_token: SMTP_CONFIG.refresh_token
})
const accessToken = await oauth2Client.getAccessToken().then((token) => {
return token.token;
})
const transporter = await nodemailer.createTransport({
host: SMTP_CONFIG.host,
port: SMTP_CONFIG.port,
secure: true,
auth: {
type: 'OAuth2',
user: SMTP_CONFIG.user,
clientId: SMTP_CONFIG.client_id,
clientSecret: SMTP_CONFIG.secret_key,
refreshToken: SMTP_CONFIG.refresh_token,
accessToken: accessToken
}
})
await transporter.sendMail({
subject: 'Verificação de acesso ao AppLinker',
from: 'Protheus Mobile' + `<${SMTP_CONFIG.user}>`,
to: `${email}`,
html: `<div>
<div
style="background:#4DBFBF;background-color:#4DBFBF;margin:0px auto;max-width:600px;"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="background:#4DBFBF;background-color:#ffffff;width:100%;"
>
<tbody>
<tr>
<td
style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;vertical-align:top;"
>
<div
class="dys-column-per-100 outlook-group-fix"
style="direction:ltr;display:inline-block;font-size:13px;text-align:left;vertical-align:top;width:100%;"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align:top;"
width="100%"
>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style='color:#0c9abe;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:36px;line-height:1;text-align:center;'
>
Boas Vindas
</div>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style='color:#586a6e;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:16px;line-height:20px;text-align:center;'
>
<br />
Para alterar a senha cadastrada no AppLinker clique no botão abaixo:
<br />
<br />
</div>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
vertical-align="middle"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="border-collapse:separate;line-height:100%;width:200px;"
>
<tr>
<td
align="center"
bgcolor="#178F8F"
role="presentation"
style='background-color:#0c9abe; border:"solid 1px red";border-radius:4px;cursor:auto;padding:10px 25px;'
valign="middle"
>
<a
href="https://applinker.engpro.totvs.com.br/reset-password?token=${emailToken}"
style='background-color:#0c9abe; color:white;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:16px;font-weight:bold;line-height:30px;margin:0;text-decoration:none;text-transform:none;'
target="_blank"
>
Alterar Senha
</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style=' color:#586a6e;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:12px;margin-top:10;text-decoration:none;text-transform:none;'
>
Para mais detalhes a respeito do uso da AppLinker <a href="https://tdn.totvs.com/x/KHbQHw">clique aqui!<a/>
</div>
</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>`
}).then(() => {
res.status(200).send({ message: 'Email enviado com sucesso.' });
}).catch(error => {
res.status(500).send({ message: 'Não foi possivel enviar o email.' })
})
} catch (err) {
console.log('aqui')
res.status(500).send({ error: err.name });
}
}
public async validate(req: Request, res: Response, next: any) {
const db = new ConfigDB();
try {
const conn = await db.connectDB();
const token = req.params.token;
if (token) {
jwt.verify(token, config.masterKey, async (err, decodedToken) => {
if (err) {
return res.status(400).json({ error: 'Incorrect token' });
}
const { email } = decodedToken;
let result = await conn.query("update tb_users set enable = true where email = $1 and enable = false", [email]);
return res.redirect('https://applinker.engpro.totvs.com.br/login?isActive=true')
})
} else {
res.status(500).send({ error: 'Invalid token' });
}
} catch (err) {
res.status(500).send({ error: err.name });
}
}
public async resetPassword(req: Request, res: Response, next: any) {
const db = new ConfigDB();
try {
const conn = await db.connectDB();
const token = req.body.token;
if (token) {
jwt.verify(token, config.masterKey, async (err, decodedToken) => {
if (err) {
return res.status(400).json({ error: 'Incorrect token' });
}
const { email } = decodedToken;
let result = await conn.query("update tb_users set password = md5($2) where email = $1", [email, req.body.password]);
if (result.rowCount > 0) {
res.status(200).send({ message: "Senha alterada com sucesso" });
} else {
res.status(403).send({ error: "Não foi possivel alterar a senha." });
}
})
} else {
res.status(500).send({ error: 'Invalid token' });
}
} catch (err) {
res.status(500).send({ error: err.name });
}
}
}
|
para: Bloco de código |
---|
language | js |
---|
theme | Midnight |
---|
firstline | 1 |
---|
title | AppLinkerServer/server/modules/auth/controller.ts |
---|
| import { ConfigDB } from './../database/config_db';
import { Request, Response } from 'express';
import * as jwt from 'jsonwebtoken';
import * as nodemailer from 'nodemailer';
import { google } from 'googleapis';
const SMTP_CONFIG = require('./../../config/env/smtp')
const config = require('../../config/env/')();
// declaracao do OAuth2
const OAuth2 = google.auth.OAuth2;
export class AuthController {
protected client;
protected adSuffix = "dc=local";
constructor() {}
public auth(req: Request, res: Response, next: any) {
this.authWithoutAD(req, res, next);
}
public async register(req: Request, res: Response, next: any) {
const db = new ConfigDB();
try {
const conn = await db.connectDB();
let result = await conn.query("select * from tb_users where email = $1 ", [req.body.user]);
if (result.rows.length > 0) {
return res.status(400).send({ error: "O email ja esta sendo utilizado." });
}
await conn.query("insert into tb_users (email, password,enable) values ($1, md5($2),false)", [req.body.user, req.body.password]).then(res => {
result = res
}).catch(error => {
console.log(error);
});
if (!result.err) {
res.send({
userEmail: req.body.user
});
await this.sentEmail(req.body.user)
} else {
res.status(400).send({ error: "Não foi possivel cadastrar" });
}
conn.end();
} catch (err) {
return res.status(500).send({ error: err.name });
}
}
public async authWithoutAD(req: Request, res: Response, next: any) {
const db = new ConfigDB();
try {
const conn = await db.connectDB();
let result = await conn.query("select email from tb_users where email = $1 and password = md5($2) and enable = true", [req.body.user, req.body.password]);
if (result.rowCount > 0) {
res.send({
user: req.body.user.split("@")[0],
userEmail: req.body.user,
token: jwt.sign({ user: req.body.user }, config.masterKey)
});
} else {
result = await conn.query("select email from tb_users where email = $1 and password = md5($2) and enable = false", [req.body.user, req.body.password]);
if (result.rowCount > 0) {
res.status(401).send({ error: "Usuário aguardando aprovação " });
} else {
res.status(403).send({ error: "Senha ou email incorretos " });
}
}
} catch (err) {
res.status(500).send({ error: err.name });
}
}
// Acrescentando OAuth2 Authentication
public async sentEmail(email: string): Promise<void> {
const emailToken = jwt.sign({ email }, config.masterKey);
const oauth2Client = new OAuth2(SMTP_CONFIG.client_id, SMTP_CONFIG.secret_key, SMTP_CONFIG.redirect_uri);
oauth2Client.setCredentials({
refresh_token: SMTP_CONFIG.refresh_token
})
const accessToken = await oauth2Client.getAccessToken().then((token) => {
return token.token;
})
const transporter = await nodemailer.createTransport({
host: SMTP_CONFIG.host,
port: SMTP_CONFIG.port,
secure: true,
auth: {
type: 'OAuth2',
user: SMTP_CONFIG.user,
clientId: SMTP_CONFIG.client_id,
clientSecret: SMTP_CONFIG.secret_key,
refreshToken: SMTP_CONFIG.refresh_token,
accessToken: accessToken
}
})
await transporter.sendMail({
subject: 'Verificação de acesso ao AppLinker',
from: 'Protheus Mobile' + `<${SMTP_CONFIG.user}>`,
to: `${email}`,
html: `<div>
<div
style="background:#4DBFBF;background-color:#4DBFBF;margin:0px auto;max-width:600px;"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="background:#4DBFBF;background-color:#ffffff;width:100%;"
>
<tbody>
<tr>
<td
style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;vertical-align:top;"
>
<div
class="dys-column-per-100 outlook-group-fix"
style="direction:ltr;display:inline-block;font-size:13px;text-align:left;vertical-align:top;width:100%;"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align:top;"
width="100%"
>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style='color:#0c9abe;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:36px;line-height:1;text-align:center;'
>
Boas Vindas
</div>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style='color:#586a6e;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:16px;line-height:20px;text-align:center;'
>
<br />
Para ativar sua conta no AppLinker clique no botão abaixo:
<br />
<br />
</div>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
vertical-align="middle"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="border-collapse:separate;line-height:100%;width:200px;"
>
<tr>
<td
align="center"
bgcolor="#178F8F"
role="presentation"
style='background-color:#0c9abe; border:"solid 1px red";border-radius:4px;cursor:auto;padding:10px 25px;'
valign="middle"
>
<a
href="http://localhost:3000/auth/validate/${emailToken}"
style='background-color:#0c9abe; color:white;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:16px;font-weight:bold;line-height:30px;margin:0;text-decoration:none;text-transform:none;'
target="_blank"
>
Ativar
</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style=' color:#586a6e;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:12px;margin-top:10;text-decoration:none;text-transform:none;'
>
Para mais detalhes a respeito do uso da AppLinker <a href="https://tdn.totvs.com/x/KHbQHw">clique aqui!<a/>
</div>
</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
>`
}).catch(error => {
console.log(error)
})
}
public async sentEmailToReset(req: Request, res: Response, next: any): Promise<void> {
try {
const email = req.body.user;
const emailToken = jwt.sign({ email }, config.masterKey);
const oauth2Client = new OAuth2(SMTP_CONFIG.client_id, SMTP_CONFIG.secret_key, SMTP_CONFIG.redirect_uri);
oauth2Client.setCredentials({
refresh_token: SMTP_CONFIG.refresh_token
})
const accessToken = await oauth2Client.getAccessToken().then((token) => {
return token.token;
})
const transporter = await nodemailer.createTransport({
host: SMTP_CONFIG.host,
port: SMTP_CONFIG.port,
secure: true,
auth: {
type: 'OAuth2',
user: SMTP_CONFIG.user,
clientId: SMTP_CONFIG.client_id,
clientSecret: SMTP_CONFIG.secret_key,
refreshToken: SMTP_CONFIG.refresh_token,
accessToken: accessToken
}
})
await transporter.sendMail({
subject: 'Verificação de acesso ao AppLinker',
from: 'Protheus Mobile' + `<${SMTP_CONFIG.user}>`,
to: `${email}`,
html: `<div>
<div
style="background:#4DBFBF;background-color:#4DBFBF;margin:0px auto;max-width:600px;"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="background:#4DBFBF;background-color:#ffffff;width:100%;"
>
<tbody>
<tr>
<td
style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;vertical-align:top;"
>
<div
class="dys-column-per-100 outlook-group-fix"
style="direction:ltr;display:inline-block;font-size:13px;text-align:left;vertical-align:top;width:100%;"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align:top;"
width="100%"
>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style='color:#0c9abe;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:36px;line-height:1;text-align:center;'
>
Boas Vindas
</div>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style='color:#586a6e;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:16px;line-height:20px;text-align:center;'
>
<br />
Para alterar a senha cadastrada no AppLinker clique no botão abaixo:
<br />
<br />
</div>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
vertical-align="middle"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="border-collapse:separate;line-height:100%;width:200px;"
>
<tr>
<td
align="center"
bgcolor="#178F8F"
role="presentation"
style='background-color:#0c9abe; border:"solid 1px red";border-radius:4px;cursor:auto;padding:10px 25px;'
valign="middle"
>
<a
href="http://localhost:3000/reset-password?token=${emailToken}"
style='background-color:#0c9abe; color:white;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:16px;font-weight:bold;line-height:30px;margin:0;text-decoration:none;text-transform:none;'
target="_blank"
>
Alterar Senha
</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td
align="center"
style="font-size:0px;padding:10px 25px;word-break:break-word;"
>
<div
style=' color:#586a6e;font-family:"Droid Sans", "Helvetica Neue", Arial, sans-serif;font-size:12px;margin-top:10;text-decoration:none;text-transform:none;'
>
Para mais detalhes a respeito do uso da AppLinker <a href="https://tdn.totvs.com/x/KHbQHw">clique aqui!<a/>
</div>
</td>
</tr>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>`
}).then(() => {
res.status(200).send({ message: 'Email enviado com sucesso.' });
}).catch(error => {
res.status(500).send({ message: 'Não foi possivel enviar o email.' })
})
} catch (err) {
res.status(500).send({ error: err.name });
}
}
public async validate(req: Request, res: Response, next: any) {
const db = new ConfigDB();
try {
const conn = await db.connectDB();
const token = req.params.token;
if (token) {
jwt.verify(token, config.masterKey, async (err, decodedToken) => {
if (err) {
return res.status(400).json({ error: 'Incorrect token' });
}
const { email } = decodedToken;
let result = await conn.query("update tb_users set enable = true where email = $1 and enable = false", [email]);
return res.redirect('http://localhost:4200/login?isActive=true')
})
} else {
res.status(500).send({ error: 'Invalid token' });
}
} catch (err) {
res.status(500).send({ error: err.name });
}
}
public async resetPassword(req: Request, res: Response, next: any) {
const db = new ConfigDB();
try {
const conn = await db.connectDB();
const token = req.body.token;
if (token) {
jwt.verify(token, config.masterKey, async (err, decodedToken) => {
if (err) {
return res.status(400).json({ error: 'Incorrect token' });
}
const { email } = decodedToken;
let result = await conn.query("update tb_users set password = md5($2) where email = $1", [email, req.body.password]);
if (result.rowCount > 0) {
res.status(200).send({ message: "Senha alterada com sucesso" });
} else {
res.status(403).send({ error: "Não foi possivel alterar a senha." });
}
})
} else {
res.status(500).send({ error: 'Invalid token' });
}
} catch (err) {
res.status(500).send({ error: err.name });
}
}
} |
|
|
|
Card |
---|
effectDuration | 0.5 |
---|
id | banco-dados |
---|
label | Banco de Dadosdados |
---|
title | Banco de Dadosdados |
---|
| Deck of Cards |
---|
| Card |
---|
effectDuration | 0.5 |
---|
id | crie-server |
---|
label | Crie um Serverserver |
---|
title | Crie um Serverserver |
---|
| Criando o DataBase DatabasePara criar um Banco de Dados clique com o botão direito em "Databases" e depois em "Create". De o nome de "applinker" e clique em "Save". Painel |
---|
title | Criação do Serverserver |
---|
|
|
|
Card |
---|
id | tabela |
---|
label | Tabela |
---|
title | Tabela |
---|
| Criando a TabelatabelaPara criar uma tabela no Banco banco de Dados dados clique com o botão direito em "Tables" e depois em "Query Tool". Com o editor de querys aberto execute o script. Bloco de código |
---|
language | sql |
---|
theme | Confluence |
---|
firstline | 1 |
---|
title | Ambiente Local |
---|
| CREATE TABLE public.tb_users
(
id serial NOT NULL,
email character varying(50) COLLATE pg_catalog."default" NOT NULL,
password character varying(50) COLLATE pg_catalog."default",
enable boolean,
register text COLLATE pg_catalog."default" DEFAULT now()
) |
Segue a baixo abaixo uma representação: Painel |
---|
title | Criando a Tabelatabela |
---|
|
|
|
|
|
|
|
|
|
|
|