#04 Tela de login com recuperação de senha (Angular 19 + Supabase) | [Série] Criando um SaaS do ZERO

Neste vídeo de quase duas horas, Samuel Rezon faz um live‑coding demonstrando como implementar autenticação completa – login, logout, recuperação e redefinição de senha – em um SaaS Angular (NX) usando Supabase como BaaS. Ele começa explicando o que é Supabase, comparando‑o com Firebase (SQL vs NoSQL, modelo de preço, open‑source, recursos como real‑time, Edge Functions, storage, logs, backups, cron jobs). Em seguida cria uma conta Supabase, explora o dashboard (table editor, SQL editor, visualizer, backups, policies, logs, API docs, cron jobs) e cria a tabela pública users com Row‑Level Security e triggers que sincronizam o perfil ao criar um usuário. Configura o ambiente Angular: adiciona dark‑mode do ng‑zorro, cria arquivos de tema, ajusta o tsconfig para alias @env, instala supabase‑js, cria um serviço Supabase injetável com URL e key nos environments. Implementa a tela de login usando ng‑zorro, Reactive Forms e Angular Signals, chama supabase.auth.signInWithPassword, persiste a sessão no localStorage, usa AppInitializer para carregar a sessão ao iniciar e cria um AuthGuard que redireciona usuários já autenticados fora das rotas de auth. Depois cria a página “Esqueci minha senha”, envia o e‑mail de reset via Supabase, configura os templates de e‑mail no dashboard e cria a página de “Reset password” que atualiza a senha com supabase.auth.updateUser. Também demonstra uso de LoadingService, NotificationService, Copilot para gerar código e mensagens. Ao final, o fluxo completo de login, proteção de rotas e recuperação de senha está funcional, mostrando que todo o backend pode ser gerido apenas com Supabase e o frontend Angular.
Chapters
E aí, meus amigos, tudo bem com vocês? Samuel Rezon por aqui e hoje a gente vai falar sobre o Supabase. Eu vou mostrar tudo que ele tem para oferecer para gente e como é que a gente pode criar um sistema de autenticação com Angular e o Supabase. Tava muito ansioso para falar sobre isso, então se prepara porque vai ser incrível. Já deixa o like, se inscreve no canal, ativa o sininho para não perder nenhum vídeo. E antes de começar, eu criei uma comunidade do canal no WhatsApp, é o primeiro link aqui na descrição, e foi uma forma que eu encontrei de ficar mais próximo de vocês, de tirar dúvida, de receber feedback, da gente trocar ideia, falar sobre Angular, Supabase, todas essas questões que a gente tá falando aqui nessa série. Então depois de assistir o vídeo, vai lá, clica no link e entra na nossa comunidade, fechou? Bora pro vídeo. Bom, hoje a gente vai falar sobre o Superbase, meu querido Superbase. E a primeira coisa que eu quero deixar bem claro para vocês é que o Superbase ele é um BaaS. Que que é um BaaS? É um backend as a service. Então a gente tem um SaaS que a gente tá criando, que é um software as a service, e a gente tem também um backend as a service. O Supabase, ele pode ser utilizado no back-end. Então a gente pode sim utilizar o Supabase no Node.js, a gente pode utilizar o Supabase em um C# da vida, não importa. A gente pode sim, mas ele é um back-end as a service. O nosso objetivo aqui como um sistema, e o nosso objetivo aqui criando o nosso SaaS, é que o Supabase seja o nosso back-end principal. A gente, a ideia não vai ser A ideia não vai ser criar um outro backend ou fazer alguma outra coisa. A gente vai utilizar o Supabase porque eu vou provar para vocês que é possível fazer um sistema inteiro só no frontend. Fechou? Outra coisa legal do Supabase é que ele é uma alternativa open source ao Firebase. Então o Supabase, por ele ser open source, a gente consegue, por exemplo, pegar todas as instâncias dele do Docker subir na nossa própria infraestrutura. Só que o Supabase, ele tem a própria infraestrutura dele com um plano gratuito. Se você chegar, se você quiser pagar, você pode pagar, mas ele já tem um plano gratuito. A gente vai utilizar 100% do plano gratuito dele por enquanto, e ele tem toda a infraestrutura dele. Então a gente não tem que se preocupar com DevOps, a gente não tem que se preocupar com container dock, com escalabilidade. Enfim, vou mostrar e vou falar bem sobre isso para vocês. E o que me fez amar o Supabase, o que me fez usar o Supabase, é o banco de dados ser Postgres, porque eu não me acostumei com banco de dados não-relacional. E eu vou falar aqui sobre a diferença do Supabase e o Firebase para quem tá acostumado, porque o Firebase é o que é, é o mais conhecido, né, hoje em dia. Mas o que me fez vir para o Supabase foi banco de dados Postgres, porque é um banco relacional e eu não consigo colocar na minha cabeça como que funciona o banco não-relacional.
Fechou?
Falando das diferenças do Supabase versus o Firebase. Então, sobre banco de dados, o Supabase usa o Postgres e o Firebase usa o Firestore, que é um não-relacional. Eles têm autenticação. O Supabase tem um real-time subscriptions, que a gente consegue trabalhar com dados em real-time. Eu vou mostrar na página inicial deles. O Firebase também tem isso. O Firebase tem um Cloud Functions, que é a mesma coisa do Edge Functions do Supabase. Então são funções serverless que a gente consegue rodar. Os dois também têm storage, então o Supabase tem um storage e o Firebase também. E uma coisa que o Firebase tem que o Supabase não tem é hosting. E a gente vai hospedar o nosso front-end no Firebase Hosting. Isso é uma coisa que eu uso no Firebase, que é gratuito também, e a gente consegue hospedar lá e é muito fácil da gente mexer com isso. Então sobre o banco de dados, no Firebase é NoSQL e no Supabase é um SQL normal. O Supabase ele é open source e o Firebase é mantido pela Google, então o dono do Firebase é a própria Google. Sobre preços e cobranças, no Supabase a cobrança ela é baseada na quantidade de dados armazenados, com solicitações de API ilimitadas e usuários de autenticação. Então no Supabase a gente consegue prever custo e isso faz muita diferença para o Firebase. Que no Firebase as cobranças são baseadas no número de leituras, gravações e exclusões. Então a gente não consegue ter uma previsibilidade do custo que a gente tem quando a nossa aplicação escalar num nível absurdo. Isso é uma coisa que a gente tem com o Supabase. Então isso também é uma diferença gritante, uma diferença que me faz gostar muito mais do Supabase. Desempenho, cara, é, os dois vão ter um alto desempenho, O Supabase eu gosto mais dele pelo Postgres, que é um banco relacional, e cara, tem tudo do Postgres, tem muita documentação. O Firebase, quando a gente precisa criar coisas complexas, eu acho que fica um pouco mais difícil. Então eu prefiro ainda o Supabase. Para mim o Supabase ganha em várias coisas, mas essas são as principais diferenças entre o Firebase e o Supabase. E aí, o que que a gente vai fazer no vídeo de hoje? Eu tenho aqui as etapas que a gente tinha falado dos nossos vídeos. Então hoje a gente vai cuidar dessa parte aqui do Supabase e dessa parte aqui de autenticação. Essa parte de tela de cadastro eu vou deixar para o próximo vídeo, porque esse vai ser um vídeo bem especial onde eu vou criar um formulário multi-step e também eu vou transformar os formulários que a gente vai criar aqui hoje em formulários dinâmicos. Vou mostrar para vocês como que eu trabalho no Angular criando formulários dinâmicos sem eu precisar ficar duplicando o código no HTML toda hora. Então eu vou transformar os formulários em um formulário dinâmico e criar um formulário multi-step salvando no local storage e tudo mais. Então esse vídeo vai ser um vídeo específico e hoje a gente vai cuidar dessa parte daqui. E aí, falando das etapas do vídeo de hoje, a gente vai fazer tudo isso aqui. A gente vai criar a conta no Superbase, eu vou mostrar o dashboard e as funcionalidades do Superbase, criar a tabela de usuários, configurar o role level security, criar um usuário de teste pelo Superbase, vou instalar e configurar ele no projeto, a gente vai codar a tela de autenticação com login e senha, codar a tela de esqueci minha senha, finalizar e fazer toda a parte de salvar o usuário no sistema pra gente ter ele criado e criar um guarda de rota de autenticação pra sempre direcionar pro login caso o usuário não estiver logado.
Show?
Tem bastante coisa. E um dos motivos de eu estar trazendo tudo isso aqui hoje é porque eu fiz uma pesquisa recente aqui no YouTube com o pessoal lá da comunidade, porque eu perguntei o que que eles preferiam em questão de duração de vídeo, se eram vídeos mais longos ou vídeos mais curtos. Então eu pretendo nesse vídeo criar um vídeo bem longo, vai ser praticamente um live coding aqui comigo e vai ser bem legal. Primeira coisa que eu quero falar para vocês sobre o Supabase, então a gente tá na landing page do Supabase E ele fala, né, cria em uma semana e escale para milhões. Isso é o Supabase, é uma alternativa open source ao Firebase e a gente consegue ter literalmente tudo isso aqui no plano gratuito. Então a gente tem um banco de dados Postgres, a gente tem autenticação, a gente tem as edge functions que são serverless, funções serverless, a gente tem storage Real-time, esse aqui é muito legal. O Supabase também tem um vector, que é a forma de integrar com os nossos sistemas. E a gente tem também APIs instantâneas, que eu vou mostrar para vocês. Isso aqui é maravilhoso. Tudo isso dentro do Supabase, a gente vai usar bastante coisa aqui. E aí, antes da gente criar a conta, eu só quero mostrar para vocês como que tá o projeto atualmente, que eu fiz algumas alterações aqui só para deixar ele já pronto para a gente mexer. Então, basicamente, o que eu fiz foi configurar o dark mode do ng-zorro aqui no projeto e preparar a tela de autenticação. Então se eu volto aqui no nosso sistema, eu vou mostrar para vocês, eu vou vir aqui na pasta /auth e quando eu entro aqui eu já tenho na minha barra de autenticação um card de minha barbearia e um toggle theme aqui do ng-zorro para mim transformar ele em um tema escuro. Como que eu fiz isso? Deixa eu voltar aqui no ng-zorro. Cara, essa documentação do ng-zorro aqui é perfeita e a gente vai usar bastante ela. Mas basicamente eu vim aqui em Theme Customization e eu procurei aqui na parte do Dark Mode, aqui ele vai mostrar, aqui, ó, Theme Dynamic Switching. E aí ele tem aqui um projeto de exemplo que basicamente eu vim aqui nesse projeto de exemplo, entendi qual que era o passo a passo, né, e foi Foi literalmente isso aqui. E aí eu copiei os arquivos de lá e colei no meu projeto, configurei. É muito simples. Então basicamente eu tenho os meus arquivos, eu tenho um arquivo base aqui para mim salvar minha cor primária, eu tenho meu arquivo dark e eu tenho meu arquivo default. Eu tenho meus dois arquivos principais, o meu style eu fechei ele, eu tive que adicionar aqui no styles a configuração aqui para ele do default e do dark. Isso aqui tá tudo lá naquela documentação do ng-zorro. Show! E uma outra coisa que eu adicionei é um arquivo de mídias, que é normalmente como eu costumo deixar o site responsivo, e a gente vai usar isso aqui mais para frente quando a gente precisar, tá bom? Então eu configurei essa parte de styles aqui. Isso aqui tá tudo aqui, ó, eu criei uma pasta de styles, os temas do os templates do NGZOHO estão aqui, mídias, dark, class, styles, o project que eu alterei. E eu também alterei aqui no app.config o theme service, e esse theme service é o do próprio NGZOHO, eu copiei e colei, e é basicamente um service pra gente alterar o tema. E quando eu preciso alterar esse tema, eu só chamo o theme service e dou um toggleTheme. E é basicamente isso que eu faço. Na página de login eu Eu só coloquei um ng-flex aqui e adicionei um botão que é aquele botão do toggle theme. Quando a gente vem aqui é esse carinha aqui. E no meu layout eu só coloquei um card chamado Minha Barbearia. Esse card aqui é do próprio ng-zorro e o router-outlet, porque esse aqui é o layout. Então todas as minhas páginas vão ter esse mesmo layout aqui. Um CSS customizado para deixar o card centralizado. E aqui, como eu disse, a mídia eu uso quando eu tiver em uma versão mobile, eu troco o widget dele para 90vw. Basicamente foi isso aqui que eu fiz no projeto. A gente vai comitar isso aqui. Deixa eu abrir um novo terminal. CCM, isso aqui é a nossa inteligência artificial trabalhando para criar mensagem de commit para mim. Então, add team switch funcionar, add team switch layout. Perfeito.
Commit e tá feito. Show!
Então, explicado porque o projeto tá um pouco diferente desde que a gente parou da última vez. E outra coisa que eu acabei esquecendo: a gente no último vídeo, a gente configurou o Transloco. Eu desfiz as alterações porque eu não acho que faz sentido a gente continuar usando o Transloco aqui no sistema que vai ser provavelmente 100% voltado para o público brasileiro. Mas se o seu SaaS, você sabe que na frente você vai usar tradução, lá na frente já deixa configurado e já começa fazendo a configuração e deixando todos os arquivos com tradução, porque fica mais fácil de fazer. Então eu não acho que faz sentido a gente dar continuidade nisso aqui, mas seria nessa etapa anterior, eu deixaria tudo configurado essa questão de tradução. Beleza? Vamos lá para o Supabase. Então aqui na parte do Supabase a gente Vai criar nossa conta, você vai criar sua própria conta. Eu criei a minha, mas eu não fiz nada nela, tá bom? Então a primeira coisa que a gente vai cair nessa tela, né, é criar a tela da nossa organização. Então eu vou criar aqui a minha organização, vai ser Samuel Ruizon Dev mesmo, pessoal, no plano gratuito. Plano pago é $25 por mês, gente, isso é muito barato. Vocês não tem noção do quanto de diferença que tem. Só para vocês verem a questão de planos. No plano free a gente tem requisições ilimitadas para API, ilimitado. A gente tem até 50 mil usuários ativos. A gente tem 500 MB de database do Postgres. A gente tem 5 GB de tráfego de banda. A gente tem 1 GB de file storage e a gente tem o suporte da comunidade. Então, gente, é muita, muita coisa. Isso aqui nem é tudo. Quando a gente vem aqui para baixo na página de de custos, a gente tem o database, o auth, o storage, real-time. Gente, do real-time a gente tem 2 milhões de mensagens por mês gratuitas. É muita coisa, muita, muita coisa que o Superbase tem para gente, e a gente vai utilizar bastante dessas coisas. Mas criando a minha organização aqui, como eu disse, tá zerada essa conta do Superbase, eu acabei de criar ela. E agora ele tá me pedindo para criar a senha do banco de dados. Eu vou deixar ele mesmo gerar, vou copiar isso aqui e vou salvar em outro lugar aqui. E aqui eu vou selecionar a região, a gente vai colocar aqui América do Sul São Paulo. É só criar um novo projeto. E aí que ele tá setando o projeto, não foi criado ainda, mas eu já tenho a minha API aqui que é pública, que eu posso utilizar no meu front-end, e essa aqui é a privada que eu utilizaria num serviço Apache no meu backend, porque essa aqui ela dá um bypass no raw level security. Então isso aqui é bem importante ficar seguro. E aqui ele me redirecionou sozinho para minha tela inicial do projeto e ele vai me dar algumas coisas aqui que a gente tem. E agora eu vou repassar por vocês por esse dashboard do Supabase para mostrar tudo que a gente tem e algumas coisas legais que a gente consegue fazer aqui. Então a primeira coisa que a gente tem é o table editor. Aqui a gente consegue criar as tabelas do nosso sistema. Eu já consigo vir aqui e mudar o esquema para alfa, por exemplo. Eu tenho também um SQL Editor. Aqui eu consigo criar funções e criar SELECT, INSERT, qualquer coisa de SQL por aqui. E o legal é que a gente tem uma IA do próprio Supabase aqui. Outra coisa que a gente tem é o esquema visualizer, que a gente consegue ver as tabelas do nosso sistema. Deixa eu mudar meu esquema aqui para public. Mas aqui a gente tem as funções e a gente vai ver isso mais para frente. Deixa eu mudar esse carinha aqui para public, que aí a gente vai ver os outros aqui também certinho. A gente tem aqui a parte de backups, migrations e roles e policies. E gente, tem muita, muita coisa aqui. O storage do Supabase, que a gente consegue salvar As Edge Functions vão ser tudo aqui, então ele já me fala como criar uma Edge Function. Real-time também, eu consigo simular as questões e ver o que que tá sendo trafecado aqui no real-time. Aqui eu tenho Security Advisor do Supabase, eu também consigo ver reports da minha API, eu consigo ter log. Gente, isso aqui, isso aqui é uma maravilha, porque eu literalmente tenho um log de tudo que tá acontecendo no meu banco de dados. Literalmente tudo. E isso é maravilhoso, isso é perfeito para quem gosta de trabalhar com o MongoDB. A gente não precisa configurar nada, já tem tudo aqui. Então faça uma requisição para o Scopase e esse log já vai estar aparecendo aqui para gente. Então a gente tem log de tudo: real-time, add function, tudo, vocês imaginaram. E essa parte de API docs aqui que é maravilhosa. Aqui a gente consegue, depois que a gente cria uma tabela no MongoDB, a gente consegue ver a documentação completa de tudo que a gente consegue fazer na tabela. Select, update, insert, tudo a gente vai ter aqui nesse API docs. Da gente ter várias integrações aqui que eles têm, e são integrações práticas, simples e fáceis. Por exemplo, a gente tem cron job, a gente consegue criar cron jobs aqui pelo Supabase. Eu já vou habilitar esse cara aqui porque eu sei que a gente vai utilizar isso para frente em algum momento, mas a gente tem um cron job aqui no Supabase. E a gente tem várias outras coisas que a gente consegue habilitar aqui dentro do nosso sistema. Então vamos olhar qual que é a nossa próxima etapa. A gente já criou a conta e o projeto no Supabase, eu já mostrei as funcionalidades. Então a gente agora vai criar a tabela de usuários, configurar o role level security.
Beleza?
Vamos lá então, como que a gente faz isso? Aqui em SQL Editor o Supabase nos dá esses quick starts aqui. Isso aqui é maravilhoso. A gente tem várias formas de iniciar algo, a gente tem até um exemplo de um Slack clone aqui, mas a gente vai usar esse aqui, ó, User Management Starter. Quando a gente clica, ele já dá pra gente um SQL que faz basicamente o quê? É um SQL normal, ele vai criar a tabela de profiles. Esse role level security a gente tem aqui, a gente consegue ver o que que ele é, é a forma da gente dá mais segurança aos dados que estão salvos na nossa base de dados. Porque como isso fica exposto no front-end, como o Supabase consegue ser chamado pelo front-end, a gente tem que trazer uma segurança a mais dentro das nossas tabelas do banco de dados para que não haja nenhum problema e nenhuma falha de segurança. Então a gente habilita e aí que ele já está criando algumas policies. Então, "Public profiles are viewable by everyone", então todo mundo consegue visualizar os perfis públicos. Aqui somente os usuários podem inserir o próximo, o próprio perfil deles. E aqui os usuários podem atualizar o próprio perfil deles. E aqui o Supabase está criando uma função que basicamente gerencia um novo usuário. E o que que ela faz? Quando o trigger aqui, ó, quando um usuário for criado lá no Supabase Authentication, no esquema de auth, a gente vai rodar essa função E que que ele vai fazer? Ele vai inserir na public profiles o ID, o nome completo e o avatar do usuário.
Muito simples, muito prático e muito fácil.
Basicamente é o que essa função tá fazendo aqui. E por último, ele tá criando um novo bucket chamado avatars e ele também cria uma policy para esse storage aqui.
Show!
Basicamente é isso. E a gente vai fazer algumas alterações aqui nessa tabela de profiles. A primeira delas é que eu não quero chamar profiles, eu quero que seja chamada users mesmo. Então eu vou dar um Ctrl+D aqui igual no VS Code, esse aqui é um editor igual o VS Code. Ctrl+D em profiles e eu quero que seja chamado, eu quero mudar para users. Eu vou pesquisar profile aqui também, dá um Ctrl+D e mudo para user.
Perfeito.
Outra coisa que eu vou alterar vai ser aqui, ó, eu não quero que seja um username, eu quero que seja um email.
Aqui eu posso tirar, acho que não precisa disso.
Websites também eu acho que não precisa na tabela de usuários, mas essa tabela aqui é uma tabela que vai ficar, é nossa tabela pública, mas o Supabase tem a própria tabela dele de usuários. Então essa tabela a gente pode adicionar coisas aqui depois, a gente tem total controle sobre isso aqui. Então a gente tá criando nossa tabela de usuários, ativando o role level security para elas, criando a função para dar o trigger. A gente vai adicionar aqui também email.
New.email para a gente salvar o e-mail do usuário também quando ele for criado.
E eu acho que é isso, pessoal. Vamos rodar esse código. A gente pode rodar apertando aqui ou apertando Ctrl+Enter, ele vai rodar o código. E o que que a gente já tem? A gente já tem a nossa tabela de usuários aqui criada. A gente vem aqui embaixo em definition, a gente consegue ver a tabela que foi criada. A gente consegue adicionar dados por aqui, a gente consegue editar a tabela por aqui também, gente, tudo pelo Supabase, é tudo por aqui. E como eu disse, lembra do API Docs? Aqui no API Docs agora a gente tem tables and views, a gente tem users, e pronto, aqui eu tenho a documentação completa da minha tabela, onde eu consigo filtrar, todos os filtros que o Supabase tem, onde eu consigo inserir Eu tenho a documentação com o Supabase aqui funcionando para mim perfeitamente. Show! Então eu já tenho minha tabela de usuários criada. Vamos dar um check aqui também. A gente já tem um role level security configurado também e a gente vai criar um usuário de teste pelo Supabase. Vamos criar isso para a gente ter um usuário para a gente fazer o login, porque como a gente não vai configurar o cadastro hoje, a gente vai fazer só login, a gente vai ter que ter um usuário de teste. Então a gente vem aqui no próprio Supabase, em Authentication, Add User, Create New User. Então aqui eu vou colocar samuelisondev@gmail.com, a minha senha, Auto-Confirm User sim, Create User.
Prontinho, não quero salvar.
Meu usuário está criado. Quando a gente vier aqui na tabela de users, quem que vai estar aqui? Meu usuário, perfeito. Meu e-mail, eu não tenho nome e avatar ainda porque eu criei ele por lá e lá eu não configuro nada disso, mas aqui eu vou colocar Samuel Bison. O avatar eu não vou deixar aqui. Perfeito, gente, a parte de usuário a gente já tem usuário cadastrado no sistema. Então agora a gente consegue ir para o nosso projeto configurar o Supabase e fazer o login com nosso usuário. Vamos fazer isso. Então aqui no nosso projeto eu vou precisar instalar o supabasejs. Como que eu faço isso? Eu posso vir aqui, supabase install, vou dar um Google aqui só para mim achar a documentação. Eu preciso somente desse código: npm install supabasejs, traço S maiúsculo para salvar. Pronto, tá instalado o Supabase. A gente já tem o supabase.js. Agora, o que que a gente vai fazer aqui no nosso projeto? A gente vai aqui em apps, My Barber Shop, src, app, shared, services, e a gente vai criar aqui uma nova pasta chamada supabase. E aqui eu vou criar um novo serviço, schematic/service, vai chamar supabase.
Generate.
Beleza, eu tenho meu service aqui gerado. Eu vou criar uma variável chamada Supabase, SupabaseClient, esse carinha aqui que eu vou utilizar. E aqui no construtor eu vou chamar esse cara, this.supabase, e aqui eu vou passar a minha URL e a minha key. Só que para isso eu preciso salvar essa URL, essa key, em algum lugar aqui do meu projeto de Angular. E nos novos projetos Angular a gente precisa adicionar os environments aqui manualmente, porque eles tiraram isso na v15. Então a gente vem aqui, Angular Edge Environments, e a gente acha o schematics que a gente precisa rodar. Esse carinha aqui, ó, ng generate environments. Se eu rodar o ng, ele não vai funcionar porque a gente tá no projeto NX. Então eu dou um NX generate environments. Ele deu um erro porque a gente precisa passar o projeto, então não vamos esquecer disso.
project --project=mybatterieshop.
Beleza, já gerou meu environment aqui. E aqui a gente vai precisar de duas coisas: supabase-url e supabase-key. Nada mais que isso. E agora, voltando aqui no nosso Supabase, Eu preciso da minha key, do meu project URL, esse carinha aqui, cola, e da minha key. Eu vou copiar isso aqui e colocar no development também e pronto. Agora eu já consigo chamar aqui environment, environment.supabase_url.
Environment, super basic.
A gente vai alterar aqui no nosso tsconfig, a gente vai adicionar um @environment também, @env.
Perfeito! Copilot é maravilhoso, gente, vocês deveriam usar Copilot.
Aqui vai ser só o environment mesmo.
Perfeito!
E aí o que eu gosto de fazer também, eu gosto de criar um folder functions.
Eu vou criar um supabase inject supabase function.ts. Export const inject supabase.
Eu vou dar aqui um const supabaseService é @Inject angular-supabase-service return supabase.
Perfeito!
Isso aqui é só pra gente ter uma instância do supabase pra gente não precisar ficar chamando esse service aqui toda hora. E beleza, nosso supabase já tá funcionando. Então agora vamos codar a nossa página de login com o nosso formulário. E a primeira coisa que a gente vai fazer é vir aqui no ng-zorro e a gente vai copiar o código de um formulário do ng-resolve.
Então a gente copia esse código aqui, a gente vai colar ele aqui, aqui a gente pode tirar, a gente vai importar esse nz-form-module, importa ele aqui, nz-input-module também que a gente vai precisar. Vamos tirar esse span aqui que a gente não precisa dele, esses carinhas aqui. No nosso formulário layout vertical. Perfeito. Aqui a gente vai tirar esse nome, a gente vai tirar esse ID, a gente vai importar o reactive forms module e a gente vai colocar aqui um form control name email e vai ser a mesma coisa para senha password. Agora a gente vai criar o nosso login form, form group, constructor Aqui a gente vai instanciar nosso FormGroup. ValidatorRequired. Perfeito. Importamos tudo aqui. Esse carinha vai se chamar login e a gente vai criar um método chamado login aqui, console.log login form. Beleza. Aqui a gente chama de login. E agora quando a gente volta no nosso sistema, deu um erro por causa do FormControl. Deixa eu dar uma olhadinha aqui. Ah, porque a gente não importou o FormControl aqui. Então FormGroup, LoginForm. Perfeito, show! Já tá funcionando aqui. Deixa eu só deixar esse botão aqui nz-block. Esse nz-block vai deixar o botão inteiro aqui na tela. Perfeito. Se eu digito aqui 123@gmail.com, 123, que já pega o valor do meu formulário.
E gente, agora vamos fazer esse login aqui no Supabase. Como que faz o login no Supabase?
private Supabase inject Supabase, e aqui eu vou pegar os meus valores do formulário. Se não for válido, eu vou dar aqui um private NotificationService, inject do Angular, NzNotificationService, só pra gente mostrar uma mensagem pro usuário. E aqui eu dou um return e dou um this.notificationService. Perfeito. E agora eu pego os campos de email e password e eu dou um await. Deixa eu mudar esse método aqui para async, tira esse void daqui. await this.superbase.auth.signinWithPassword email e password. Gente, dessa forma aqui o meu usuário já vai estar logado no Superbase. E aí depois disso, private route router, a gente vai redirecionar ele para a tela inicial.
E aí aqui eu só quero criar essa tela inicial para gente.
Na verdade, acho que a gente já tem, né? Ele só vai sair da tela de login. Mas vamos fazer um teste aqui. Aqui eu vou dar um const erro para a gente ver se a gente recebeu algum erro. If, vamos ver como é que vai acontecer aqui agora. Show! Vou dar aqui 123@gmail.com, 123, login, erro. Invalid login credentials. Então aqui a gente já recebeu um erro, a gente pode arrumar isso aqui para a gente colocar uma mensagem melhor. Erro ao fazer login, verifique suas credenciais e tente novamente. Gente, o Copilot é excelente para esse tipo de texto, show! E agora vamos ver se a gente consegue colocar samuelrizondev@gmail.com. Show!
Login.
Pronto, funcionou. Viram que eu fui redirecionado para a tela? O meu usuário aqui, ele já tá logado. Se eu vier aqui em application, no localStorage, a gente já vê aqui que a gente tem um access token, a gente já tem os dados principais dos usuários aqui no Supabase.
E autenticação nos Firebase é isso. Fez o login dessa forma, agora já tem usuário dentro do meu sistema. Eu preciso só salvar ele aqui para fazer tudo funcionar. Então vamos lá no nosso sistema agora de novo, que a gente precisa criar agora um auth service, esse carinha aqui, ó. Então o que que a gente vai fazer com esse carinha?
A gente vai criar um current user e ele vai ser um Signal de um IUser. Lembra que a gente criou essa interface lá atrás? A gente vai ter um User, beleza, nome, email, status. A gente precisa lá no Supabase ver quais informações que a gente tem no nosso usuário, na nossa tabela de usuário, users. Eu venho aqui, vem na definition, mas a gente tem um ID, email, fullname e avatar. Então ID, email, fullname, password a gente não precisa salvar aqui porque isso fica lá na tabela de autenticação do próprio Supabase. Então a gente tem aqui ID, fullname, email, avatar. Isso mesmo, isso mesmo, beleza. E esse carinha aqui vai ser do tipo Signal, então SignalUser. Isso aqui tá ótimo. Então a gente vai ter o usuário atual. Então agora eu vou criar uma função chamada load.
Essa função vai ser iniciada quando a gente começar, quando a gente, aplicação iniciar, e E o objetivo dela vai ser carregar a sessão do Supabase.
Então getSession, show, na verdade aqui é um data. E aí aqui eu verifico se data.session, deixa eu dar um await aqui, tem que ter o await, await async, se data.session Se não tiver data.session, eu tenho que deslogar o usuário. Então, para me deslogar o usuário, eu vou dar aqui uma async purgeAuth, purgeAndRedirect. Perfeito, perfeito. Aqui eu vou private hold, perfeito. Então aqui, se não tiver, eu vou dar um await, await, por exemplo, redirect. Mas se eu tiver, eu vou dar um currentUser. Aqui não é essa forma de utilizar o signo, aqui vai ser um user ou null. E agora sim eu consigo dar um set aqui. Perfeito. data.session.user. Show! Aqui ele vai falar que o tipo de user não é o do IUser, então aqui eu vou dar um as, a new AsUser, porque o tipo desse carinha aqui não é o mesmo desse meu carinho, mas eu tô Forçando ali. Agora vou dar um console.log user logado. O Copilot ainda não sabe como é que funciona o Signal direito, então ele sempre fica dando esses valores diferentes aqui no sistema. Mas beleza, isso aqui tá funcionando.
Agora a gente precisa adicionar esse carinha aqui na nossa aplicação inicial.
Então provide AppInitializer a gente vai rodar o auth_service.load e agora quando eu venho aqui para esse carinha, eu carrego aqui, entro aqui, olha que maravilha, gente, o meu usuário já está carregado aqui dentro do sistema. Então quando eu carrego a minha página, a primeira coisa que ele faz é dar um user loaded aqui E a gente sabe que o nosso usuário já tá logado e já tá funcionando.
Que que a gente vai fazer agora? A gente vai fazer uma guarda de rota para a gente saber se eu entrar na página de autenticação, eu não quero continuar nessa página de autenticação se o meu usuário já estiver logado.
Então, para isso, no Angular é muito simples, e eu vou criar next generate Schematics, guard. E eu vou criar isLoggedIn, se o usuário está logado. Eu não quero o flat, eu vou dar um generate aqui. E aí eu preciso nesse auth service, se o meu usuário tiver logado, eu quero criar isLoggedIn, esse carinha aqui. Então, se ele estiver logado, eu quero dar um isLoggedIn set to true. E basicamente o que eu preciso fazer é: se o cara tiver logado, se ele não tiver logado, eu já dou um redirect. Senão, ele está logado. Perfeito. Vamos ver se isso aqui vai funcionar. A gente vai pegar esse carinha e colocar nas nossas rotas de guarda, app routes, nesse carinha aqui. A gente vai usar o CanActivate e isLoginGuard. Beleza, vamos ver se esse negócio tá funcionando mesmo. Vamos lá no nosso app, a gente vai entrar aqui e não funcionou. IsLoginGuard. Ele tá chamando aqui, ele tá verificando se tá logado. Aqui na verdade é o que eu quero saber, se o cara estiver logado eu preciso redirecionar ele para tela inicial. Então aqui eu dou um route.navigate, dou um const router injectRouter E aqui eu dou um router.navigate, se ele estiver logado. Se ele não estiver logado, ele tá na tela certa, porque aqui eu só quero verificar a minha página de autenticação.
Então aqui, ó, já foi.
Se eu tentar acessar minha página de autenticação, ele não deixa, ele já redireciona para cá, porque meu usuário tá logado, retorno como false. E aqui eu retorno como true. Então nossas rotas de autenticação já estão salvas dessa parte do usuário, caso o usuário já esteja logado. Para a gente deslogar, eu vou limpar o localStorage aqui e vou tentar acessar aqui novamente, e aqui ele já deixa, tá bom? Então já estamos aqui na página de novo.
Agora o próximo passo é a gente criar a parte de esqueci minha senha. Vamos fazer essa parte então.
A gente vai vir aqui em Pages, gerar uma nova página, Schematics, Component, Forgot Password. Eu vou dar um CSS aqui, vai ser uma page, e eu vou gerar esse carinha aqui. Na nossa página de login, a gente vai adicionar aqui nesse carinha dentro do form-item, um a, de esqueci minha senha. Exatamente isso aqui. Não quero esse cara aqui, não quero esse cara aqui. Meu Deus, Copilot, arruma cada coisa, cada confusão. Router, módulo, aqui eu não quero o clique, meu amigo, é só dar um router aqui, ó, router link, ao forgot password. E não é inglês. Esqueceu sua senha. Eu vou salvar, eu vou voltar lá para nossa aplicação. E aqui, ó, já tá o esqueceu sua senha. E agora a gente precisa criar a rota desse carinha, path /forgot_password, forgot_password_page. Funcionou perfeitamente. Então quando eu clicar aqui ele já manda para o meu 4Code PasswordWorks. Eu vou copiar tudo que tá aqui, vou colar. Eu vou precisar somente do meu e-mail, então esse cara aqui eu não preciso. Esse cara aqui vai se chamar enviar e-mail, aqui eu vou mudar para submit. Aqui eu vou criar um outro botão, nz-button-voltar, perfeito. O type vai ser um text. Aqui eu vou importar os meus carinhas que eu preciso para fazer isso funcionar. Preciso de um botão, flex-module não preciso, form-module, input-module preciso, react-forms-module. E routerModule. Eu preciso importar esses caras aqui. Perfeito. E aqui eu vou dar um inject private Supabase, recebe inject Supabase. Aqui eu acho que eu prefiro criar só um new FormControl. Vamos usar um Signal aqui mesmo, acho que é só o email que eu preciso. Então eu não vou usar form-control não, vou pegar esse carinha aqui, ng-model email. Eita, jogo! ng-model email, em vez do react vai ser o form-model. Perfeito, vamos ver, submit email, console .log dis.email. Vamos ver se isso aqui tá funcionando. Esqueci minha senha. Teste. Ele tá falando aqui: Gmod use form tag. Vamos ver como é que a gente usa o Signal nesse caso.
Tudo de Signal é novo, tanto não só para mim, mas para vocês, e a gente vai descobrir essas partes juntos.
Então, Angular signals. A gente vai na documentação e eu quero saber o ângulo input signals. Esse carinha aqui, ó, input number. Será que esse cara aqui mesmo? Preciso saber do HTML. Angular Signals, GModel. Beleza, ele chama model. Então é diferente, tá vendo? Não é um signo normal, ele chama model. Model Angular Core nesse carinha. Beleza, vamos ver agora se funcionou. Esqueceu sua senha. ng-model, a gente tem que colocar o nome. Então aqui, name, email. Aqui ele deu uma coisa muito maluca, mas eu preciso acessar o valor dessa forma porque é um signon, né? Aí tá difícil. Show! Então vamos lá, signon aqui, vamos aprender signon juntos. Mas basicamente no Super Base a gente vai fazer isso aqui, o async await Supabase password reset password for email, this.email. Dessa forma aqui eu vou importar NotificationService, serve inject, ng-notification-service, e o inject também eu vou importar. This notification email enviado, verifique sua caixa de entrada. Desse ponto email recebe, não é assim, é um set, uma string vazia. Show disabled se esse email, se a gente não tiver email. Então beleza, o forgot password está desabilitado. Eu vou dar um samuelrizondev@gmail.com. Só que antes de enviar esse e-mail para o Supabase, a gente precisa fazer uma configuração aqui no nosso Supabase.
Que configuração que é essa?
A gente vem aqui em Authentication e a gente vai vir aqui em Mails.
E cara, o Supabase já tem esses e-mails prontos que a gente consegue configurar o HTML deles. O email que a gente vai usar é esse carinha aqui, ó, reset password, e ele vai enviar exatamente esse email, só que eu quero que ele envie para esse reset password aqui.
Então ele vai dar um confirmation URL reset password para a gente redirecionar o usuário para essa tela.
E para isso a gente vai ter que criar também uma tela de reset password. Só que essa tela ela não vai ficar aqui dentro do módulo de autenticação, porque dentro desse módulo a ideia é que isso aqui seja para parte do usuário que está fora do sistema.
Eu costumo criar essa tela aqui em core, então eu vou criar uma pasta pages e eu vou criar uma nova página, schematic component, chamado reset_password. Eu vou dar um sss aqui. Vai ser uma page e eu vou clicar em Generate. Essa tela ela vai ficar aqui em uma das minhas rotas principais e eu vou chamar um path aqui reset_password. Não vai ser no domain, /core/pages/reset_password_page. Perfeito. A gente vai pegar a mesma ideia do nosso login. A gente vai colar esse carinha aqui, só que não é o email mais, agora é a nossa senha. E uma coisa vocês vão ver que vai ficar desconfigurado porque eu não vou estar usando essa parte do AlfLayout, mas a gente resolve isso tranquilamente. Então eu vou vir aqui em— deixa eu pegar o do Forgot Password, que eu acho que é o mesmo dele. Então eu pego isso aqui, importo todos esses caras aqui, vou pegar esse carinha edual_missing_ports, password, password. E aí aqui no supabase a gente vai dar um this.auth.update_user Password sem alterada, sua senha foi alterada com sucesso.
E agora private router recebe object router, a gente vai redirecionar o usuário para tela inicial, porque quando o usuário clica no e-mail do Superbase, ele é direcionado para o nosso sistema já logado.
Então o Superbase já loga ele no sistema e ele consegue atualizar as informações dele de uma forma bem simples. Então a gente tem aqui a nossa tela, aqui vai ser um submit e atualizar, atualizar senha, nova senha. Deixa eu ver aqui só uma coisinha que eu acho que e-mail senha. Perfeito. Bom, vamos ver como que tá funcionando agora. A gente já atualizou esse cara para ele redirecionar para o reset password. Na minha URL configuration aqui, eu preciso colocar a minha URL localhost:4244.
Save.
Beleza, então agora espero que a gente já tenha essa parte de esquecer minha senha funcionando. Vou vir aqui, vou fechar, enviar e-mail. Ele mandou e-mail enviado com sucesso, verifique sua caixa de entrada. Se eu entrar no meu Gmail agora, gmail.com Demorou um tempinho, mas chegou, ó, chegou 2 ainda. Beleza, então funcionou. Vamos clicar aqui no segundo, dá um reset password. Cliquei, ele me direcionou para cá. Vamos ver aqui se eu clicar nesse, também não funcionou. E vamos mandar de novo, enviar email. Beleza, enviou o e-mail. Aqui eu vou ter que esperar um pouquinho, não sei o que que ele tá reclamando aqui. Ah, tá explicado aqui, ele deu um load shield ao invés de um load component. Beleza, corrigido. Agora a gente pode vir aqui no nosso sistema. Se eu tentar achar, acessar o reset password NG Control, no Provider for NG Control, não tem problema. Tá dando esse carinha aqui, por quê? Porque eu não fiz igual o outro. Pronto, agora tá funcionando. Isso é a vida de um dev. Reset password, perfeito. Como eu falei, tá bugado aqui a parte do off layout. Mas isso aqui não é um problema pra gente porque a gente pode fazer esse carinha aqui, ó, porque o nosso is_login tá dentro aqui, então todos esses children aqui vão usar ele. Mas eu posso colocar o meu reset_password aqui dentro, posso colocar reset_password aqui dentro, e o meu canActivate eu vou colocar dentro das minhas rotas aqui. Então essas rotas aqui precisam estar guardadas por esse carinha. E aí aqui ele vai chamar agora /auth/resetpassword. Então eu preciso vir cá no Superbase, alterar ele para /auth/resetpassword. Beleza, save. Aqui na minha aplicação, auth/reset_password. Beleza, minha barbearia, nova senha, e aqui eu consigo alterar minha senha. Mas a gente precisa chegar nessa parte aqui pelo Supabase, então eu vou vir aqui, /auth, Meu usuário tá logado porque eu acessei pelo Superbase aquela hora, então vou carregar aqui de novo. Esqueceu sua senha?
Enviar e-mail.
Carregando. Beleza, a gente vem aqui no Superbase. Já tô por aqui, vem no meu e-mail. Recebi meu e-mail de esqueci minha senha, esse e-mail aqui. Cliquei, olha que maravilha, alf/resetpassword. Eu vou colocar 456789. Deixa eu abrir o console.log aqui, atualizar a senha. Senha alterada com sucesso. E agora se eu tentar logar aqui de novo com meu usuário samuelrizondev@gmail.com, 123456, login, erro. 456789, login, funcionou. Ufa, tá funcionando, pessoal! Parte de login, de autenticação, nossa, já tá linda, maravilhosa, funcionando com esqueci minha senha.
Uma outra coisa que eu quero deixar de detalhe aqui para vocês é quando a gente clicar aqui, eu quero desabilitar o botão e dar um loading.
Então é para isso que eu tenho loadService na minha aplicação. Quando eu venho aqui em forgotPassword, eu vou importar, eu vou dar um protected loadingService inject loadingService. Aqui eu vou dar um this.loadingService.start e aqui eu dou um stop. E olha, gente, ng-zorro é uma maravilha. O botão, ele tem um ngLoading onde eu passo loadingService.load e acabou, meus amigos.
Quem é material perto de ng-zorro? Olha isso aqui agora, meus amigos. Cliquei.
Maravilha!
Eu não consigo mais clicar no botão.
O e-mail foi enviado e tá tudo funcionando. Ufa!
A gente viu um monte de coisa. Eu não sei nem quanto tempo vai durar esse vídeo, mas eu espero que vocês tenham conseguido entender o poder do Supabase, o quão é fácil fazer tudo isso aqui. Algumas coisas eu deixei vocês verem o meu processo, né, de procurar, de encontrar as coisas, para não deixar tudo prontinho aqui para vocês. Mas a vida de um desenvolvedor é isso. A gente achar erro, a gente pesquisar, entender como é que funciona, principalmente essa parte de signals. A gente vai aprender bastante coisa nesse projeto. Então, cara, eu duvido vocês acharem um tipo de conteúdo tão completo como esse na internet hoje sobre Angular, Supabase, e você não acha isso nem em curso pago. Então deixa o seu like, se inscreve no canal, ativa o sininho e compartilha esse vídeo com a galera para chegar no máximo de gente possível. E não se esquece de entrar na comunidade do nosso canal, o link tá aqui no WhatsApp, mas se você quiser eu vou deixar também um QR code aqui do meu lado para você acessar. Então lê esse QR code, entra lá na comunidade para a gente bater um papo sobre tudo isso que eu fiz aqui, tudo isso que a gente está conversando e que a gente está construindo tudo junto aqui no nosso canal. Muito obrigado pelo vídeo, até a próxima, valeu!










