import { Injectable } from '@angular/core'; import { CognitoAccessToken, CognitoIdToken, CognitoRefreshToken, CognitoUserSession } from 'amazon-cognito-identity-js'; import { parse, startOfDay } from 'date-fns'; import { delegate } from 'utils-decorators'; import { Application } from '../application/application'; import { UsuarioData } from '../data/usuario.data'; import { Cliente } from '../types/cliente'; import { CacheContainer } from '../utils/cache-container'; import { TipoPessoa } from '../utils/Constantes'; import { InternalStorage } from '../utils/storage.util'; import { CognitoService } from './cognito.service'; enum StorageKeys { ID_TOKEN = 'ID_TOKEN', ACCESS_TOKEN = 'ACCESS_TOKEN', REFRESH_TOKEN = 'REFRESH_TOKEN', USERNAME = 'USERNAME' } // TODO: Ao fazer o login e ao dar refresh no token, limpar o cache container. const authCache: CacheContainer = new CacheContainer(); @Injectable({ providedIn: 'root' }) export class AuthService { #storage: InternalStorage = new InternalStorage({ name: Application.STORAGE_NAME, storeName: Application.USER_STORAGE_NAME }); constructor( private cognitoService: CognitoService ) { } public async getUsuario() { const session = await this.getCognitoSession(); const { payload } = session?.getIdToken() ?? { payload: null }; if (!payload) return null; const email = payload.email; const nome = payload.name; const cpf = payload['cognito:username']; const cpfCnpj = payload['cognito:username']; const dataNascimento = startOfDay(parse(payload.birthdate, 'yyyy-MM-dd', new Date())); const tipoPessoa: TipoPessoa = payload['custom:tipoPessoa'] as TipoPessoa; const celular = payload.phone_number; return new UsuarioData({ cpfCnpj: tipoPessoa === TipoPessoa.PF ? cpf : cpfCnpj, email, nome, tipoPessoa, dataNascimento, celular }); } @delegate() public async signUp(cliente: Cliente) { return this.cognitoService.signup(cliente); } @delegate() public async confirmPassword(email: string, code: string, password: string) { return this.cognitoService.confirmPassword(email, code, password); } @delegate() public async verifyCode(email: string, code: string) { return this.cognitoService.verify(email, code); } @delegate() public async passwordRecover(email: string) { // TODO: Validar email // if() await this.cognitoService.forgotPassword(email); return true; } @delegate() public async login(email: string, password: string) { try { const result = await this.cognitoService.sigin(email, password); await this.#storage.set(StorageKeys.ID_TOKEN, result.idToken); await this.#storage.set(StorageKeys.ACCESS_TOKEN, result.accessToken); await this.#storage.set(StorageKeys.REFRESH_TOKEN, result.refreshToken); await this.#storage.set(StorageKeys.USERNAME, email); return result; } catch (err) { console.error(err); throw err; } } @delegate() public async resendConfirmationCode(email: string) { return this.cognitoService.resendVerificationCode(email); } @delegate() public async logout() { return await this.#storage.clear(); } @delegate() public async isLoggedIn() { const idToken = await this.#storage.get(StorageKeys.ID_TOKEN); return !!idToken; } @delegate() public async getToken(): Promise { return this.#storage.get(StorageKeys.ID_TOKEN); } @delegate() public async refreshToken() { const refreshToken = await this.#storage.get(StorageKeys.REFRESH_TOKEN); const result = await this.cognitoService.refreshToken(refreshToken); if (result.accessToken) await this.#storage.set(StorageKeys.ACCESS_TOKEN, result.accessToken); if (result.idToken) await this.#storage.set(StorageKeys.ID_TOKEN, result.idToken); if (result.refreshToken) await this.#storage.set(StorageKeys.REFRESH_TOKEN, result.refreshToken); } @delegate() public async getCognitoSession(): Promise { const AccessToken = await this.#storage.get(StorageKeys.ACCESS_TOKEN); const IdToken = await this.#storage.get(StorageKeys.ID_TOKEN); const RefreshToken = await this.#storage.get(StorageKeys.REFRESH_TOKEN); if (!AccessToken || !IdToken || !RefreshToken) return null; return new CognitoUserSession({ AccessToken: new CognitoAccessToken({ AccessToken }), IdToken: new CognitoIdToken({ IdToken }), RefreshToken: new CognitoRefreshToken({ RefreshToken }) }); } }