Merge pull request #16 from Quantum-P3/feature/US-01-fix

Inicio de sesion con google
This commit is contained in:
Eduardo Quiros 2021-07-11 04:13:46 +00:00 committed by GitHub
commit 7fb9b9b88b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 257 additions and 8 deletions

View File

@ -80,6 +80,8 @@
"@ng-bootstrap/ng-bootstrap": "9.1.3", "@ng-bootstrap/ng-bootstrap": "9.1.3",
"@ngx-translate/core": "13.0.0", "@ngx-translate/core": "13.0.0",
"@ngx-translate/http-loader": "6.0.0", "@ngx-translate/http-loader": "6.0.0",
"@types/gapi.auth2": "0.0.54",
"angularx-social-login": "^4.0.1",
"bootstrap": "4.6.0", "bootstrap": "4.6.0",
"dayjs": "1.10.5", "dayjs": "1.10.5",
"ngx-infinite-scroll": "10.0.1", "ngx-infinite-scroll": "10.0.1",

View File

@ -8,5 +8,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* Properties are configured in the {@code application.yml} file. * Properties are configured in the {@code application.yml} file.
* See {@link tech.jhipster.config.JHipsterProperties} for a good example. * See {@link tech.jhipster.config.JHipsterProperties} for a good example.
*/ */
@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false) @ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
public class ApplicationProperties {} public class ApplicationProperties {}

View File

