diff --git a/.gitignore b/.gitignore index 15c7b211..86c775f8 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,6 @@ Thumbs.db /src/app/environment /src/app/secret /src/app/app.constant.ts +certificate.cnf +localhost.crt +localhost.key diff --git a/certificate.cnf b/certificate.cnf new file mode 100644 index 00000000..1986482b --- /dev/null +++ b/certificate.cnf @@ -0,0 +1,21 @@ +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +x509_extensions = v3_req +distinguished_name = dn + +[dn] +C = IN +ST = India +L = India +O = My Organisation +OU = My Organisational Unit +emailAddress = email@domain.com +CN = localhost + +[v3_req] +subjectAltName = @alt_names + +[alt_names] +DNS.1 = localhost \ No newline at end of file diff --git a/localhost.crt b/localhost.crt new file mode 100644 index 00000000..75cfdd4d --- /dev/null +++ b/localhost.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEATCCAumgAwIBAgIUAgGacEDYDmbF0fkO7yGM9N1I+60wDQYJKoZIhvcNAQEL +BQAwgZ0xCzAJBgNVBAYTAklOMQ4wDAYDVQQIDAVJbmRpYTEOMAwGA1UEBwwFSW5k +aWExGDAWBgNVBAoMD015IE9yZ2FuaXNhdGlvbjEfMB0GA1UECwwWTXkgT3JnYW5p +c2F0aW9uYWwgVW5pdDEfMB0GCSqGSIb3DQEJARYQZW1haWxAZG9tYWluLmNvbTES +MBAGA1UEAwwJbG9jYWxob3N0MB4XDTIzMTIwMTEzNTAxMFoXDTMzMDgzMDEzNTAx +MFowgZ0xCzAJBgNVBAYTAklOMQ4wDAYDVQQIDAVJbmRpYTEOMAwGA1UEBwwFSW5k +aWExGDAWBgNVBAoMD015IE9yZ2FuaXNhdGlvbjEfMB0GA1UECwwWTXkgT3JnYW5p +c2F0aW9uYWwgVW5pdDEfMB0GCSqGSIb3DQEJARYQZW1haWxAZG9tYWluLmNvbTES +MBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9UhfQgCZGNUwosWjdXmf84oJA3njHWBm8t2Z3SNr6R58FqHPzvJOWJUsq0ze +98MrT1aFPiAvVush6Igxxl+Ky/mn+TdTPRYZO4rUXrUPi97nCqKFh4igwnduEpgI +UdoZ1PEmUxU4W47mOdi78wyMIOk5hiNkn2zmYW0jlPdfUlg8kL+6loWyvgdmQElf +J2Fv5IneEFZIl9E6svck7kJXt6xzn+7opuVwNPOS9S9rvMdJpWquPcbUtkTlFPch +qYF+h5DT+IWZ/Wt8CCpS55Ec26+GEOXHQLfkmnZvCn0cpptwLwsYqxY/5IvCDuMo +c03xSbNRxMctxKBSZ4YW89DsiQIDAQABozcwNTAUBgNVHREEDTALgglsb2NhbGhv +c3QwHQYDVR0OBBYEFLeeY5dZnBSSytrxuTkTuIdcGLlRMA0GCSqGSIb3DQEBCwUA +A4IBAQBYnbG3s3LLEo0rfu409OnmEE6nlV9+Q2OPRGwoAY/GFInN9dkYZ5hChuft +Mg1y0HAdwYtbzMlB71ccKpfdeLwOQYhviv3C2PB9GR8RcRmfpfRx/mdcN39WOlPu +l7beJnoNfdNQn0H2+eurD5bYdxFVAzyFpob6dyiZXRU1gWsW0XsCF1du2aWD6qtq +jgq8fDpApglj8jXR26cIHjxPjwAZcfk3/HiBMqJKh5E/6PsyafuNFPeWwYMr4p0o +DaWIgQ8r5IC+CgRZLj2aY2QW/zM74ZiNUpUZyF+nYRtjyjOwU/oZmbXKpJ9qAbne +YvaHT8bZfS3OMThcRFejeWBt6Ad0 +-----END CERTIFICATE----- diff --git a/localhost.key b/localhost.key new file mode 100644 index 00000000..596a0d2c --- /dev/null +++ b/localhost.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD1SF9CAJkY1TCi +xaN1eZ/zigkDeeMdYGby3ZndI2vpHnwWoc/O8k5YlSyrTN73wytPVoU+IC9W6yHo +iDHGX4rL+af5N1M9Fhk7itRetQ+L3ucKooWHiKDCd24SmAhR2hnU8SZTFThbjuY5 +2LvzDIwg6TmGI2SfbOZhbSOU919SWDyQv7qWhbK+B2ZASV8nYW/kid4QVkiX0Tqy +9yTuQle3rHOf7uim5XA085L1L2u8x0mlaq49xtS2ROUU9yGpgX6HkNP4hZn9a3wI +KlLnkRzbr4YQ5cdAt+Sadm8KfRymm3AvCxirFj/ki8IO4yhzTfFJs1HExy3EoFJn +hhbz0OyJAgMBAAECggEAB6GHXHy7cUdBWAW5PWXPM7WNwhGCyZlEHVZcG6y8W3ho +PhBYMFUfr11VZ69Ao5QrRDC0p1dl1E4vPqECwsFvsRi0tgns2XJseWAAa0GLo4Yd +NC/qDWqogmGn/MTv7f37U5bnYpUp151f7Rj2AKHZYopm+1TyuTawidjqTw+NeWNi +R94X5BswWJekKl2K4TRjekYERooRfepuWMqVKQ40+LLdyl0d3mJ+KKC6C3ZtyuuS +KsiYx1vcf3RQoQIX6ySIBxNXpyivgtgO2XVouumMceM2yT8NOmaEaG3lztek1+LM +A+37YeqjVoY6APz+VsZWM2+Z9AoE309A7nNccb4Z9QKBgQD9RUyXrBlFpOUGLpVW +Lahp8nlzTrrpwcMwP4OJ1rHnjMXbIfKS3jSSkXrilam6vsNGxxWOOkBk6W3ePidb +LloVXqNXB6sbWqNTBhuDmAgAlyHntQzStG62EXLyBEvTj7sjZpAFkUJTJ6l6EerU +x/sKv1jIYnnFdB29SvF+YRiAlQKBgQD37QlNI/s4wgqPcfKoO/j+E/G7rl0vOy3+ +U+dgFXpQ2l2tYQERDUXVY5PO+Yq+j5WoG+/10l960erH77eatz08fXRJWOXLW50k +pJG4k2/0RoVvgpd4WMw0GQqSzz8a1r2onCjWaCmLI4oa+FB1Q4zJCs1fULT7alk5 +GulW0hQ7JQKBgQCAGhkPbiCqNSkR42XtXNKeI+KCDARGT5bmRHnHsivxriY1HAqR +doqox6ScDo72wZ4Loo6ojZYcdGT5z/4gBGXUATYkwuAsyb9qMuCfwrnpcofXpp+B +w3lr5Y96Eeo4a65/zVRzPHGLlbgG4iEg1rWHThkd4ZEt6flQ0SMshPfbsQKBgQDm ++W4w79ScjCpKeV4YXcca7nnG4CrwVbIDvydP3LKXoNilLjpQKI1mv950dQdNgXdr +pptn6RYK1oZkvm/PM+dY84fizW9IhZFhEfCwhKtIaGrn+EIlXJTh9HJlU6720hjf +fJyPI3uQpQuFFNHgbY47vlSW+BmkIO/+w5OfzxgKAQKBgEvszMU5vpUErl+SRv9q +Wkc2p3iI87koATF5W7+3uuTByHJl2TAZYd6xupmdEKedOfoFvIoJOtKMjgnPoIOF +0gFmmms3uAnpPhgmvdcRPP6yyPSuC60/XjAanDYUCrYbYtDvQCcuK2HIJL3zC2pv +4NwRSFqWLcytWvbMB6bWywkq +-----END PRIVATE KEY----- diff --git a/package-lock.json b/package-lock.json index 21edd442..566d2b68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "unb-tv-frontend", "version": "0.0.0", "dependencies": { + "@abacritt/angularx-social-login": "^2.0.0", "@angular/animations": "^15.2.0", "@angular/cdk": "^15.2.9", "@angular/common": "^15.2.0", @@ -18,6 +19,7 @@ "@angular/platform-browser": "^15.2.0", "@angular/platform-browser-dynamic": "^15.2.0", "@angular/router": "^15.2.0", + "@types/gapi.auth2": "^0.0.60", "angular-oauth2-oidc": "^15.0.1", "hls.js": "^1.4.12", "jwt-decode": "^3.1.2", @@ -49,6 +51,18 @@ "typescript": "~4.9.4" } }, + "node_modules/@abacritt/angularx-social-login": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@abacritt/angularx-social-login/-/angularx-social-login-2.0.0.tgz", + "integrity": "sha512-SgbkgOTlcbaOmGDL6eCMIXct4+nFpzWjYqUfN7gqyBdb7D/rlo0hDd0hntMqoK5Tc3AA1z2ZAg+fZlSaBuRvEg==", + "dependencies": { + "tslib": ">=2.5.0" + }, + "peerDependencies": { + "@angular/common": ">=15.0.0", + "@angular/core": ">=15.0.0" + } + }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -5260,6 +5274,19 @@ "@types/send": "*" } }, + "node_modules/@types/gapi": { + "version": "0.0.47", + "resolved": "https://registry.npmjs.org/@types/gapi/-/gapi-0.0.47.tgz", + "integrity": "sha512-/ZsLuq6BffMgbKMtZyDZ8vwQvTyKhKQ1G2K6VyWCgtHHhfSSXbk4+4JwImZiTjWNXfI2q1ZStAwFFHSkNoTkHA==" + }, + "node_modules/@types/gapi.auth2": { + "version": "0.0.60", + "resolved": "https://registry.npmjs.org/@types/gapi.auth2/-/gapi.auth2-0.0.60.tgz", + "integrity": "sha512-KQiyTHRyAcat6marTRAixrkHhkS7mqclcbQvInfxyp7IeUDSUzLBlgH1s0SFaLl1m1jRY6b+qh4NMlmVm0wPEw==", + "dependencies": { + "@types/gapi": "*" + } + }, "node_modules/@types/http-errors": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", diff --git a/package.json b/package.json index 2fe0aef2..0e6b2fef 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "private": true, "dependencies": { + "@abacritt/angularx-social-login": "^2.0.0", "@angular/animations": "^15.2.0", "@angular/cdk": "^15.2.9", "@angular/common": "^15.2.0", @@ -23,6 +24,7 @@ "@angular/platform-browser": "^15.2.0", "@angular/platform-browser-dynamic": "^15.2.0", "@angular/router": "^15.2.0", + "@types/gapi.auth2": "^0.0.60", "angular-oauth2-oidc": "^15.0.1", "hls.js": "^1.4.12", "jwt-decode": "^3.1.2", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4dd1beb2..abd3921e 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -11,6 +11,9 @@ import { OAuthModule, OAuthStorage } from 'angular-oauth2-oidc'; import { InputTextModule } from 'primeng/inputtext'; import { DropdownModule } from 'primeng/dropdown'; import { ButtonModule } from 'primeng/button'; +import { SocialLoginModule, SocialAuthServiceConfig } from '@abacritt/angularx-social-login'; +import { GoogleLoginProvider, FacebookLoginProvider } from '@abacritt/angularx-social-login'; + // Declaration import { NgModule } from '@angular/core'; @@ -58,6 +61,7 @@ import { NgxGoogleAnalyticsModule, NgxGoogleAnalyticsRouterModule } from 'ngx-go FormsModule, BrowserAnimationsModule, MatPaginatorModule, + SocialLoginModule, NgxGoogleAnalyticsModule.forRoot('G-XL7Z0L7VM8'), NgxGoogleAnalyticsRouterModule ], @@ -94,7 +98,28 @@ import { NgxGoogleAnalyticsModule, NgxGoogleAnalyticsRouterModule } from 'ngx-go }, { provide: OAuthStorage, useValue: localStorage }, MessageService, - ConfirmationService + ConfirmationService, + { + provide: 'SocialAuthServiceConfig', + useValue: { + autoLogin: false, + providers: [ + { + id: GoogleLoginProvider.PROVIDER_ID, + provider: new GoogleLoginProvider( + '254484469180-1imr4ds36p8rq4fe7udkja212tu0p7jl.apps.googleusercontent.com' + ) + }, + { + id: FacebookLoginProvider.PROVIDER_ID, + provider: new FacebookLoginProvider('2640880742734858') + } + ], + onError: (err) => { + console.error(err); + } + } as SocialAuthServiceConfig, + } ], bootstrap: [AppComponent], }) diff --git a/src/app/guard/auth.guard.spec.ts b/src/app/guard/auth.guard.spec.ts index b09a90ef..890a6d8f 100644 --- a/src/app/guard/auth.guard.spec.ts +++ b/src/app/guard/auth.guard.spec.ts @@ -3,17 +3,22 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { AuthGuard } from './auth.guard'; import { RouterTestingModule } from '@angular/router/testing'; import { LoginComponent } from '../pages/login/login.component'; +import { Router } from '@angular/router'; describe('AuthGuard', () => { let guard: AuthGuard; + let router: Router; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule, RouterTestingModule.withRoutes( - [{ path: 'login', component: LoginComponent }] - )], providers: [AuthGuard], declarations: [LoginComponent] + [{ path: 'loginsocial', component: LoginComponent }] + )], + providers: [AuthGuard], + declarations: [LoginComponent] }); guard = TestBed.inject(AuthGuard); + router = TestBed.inject(Router); }); it('should be created', () => { @@ -23,13 +28,12 @@ describe('AuthGuard', () => { it('should return true for a logged in user', () => { localStorage.setItem('token', 'testtoken'); expect(guard.canActivate()).toBe(true); - } - ); + }); - it('should return false for a logged out user', () => { + it('should navigate to loginsocial for a logged out user', () => { localStorage.removeItem('token'); - expect(guard.canActivate()).toBe(false); - } - ); - + const navigateSpy = spyOn(router, 'navigate'); + guard.canActivate(); + expect(navigateSpy).toHaveBeenCalledWith(['/loginsocial']); + }); }); diff --git a/src/app/guard/auth.guard.ts b/src/app/guard/auth.guard.ts index f98f0c30..ed5df328 100644 --- a/src/app/guard/auth.guard.ts +++ b/src/app/guard/auth.guard.ts @@ -13,7 +13,7 @@ export class AuthGuard implements CanActivate { if (this.authService.isAuthenticated()) { return true; } else { - this.router.navigate(['/login']); + this.router.navigate(['/loginsocial']); return false; } } diff --git a/src/app/pages/edit-user/edit-user.component.ts b/src/app/pages/edit-user/edit-user.component.ts index f96db7a5..2767e5f3 100644 --- a/src/app/pages/edit-user/edit-user.component.ts +++ b/src/app/pages/edit-user/edit-user.component.ts @@ -98,7 +98,7 @@ export class EditUserComponent implements OnInit { 'Sucesso', 'Usuário atualizado com sucesso!' ); - this.navigator('/profile'); + this.navigator('/videos'); }, error: (error: ErrorResponseType) => { this.alertService.errorMessage(error.error); diff --git a/src/app/pages/login-social/login-social.component.css b/src/app/pages/login-social/login-social.component.css index 807ed9e3..545b10f2 100644 --- a/src/app/pages/login-social/login-social.component.css +++ b/src/app/pages/login-social/login-social.component.css @@ -1,13 +1,21 @@ +@font-face { + font-family: 'Helvetic'; + src: url('../../../assets/fonts/Helvetica.ttf') format('truetype'); + font-weight: normal; + font-style: normal; + } .container { display: flex; flex-direction: column; justify-content: center; align-items: center; - margin-left: 80px; + width: 100%; + max-width: 360px; + margin-right: auto; + margin-left: auto; height: 100%; - margin-top: -70px; } .google-button { @@ -36,41 +44,42 @@ } -.google-button span{ - position: relative; - margin-left: -70px; -} - .facebook-button { text-align: center; background-color: white; - color: #969696; + color: black; padding: 10px 20px; border-color: black; width: 260px; - height: 30px; + height: 40px; top: 210px; - left: 50px; + left: 25px; cursor: pointer; margin: 5px; - border: 0.15px solid #3C3C3B; - border-radius: 9px; + border: 1px solid #DADCE0; + border-radius: 5px; line-height: 10px; - font-weight: 400; - font-size: 13px; - background-image: url('../../../assets/facebook.png'); + background-image: url('../../../assets/facebook-icon-white-png.png'); background-position: center; background-size: 8% auto; background-repeat: no-repeat; - background-position: 220px 4px; + background-position: 12px 9px; margin-bottom: 10.5px; - margin-top: 10.5px; - + margin-top: 19.5px; + background-color: #1877F2; + } + + .facebook-button span{ position: relative; - margin-left: -55px; + margin-left: 30px; + font-family: Helvetic ,sans-serif; + font-size: 14px; + color: white; + + } .email-button{ @@ -80,29 +89,34 @@ padding: 10px 20px; border-color: black; width: 260px; - height: 30px; + height: 40px; top: 210px; left: 50px; margin: 5px; - border: 0.15px solid #3C3C3B; - border-radius: 9px; + border: 1px solid #DADCE0; + border-radius: 5px; line-height: 10px; font-weight: 400; - font-size: 13px; - margin-top: 10.5px; + margin-top: 10px; margin-bottom: 18.5px; + background-image: url('../../../assets/email-svgrepo-com.svg'); + background-position: center; + background-size: 8% auto; + background-repeat: no-repeat; + background-position: 12px 9px; } .email-button span{ position: relative; - margin-left: -85px; + margin-left: -5px; + font-size: 14px; } .cadastro { font-size: 13px; color: #0087C8; - margin-left: -140px; + margin-left: -72px; margin-top: 18.5px } diff --git a/src/app/pages/login-social/login-social.component.html b/src/app/pages/login-social/login-social.component.html index 682d5909..3c028444 100644 --- a/src/app/pages/login-social/login-social.component.html +++ b/src/app/pages/login-social/login-social.component.html @@ -1,10 +1,22 @@
+
+
+
+
- - - - Cadastra-se - - + + + + Cadastra-se
+ diff --git a/src/app/pages/login-social/login-social.component.spec.ts b/src/app/pages/login-social/login-social.component.spec.ts index 9d476b73..029a45be 100644 --- a/src/app/pages/login-social/login-social.component.spec.ts +++ b/src/app/pages/login-social/login-social.component.spec.ts @@ -1,17 +1,47 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - import { LoginSocialComponent } from './login-social.component'; +import { SocialAuthService, SocialUser, FacebookLoginProvider } from '@abacritt/angularx-social-login'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AuthService } from '../../services/auth.service'; +import { of } from 'rxjs'; +import { Component } from '@angular/core'; + +@Component({ template: '' }) +class DummyComponent {} describe('LoginSocialComponent', () => { let component: LoginSocialComponent; let fixture: ComponentFixture; + let mockSocialAuthService: jasmine.SpyObj; + let mockAuthService: jasmine.SpyObj; beforeEach(async () => { + mockSocialAuthService = jasmine.createSpyObj('SocialAuthService', ['signIn', 'signOut']); + mockAuthService = jasmine.createSpyObj('AuthService', ['loginSocialUser']); + mockAuthService.loginSocialUser.and.returnValue(of({ + access_token: 'mock-token', + is_new_user: false, + user_id: 'mock-user-id' + })); + await TestBed.configureTestingModule({ - declarations: [ LoginSocialComponent ] - }) - .compileComponents(); + declarations: [ LoginSocialComponent, DummyComponent ], + imports: [ + HttpClientTestingModule, + RouterTestingModule.withRoutes([ + { path: 'videos', component: DummyComponent }, + { path: 'editUser/:id', component: DummyComponent } + ]) + ], + providers: [ + { provide: SocialAuthService, useValue: mockSocialAuthService }, + { provide: AuthService, useValue: mockAuthService }, + ] + }).compileComponents(); + }); + beforeEach(() => { fixture = TestBed.createComponent(LoginSocialComponent); component = fixture.componentInstance; fixture.detectChanges(); @@ -20,4 +50,41 @@ describe('LoginSocialComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should call signIn when signing in with Facebook', async () => { + const user = new SocialUser(); + user.provider = 'FACEBOOK'; + user.id = '1234567890'; + user.name = 'Test User'; + user.email = 'test@example.com'; + + mockSocialAuthService.signIn.and.returnValue(Promise.resolve(user)); + await component.signInWithFB(); + + expect(mockSocialAuthService.signIn).toHaveBeenCalledWith(FacebookLoginProvider.PROVIDER_ID); + }); + + it('should process JWT response correctly', () => { + const payload = { name: 'Test User', email: 'test@example.com' }; + const encodedPayload = btoa(JSON.stringify(payload)); + const testResponse = { + credential: `header.${encodedPayload}.signature` + }; + + component.handleCredentialResponse(testResponse); + }); + + it('should handle Facebook login and send user data to server', async () => { + const user = new SocialUser(); + user.provider = 'FACEBOOK'; + user.id = '1234567890'; + user.name = 'Test User'; + user.email = 'test@example.com'; + + mockSocialAuthService.signIn.and.returnValue(Promise.resolve(user)); + await component.signInWithFB(); + + expect(mockSocialAuthService.signIn).toHaveBeenCalledWith(FacebookLoginProvider.PROVIDER_ID); + expect(mockAuthService.loginSocialUser).toHaveBeenCalledWith({ name: user.name, email: user.email }); + }); }); diff --git a/src/app/pages/login-social/login-social.component.ts b/src/app/pages/login-social/login-social.component.ts index d8e6d1a7..fa0853aa 100644 --- a/src/app/pages/login-social/login-social.component.ts +++ b/src/app/pages/login-social/login-social.component.ts @@ -1,10 +1,115 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; +import { SocialAuthService, SocialUser } from '@abacritt/angularx-social-login'; +import { FacebookLoginProvider } from '@abacritt/angularx-social-login'; +import { HttpClient } from '@angular/common/http'; +import { Router } from '@angular/router'; +import { AuthService } from '../../services/auth.service'; +declare var gapi: any; + +interface ServerResponse { + access_token: string; + is_new_user: boolean; + user_id: string; +} + +interface GoogleIdentityResponse { + credential: string; +} + +interface GoogleIdentityResponse { + credential: string; + clientId: string; +} + +declare global { + interface Window { + handleCredentialResponse: (response: any) => void; + } +} + @Component({ selector: 'app-login-social', templateUrl: './login-social.component.html', styleUrls: ['./login-social.component.css'] }) -export class LoginSocialComponent { +export class LoginSocialComponent implements OnInit { + private user: SocialUser | null = null; + private loggedIn: boolean = false; + + + constructor( + private authService: SocialAuthService, + private http: HttpClient, + private router: Router, + private Service: AuthService + ) { } + + + + ngOnInit(): void { + window['handleCredentialResponse'] = this.handleCredentialResponse.bind(this); + this.loadGoogleButton(); + } + + loadGoogleButton(): void { + const googleScript = document.createElement('script'); + googleScript.src = 'https://accounts.google.com/gsi/client'; + googleScript.async = true; + googleScript.defer = true; + document.body.appendChild(googleScript); + } + + handleCredentialResponse(response: any) { + const jwt = response.credential; + const payload = jwt.split('.')[1]; + const decodedPayload = atob(payload); + const userInformation = JSON.parse(decodedPayload); + + const user: SocialUser = new SocialUser(); + user.name = userInformation.name; + user.email = userInformation.email; + + this.sendUserDataToServer(user); + } + + + signInWithFB(): void { + this.authService.signIn(FacebookLoginProvider.PROVIDER_ID).then((user) => { + + if (user) { + this.sendUserDataToServer(user); + } + }); + } + + signOut(): void { + this.authService.signOut(); + } + private sendUserDataToServer(user: SocialUser) { + const userSocialData = { + name: user.name, + email: user.email + }; + + this.Service.loginSocialUser(userSocialData).subscribe( + (response) => { + console.log('Resposta do servidor:', response); + + if (response && response.access_token) { + localStorage.setItem('token', response.access_token); + + if (response.is_new_user) { + this.router.navigate([`/editUser/${response.user_id}`]); + } else { + this.router.navigate(['/videos']); + } + } + }, + (error) => { + console.error('Erro ao enviar dados para o servidor:', error); + } + ); + } } diff --git a/src/app/services/auth.service.spec.ts b/src/app/services/auth.service.spec.ts index 29599618..83b00de8 100644 --- a/src/app/services/auth.service.spec.ts +++ b/src/app/services/auth.service.spec.ts @@ -132,8 +132,10 @@ describe('AuthService', () => { it('should logout', () => { localStorage.setItem('token', 'testtoken'); + const navigateSpy = spyOn(service['router'], 'navigate'); service.logout(); expect(localStorage.getItem('token')).toBeNull(); + expect(navigateSpy).toHaveBeenCalledWith(['/loginsocial']); }); - + }); diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index 55269e4b..6a2bd524 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -21,6 +21,10 @@ export class AuthService { return this.http.post(`${this.usersAPIURL}/auth/login`, user); } + loginSocialUser(userSocialData: any): Observable { + return this.http.post(`${this.usersAPIURL}/auth/login/social`, userSocialData); + } + activeAccount(emailCode: any): Observable { return this.http.patch(`${this.usersAPIURL}/auth/activate-account`, emailCode); } @@ -52,6 +56,6 @@ export class AuthService { logout(): void { localStorage.removeItem('token'); - this.router.navigate(['/login']); + this.router.navigate(['/loginsocial']); } } diff --git a/src/assets/email-svgrepo-com.svg b/src/assets/email-svgrepo-com.svg new file mode 100644 index 00000000..5fa1e9e3 --- /dev/null +++ b/src/assets/email-svgrepo-com.svg @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/src/assets/facebook-icon-white-png.png b/src/assets/facebook-icon-white-png.png new file mode 100644 index 00000000..bade5046 Binary files /dev/null and b/src/assets/facebook-icon-white-png.png differ diff --git a/src/assets/fonts/Helvetica-Bold.ttf b/src/assets/fonts/Helvetica-Bold.ttf new file mode 100644 index 00000000..332b66ca Binary files /dev/null and b/src/assets/fonts/Helvetica-Bold.ttf differ diff --git a/src/assets/fonts/Helvetica.ttf b/src/assets/fonts/Helvetica.ttf new file mode 100644 index 00000000..718f22d4 Binary files /dev/null and b/src/assets/fonts/Helvetica.ttf differ diff --git a/tsconfig.app.json b/tsconfig.app.json index 374cc9d2..f54aee6e 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/app", - "types": [] + "types": ["gapi", "gapi.auth2"] }, "files": [ "src/main.ts"