@ -92,6 +92,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.antMatchers("/api/account/reset-password/finish").permitAll() .antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/admin/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/api/admin/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api/**").authenticated() .antMatchers("/api/**").authenticated()
.antMatchers("/api/**").permitAll()
.antMatchers("/websocket/**").authenticated() .antMatchers("/websocket/**").authenticated()
.antMatchers("/management/health").permitAll() .antMatchers("/management/health").permitAll()
.antMatchers("/management/health/**").permitAll() .antMatchers("/management/health/**").permitAll()

View File

@ -156,7 +156,7 @@ public class UserService {
* Modified to register extra user data * Modified to register extra user data
* name, iconoPerfil, fechaNacimiento, estado, pais * name, iconoPerfil, fechaNacimiento, estado, pais
*/ */
public User registerUser(AdminUserDTO userDTO, String password, String name, Integer profileIcon, Integer isAdmin) { public User registerUser(AdminUserDTO userDTO, String password, String name, Integer profileIcon, Integer isAdmin, Integer isGoogle) {
userRepository userRepository
.findOneByLogin(userDTO.getLogin().toLowerCase()) .findOneByLogin(userDTO.getLogin().toLowerCase())
.ifPresent( .ifPresent(
@ -190,7 +190,13 @@ public class UserService {
newUser.setImageUrl(userDTO.getImageUrl()); newUser.setImageUrl(userDTO.getImageUrl());
newUser.setLangKey(userDTO.getLangKey()); newUser.setLangKey(userDTO.getLangKey());
// new user is not active // new user is not active
if (isGoogle == 1) {
newUser.setActivated(true);
} else {
newUser.setActivated(false); newUser.setActivated(false);
}
// new user gets registration key // new user gets registration key
newUser.setActivationKey(RandomUtil.generateActivationKey()); newUser.setActivationKey(RandomUtil.generateActivationKey());
Set<Authority> authorities = new HashSet<>(); Set<Authority> authorities = new HashSet<>();

View File

@ -67,10 +67,14 @@ public class AccountResource {
managedUserVM.getPassword(), managedUserVM.getPassword(),
managedUserVM.getName(), managedUserVM.getName(),
managedUserVM.getProfileIcon(), managedUserVM.getProfileIcon(),
managedUserVM.getIsAdmin() managedUserVM.getIsAdmin(),
managedUserVM.getIsGoogle()
); );
if (managedUserVM.getIsGoogle() != 1) {
mailService.sendActivationEmail(user); mailService.sendActivationEmail(user);
} }
}
/** /**
* {@code GET /activate} : activate the registered user. * {@code GET /activate} : activate the registered user.

View File

@ -24,6 +24,8 @@ public class ManagedUserVM extends AdminUserDTO {
private Integer isAdmin; private Integer isAdmin;
private Integer isGoogle;
public ManagedUserVM() { public ManagedUserVM() {
// Empty constructor needed for Jackson. // Empty constructor needed for Jackson.
} }
@ -60,6 +62,14 @@ public class ManagedUserVM extends AdminUserDTO {
this.isAdmin = isAdmin; this.isAdmin = isAdmin;
} }
public Integer getIsGoogle() {
return isGoogle;
}
public void setIsGoogle(Integer isGoogle) {
this.isGoogle = isGoogle;
}
// prettier-ignore // prettier-ignore
@Override @Override
public String toString() { public String toString() {

View File

@ -65,6 +65,7 @@ describe('Component Tests', () => {
name: '', name: '',
profileIcon: 1, profileIcon: 1,
isAdmin: 0, isAdmin: 0,
isGoogle: 0,
}); });
expect(comp.success).toBe(true); expect(comp.success).toBe(true);
expect(comp.errorUserExists).toBe(false); expect(comp.errorUserExists).toBe(false);

View File

@ -95,6 +95,7 @@ export class RegisterComponent implements AfterViewInit {
name, name,
profileIcon: this.profileIcon, profileIcon: this.profileIcon,
isAdmin: 0, isAdmin: 0,
isGoogle: 0,
}) })
.subscribe( .subscribe(
() => (this.success = true), () => (this.success = true),
@ -103,7 +104,7 @@ export class RegisterComponent implements AfterViewInit {
} }
} }
private processError(response: HttpErrorResponse): void { processError(response: HttpErrorResponse): void {
if (response.status === 400 && response.error.type === LOGIN_ALREADY_USED_TYPE) { if (response.status === 400 && response.error.type === LOGIN_ALREADY_USED_TYPE) {
this.errorUserExists = true; this.errorUserExists = true;
} else if (response.status === 400 && response.error.type === EMAIL_ALREADY_USED_TYPE) { } else if (response.status === 400 && response.error.type === EMAIL_ALREADY_USED_TYPE) {

View File

@ -6,6 +6,7 @@ export class Registration {
public langKey: string, public langKey: string,
public name: string, public name: string,
public profileIcon: number, public profileIcon: number,
public isAdmin: number public isAdmin: number,
public isGoogle: number
) {} ) {}
} }

View File

@ -17,6 +17,10 @@ import { SharedModule } from 'app/shared/shared.module';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { HomeModule } from './home/home.module'; import { HomeModule } from './home/home.module';
import { EntityRoutingModule } from './entities/entity-routing.module'; import { EntityRoutingModule } from './entities/entity-routing.module';
import { ReactiveFormsModule } from '@angular/forms';
import { SocialLoginModule, SocialAuthServiceConfig } from 'angularx-social-login';
import { GoogleLoginProvider } from 'angularx-social-login';
// jhipster-needle-angular-add-module-import JHipster will add new module here // jhipster-needle-angular-add-module-import JHipster will add new module here
import { NgbDateDayjsAdapter } from './config/datepicker-adapter'; import { NgbDateDayjsAdapter } from './config/datepicker-adapter';
import { fontAwesomeIcons } from './config/font-awesome-icons'; import { fontAwesomeIcons } from './config/font-awesome-icons';
@ -37,6 +41,7 @@ import { SidebarComponent } from './layouts/sidebar/sidebar.component';
// jhipster-needle-angular-add-module JHipster will add new module here // jhipster-needle-angular-add-module JHipster will add new module here
EntityRoutingModule, EntityRoutingModule,
AppRoutingModule, AppRoutingModule,
SocialLoginModule,
// Set this to true to enable service worker (PWA) // Set this to true to enable service worker (PWA)
ServiceWorkerModule.register('ngsw-worker.js', { enabled: false }), ServiceWorkerModule.register('ngsw-worker.js', { enabled: false }),
HttpClientModule, HttpClientModule,
@ -58,6 +63,18 @@ import { SidebarComponent } from './layouts/sidebar/sidebar.component';
{ provide: LOCALE_ID, useValue: 'es' }, { provide: LOCALE_ID, useValue: 'es' },
{ provide: NgbDateAdapter, useClass: NgbDateDayjsAdapter }, { provide: NgbDateAdapter, useClass: NgbDateDayjsAdapter },
httpInterceptorProviders, httpInterceptorProviders,
{
provide: 'SocialAuthServiceConfig',
useValue: {
autoLogin: false,
providers: [
{
id: GoogleLoginProvider.PROVIDER_ID,
provider: new GoogleLoginProvider('178178891217-b517thad8f15d4at2vk2410v7a09dcvt.apps.googleusercontent.com'),
},
],
} as SocialAuthServiceConfig,
},
], ],
declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, FooterComponent, SidebarComponent], declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, FooterComponent, SidebarComponent],
bootstrap: [MainComponent], bootstrap: [MainComponent],

View File

@ -65,6 +65,7 @@ describe('Component Tests', () => {
name: '', name: '',
profileIcon: 1, profileIcon: 1,
isAdmin: 1, isAdmin: 1,
isGoogle: 0,
}); });
expect(comp.success).toBe(true); expect(comp.success).toBe(true);
expect(comp.errorUserExists).toBe(false); expect(comp.errorUserExists).toBe(false);

View File

@ -93,6 +93,7 @@ export class UsuarioExtraUpdateComponent {
name, name,
profileIcon: this.profileIcon, profileIcon: this.profileIcon,
isAdmin: 1, isAdmin: 1,
isGoogle: 0,
}) })
.subscribe( .subscribe(
() => (this.success = true), () => (this.success = true),

View File

@ -128,6 +128,19 @@
<button type="submit" class="btn btn-primary w-100" data-cy="submit">Iniciar sesion</button> <button type="submit" class="btn btn-primary w-100" data-cy="submit">Iniciar sesion</button>
</div> </div>
</form> </form>
<div class="google-btn w-80 m-auto">
<div class="google-icon-wrapper">
<img class="google-icon" src="https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg" />
</div>
<button class="btn-text" (click)="signInWithGoogle()">Iniciar con Google</button>
</div>
<!--<div class="mb-3 mb-0">
<button class="btn" (click)="signInWithGoogle()">
<i class="fa fa-Google">Iniciar con Google</i>
</button>
</div>-->
</div> </div>
<!-- end card-body --> <!-- end card-body -->
</div> </div>

View File

@ -1,3 +1,56 @@
body { body {
background-color: #f2f2f2 !important; background-color: #f2f2f2 !important;
} }
$white: #fff;
$google-blue: #4285f4;
$button-active-blue: #1669f2;
.google-btn {
width: 184px;
height: 42px;
background-color: $google-blue !important;
border-radius: 2px;
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.25);
.google-icon-wrapper {
position: absolute;
margin-top: 1px;
margin-left: 1px;
width: 40px;
height: 40px;
border-radius: 2px;
background-color: $white;
}
.google-icon {
position: absolute;
margin-top: 11px;
margin-left: 11px;
width: 18px;
height: 18px;
}
.btn-text {
float: right;
margin: 5px 5px 0px 0px;
color: $white;
font-size: 14px;
letter-spacing: 0.2px;
font-family: 'Roboto';
background-color: $google-blue;
width: 135px;
height: 30px;
padding: 6px 6px 7px 6px;
border: $google-blue;
}
&:hover {
box-shadow: 0 0 6px $google-blue !important;
}
&:active {
background: $button-active-blue !important;
}
.google-div {
margin-left: 150px !important;
}
}
@import url(https://fonts.googleapis.com/css?family=Roboto:500);

View File

@ -4,6 +4,12 @@ import { Router } from '@angular/router';
import { LoginService } from 'app/login/login.service'; import { LoginService } from 'app/login/login.service';
import { AccountService } from 'app/core/auth/account.service'; import { AccountService } from 'app/core/auth/account.service';
import { SocialAuthService, SocialUser } from 'angularx-social-login';
import { GoogleLoginProvider } from 'angularx-social-login';
import { RegisterService } from '../account/register/register.service';
import { TranslateService } from '@ngx-translate/core';
import { HttpErrorResponse } from '@angular/common/http';
import { EMAIL_ALREADY_USED_TYPE, LOGIN_ALREADY_USED_TYPE } from '../config/error.constants';
@Component({ @Component({
selector: 'jhi-login', selector: 'jhi-login',
@ -15,6 +21,9 @@ export class LoginComponent implements OnInit, AfterViewInit {
username!: ElementRef; username!: ElementRef;
authenticationError = false; authenticationError = false;
error = false;
errorEmailExists = false;
errorUserExists = false;
loginForm = this.fb.group({ loginForm = this.fb.group({
username: [null, [Validators.required]], username: [null, [Validators.required]],
@ -22,14 +31,33 @@ export class LoginComponent implements OnInit, AfterViewInit {
rememberMe: [false], rememberMe: [false],
}); });
user: SocialUser = new SocialUser();
loggedIn: boolean = false;
success = false;
constructor( constructor(
private accountService: AccountService, private accountService: AccountService,
private loginService: LoginService, private loginService: LoginService,
private router: Router, private router: Router,
private fb: FormBuilder private fb: FormBuilder,
private authService: SocialAuthService,
private registerService: RegisterService,
private translateService: TranslateService
) {} ) {}
ngOnInit(): void { ngOnInit(): void {
//Servicio para verificar si el usuario se encuentra loggeado
/*this.authService.authState.subscribe(user => {
this.user = user;
this.loggedIn = user != null;
/!* console.log('correo: ' + user.email);
console.log('correo: ' + user.name);
console.log('ID: ' + this.user.id);*!/
this.authenticacionGoogle();
});
*/
// if already authenticated then navigate to home page // if already authenticated then navigate to home page
this.accountService.identity().subscribe(() => { this.accountService.identity().subscribe(() => {
if (this.accountService.isAuthenticated()) { if (this.accountService.isAuthenticated()) {
@ -42,6 +70,89 @@ export class LoginComponent implements OnInit, AfterViewInit {
this.username.nativeElement.focus(); this.username.nativeElement.focus();
} }
//Inicio Google
signInWithGoogle(): void {
this.authService.signIn(GoogleLoginProvider.PROVIDER_ID).then(() => {
this.authService.authState.subscribe(user => {
this.user = user;
this.loggedIn = user != null;
/* console.log('correo: ' + user.email);
console.log('correo: ' + user.name);
console.log('ID: ' + this.user.id);*/
this.authenticacionGoogle();
});
});
}
authenticacionGoogle(): void {
this.loginService.login({ username: this.user.email, password: this.user.id, rememberMe: true }).subscribe(
() => {
this.authenticationError = false;
if (!this.router.getCurrentNavigation()) {
window.localStorage.setItem('IsGoogle', 'true');
// There were no routing during login (eg from navigationToStoredUrl)
this.router.navigate(['']);
}
},
() => this.activateGoogle()
/*this.registerService
.save({
login: this.user.email,
email: this.user.email,
password: this.user.id,
langKey: this.translateService.currentLang,
name: this.user.name,
profileIcon: this.randomProfilePic(),
isAdmin: 0,
})
.subscribe(
() => (this.success = true),
response => this.processError(response)
) */ //console.log("Usuario no existe")
);
}
randomProfilePic(): number {
return Math.floor(Math.random() * (28 - 1 + 1)) + 1;
}
processError(response: HttpErrorResponse): void {
if (response.status === 400 && response.error.type === LOGIN_ALREADY_USED_TYPE) {
this.errorUserExists = true;
} else if (response.status === 400 && response.error.type === EMAIL_ALREADY_USED_TYPE) {
this.errorEmailExists = true;
} else {
this.error = true;
}
}
refreshToken(): void {
this.authService.refreshAuthToken(GoogleLoginProvider.PROVIDER_ID);
}
activateGoogle(): void {
this.registerService
.save({
login: this.user.email,
email: this.user.email,
password: this.user.id,
langKey: this.translateService.currentLang,
name: this.user.name,
profileIcon: this.randomProfilePic(),
isAdmin: 0,
isGoogle: 1,
})
.subscribe(
() => {
this.success = true;
this.authenticacionGoogle();
},
response => this.processError(response)
);
}
login(): void { login(): void {
this.loginService this.loginService
.login({ .login({

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { UsuarioGoogleLogInService } from './usuario-google-log-in.service';
describe('UsuarioGoogleLogInService', () => {
let service: UsuarioGoogleLogInService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(UsuarioGoogleLogInService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,9 @@
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class UsuarioGoogleLogInService {
constructor() {}
}

View File

@ -12,6 +12,7 @@
<link rel="icon" href="favicon.ico" /> <link rel="icon" href="favicon.ico" />
<link rel="manifest" href="manifest.webapp" /> <link rel="manifest" href="manifest.webapp" />
<link rel="stylesheet" href="content/css/loading.css" /> <link rel="stylesheet" href="content/css/loading.css" />
<script src="https://apis.google.com/js/platform.js" async defer></script>
<!-- jhipster-needle-add-resources-to-root - JHipster will add new resources here --> <!-- jhipster-needle-add-resources-to-root - JHipster will add new resources here -->
</head> </head>
<body> <body>

View File

@ -2,7 +2,7 @@
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "./target/classes/static/app", "outDir": "./target/classes/static/app",
"types": [] "types": ["gapi", "gapi.auth2"]
}, },
"files": ["src/main/webapp/main.ts", "src/main/webapp/polyfills.ts"], "files": ["src/main/webapp/main.ts", "src/main/webapp/polyfills.ts"],
"include": ["src/main/webapp/**/*.d.ts"] "include": ["src/main/webapp/**/*.d.ts"]