argos/dmp-frontend/src/app/ui/auth/login/login.component.ts

434 lines
16 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { AfterViewInit, Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { AuthProvider } from '@app/core/common/enum/auth-provider';
import { ConfigurableProvider } from '@app/core/model/configurable-provider/configurableProvider';
import { AuthService } from '@app/core/services/auth/auth.service';
import { ConfigurableProvidersService } from '@app/ui/auth/login/utilities/configurableProviders.service';
import { LoginService } from '@app/ui/auth/login/utilities/login.service';
import { BaseComponent } from '@common/base/base.component';
import { environment } from 'environments/environment';
import { takeUntil } from 'rxjs/operators';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { MergeLoginService } from './utilities/merge-login.service';
import { Oauth2DialogService } from '@app/ui/misc/oauth2-dialog/service/oauth2-dialog.service';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
import { FormControl } from '@angular/forms';
import { OrcidUser } from '@app/core/model/orcid/orcidUser';
import { ZenodoToken } from '@app/core/model/zenodo/zenodo-token.model';
import { LoginInfo } from '@app/core/model/auth/login-info';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
/// <reference types="gapi" />
/// <reference types="facebook-js-sdk" />
declare const gapi: any;
declare const FB: any;
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent extends BaseComponent implements OnInit, AfterViewInit {
@Input() redirect: boolean = true;
@Input() mergeUsers: boolean;
public auth2: any;
private returnUrl: string;
private twitterUrl = new BehaviorSubject(undefined);
private emailFormControl = new FormControl('');
private orcidUser: OrcidUser;
private zenodoToken: ZenodoToken;
private accessToken: string;
private oauthLock: boolean;
//public cofigurableProviders: ConfigurableProvider[];
constructor(
private router: Router,
private route: ActivatedRoute,
private loginService: LoginService,
private authService: AuthService,
public configurableProviderService: ConfigurableProvidersService,
private configurationService: ConfigurationService,
private mergeLoginService: MergeLoginService,
private oauth2DialogService: Oauth2DialogService,
private httpClient: HttpClient,
private matomoService: MatomoService,
) { super(); }
ngOnInit(): void {
if(this.authService.current() && (this.redirect == true)){
this.router.navigate(['home']);
}
this.matomoService.trackPageView('loginPage');
this.route.queryParams
.pipe(takeUntil(this._destroyed))
.subscribe((params: Params) => {
const returnUrl = params['returnUrl'];
if (returnUrl) { this.returnUrl = returnUrl; }
});
this.authService.getConfigurableProviders()
.pipe(takeUntil(this._destroyed))
.subscribe((data: any) => {
this.configurableProviderService.providers = data;
})
}
ngAfterViewInit() {
this.initProviders();
}
public linkedInLogin() {
//this.router.navigate(['/login/linkedin']);
this.oauth2DialogService.login(this.getLinkedInUrl()).pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result !== undefined) {
if (!this.oauthLock) {
this.linkedInLoginUser(result.oauthCode, result.oauthState);
this.oauthLock = true;
}
} else {
this.oauthLock = false;
}
});
}
public twitterLogin() {
// this.router.navigate(['/login/twitter']);
this.twitterUrl.asObservable().pipe(takeUntil(this._destroyed)).subscribe(url => {
if (url !== undefined) {
this.oauth2DialogService.login(url).pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result !== undefined) {
if (!this.oauthLock) {
this.twitterLoginUser(result.oauthToken, result.oauthVerifier);
this.oauthLock = true;
}
} else {
this.oauthLock = false;
}
});
}
});
this.twitterAuthorize();
}
public b2AccessLogin() {
//this.router.navigate(['/login/external/b2access'], {queryParams: {returnUrl: this.returnUrl, mergeUsers: this.mergeUsers}});
this.oauth2DialogService.login(this.getB2AccessUrl()).pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result !== undefined) {
if (!this.oauthLock) {
this.b2AccessLoginUser(result.oauthCode);
this.oauthLock = true;
}
} else {
this.oauthLock = false;
}
});
}
public orcidLogin() {
//this.router.navigate(['/login/external/orcid']);
this.oauth2DialogService.login(this.getORCIDUrl()).pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result !== undefined) {
if (!this.oauthLock) {
this.orcidLoginUser(result.oauthCode);
this.oauthLock = true;
}
} else {
this.oauthLock = false;
}
});
}
public openaireLogin() {
//this.router.navigate(['/login/openaire']);
this.oauth2DialogService.login(this.getOpenAireUrl()).pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result !== undefined) {
if (!this.oauthLock) {
this.openaireLoginUser(result.oauthCode, result.oauthState);
this.oauthLock = true;
}
} else {
this.oauthLock = false;
}
});
}
public configurableLogin(provider: ConfigurableProvider) {
this.router.navigate(['/login/configurable/' + provider.configurableLoginId])
}
public zenodoLogin() {
//this.router.navigate(['/login/external/zenodo']);
this.oauth2DialogService.login(this.getZenodoUrl()).pipe(takeUntil(this._destroyed))
.subscribe(result => {
if (result !== undefined) {
if (!this.oauthLock) {
this.zenodoLoginUser(result.oauthCode);
this.oauthLock = true;
}
} else {
this.oauthLock = false;
}
});
}
public hasFacebookOauth(): boolean {
return this.hasProvider(AuthProvider.Facebook);
}
public hasLinkedInOauth(): boolean {
return this.hasProvider(AuthProvider.LinkedIn);
}
public hasTwitterOauth(): boolean {
return this.hasProvider(AuthProvider.Twitter);
}
public hasGoogleOauth(): boolean {
return this.hasProvider(AuthProvider.Google);
}
public hasB2AccessOauth(): boolean {
return this.hasProvider(AuthProvider.B2Access);
}
public hasOrcidOauth(): boolean {
return this.hasProvider(AuthProvider.ORCID);
}
public hasOpenAireOauth(): boolean {
return this.hasProvider(AuthProvider.OpenAire);
}
public hasZenodoOauth(): boolean {
return this.hasProvider(AuthProvider.Zenodo);
}
public initProviders() {
if (this.hasProvider(AuthProvider.Google)) { this.initializeGoogleOauth(); }
if (this.hasProvider(AuthProvider.Facebook)) { this.initializeFacebookOauth(); }
}
public hasProvider(provider: AuthProvider) {
for (let i = 0; i < this.configurationService.loginProviders.enabled.length; i++) {
if (provider === this.configurationService.loginProviders.enabled[i]) { return this.isProviderProperlyConfigured(provider); }
}
return false;
}
private isProviderProperlyConfigured(provider: AuthProvider) {
switch (provider) {
case AuthProvider.Facebook: return this.hasAllRequiredFieldsConfigured(this.configurationService.loginProviders.facebookConfiguration);
case AuthProvider.Google: return this.hasAllRequiredFieldsConfigured(this.configurationService.loginProviders.googleConfiguration);
case AuthProvider.LinkedIn: return this.hasAllRequiredFieldsConfigured(this.configurationService.loginProviders.linkedInConfiguration);
case AuthProvider.Twitter: return this.hasAllRequiredFieldsConfigured(this.configurationService.loginProviders.twitterConfiguration);
case AuthProvider.B2Access: return this.hasAllRequiredFieldsConfigured(this.configurationService.loginProviders.b2accessConfiguration);
case AuthProvider.ORCID: return this.hasAllRequiredFieldsConfigured(this.configurationService.loginProviders.orcidConfiguration);
case AuthProvider.OpenAire: return this.hasAllRequiredFieldsConfigured(this.configurationService.loginProviders.openAireConfiguration);
case AuthProvider.Zenodo: return this.hasAllRequiredFieldsConfigured(this.configurationService.loginProviders.zenodoConfiguration);
default: throw new Error('Unsupported Provider Type');
}
}
private hasAllRequiredFieldsConfigured(configuration: any) {
if (configuration != null && configuration.clientId != null) { return true; }
return false;
}
/*
* GOOGLE SIGN IN
*/
private initializeGoogleOauth(): void {
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: this.configurationService.loginProviders.googleConfiguration.clientId,
scope: 'profile email'
});
this.attachGoogleSignΙn(document.getElementById('googleSignInButton'));
});
}
public attachGoogleSignΙn(element) {
if (!element) { return; }
this.auth2.attachClickHandler(element, {},
(googleUser) => {
const id_token = googleUser.getAuthResponse().id_token;
if (id_token) {
this.authLogin({ ticket: id_token, provider: AuthProvider.Google });
}
}, (error) => {
});
}
/*
* FACEBOOK SIGN IN
*/
private initializeFacebookOauth(): void {
FB.init({
appId: this.configurationService.loginProviders.facebookConfiguration.clientId,
cookie: false,
xfbml: true,
version: 'v2.8'
});
}
public facebookLogin() {
FB.login((response: any) => {
if (response.status === 'connected' || 'not_authorized') {
this.authLogin({ ticket: response.authResponse.accessToken, provider: AuthProvider.Facebook });
}
}, { scope: 'email' });
}
public hasConfigurableProviders(): boolean {
return !(this.configurableProviderService.providers == undefined) && this.configurableProviderService.providers.length > 0
}
private getLinkedInUrl() {
return this.configurationService.loginProviders.linkedInConfiguration.oauthUrl
+ '?response_type=code&client_id=' + this.configurationService.loginProviders.linkedInConfiguration.clientId
+ '&redirect_uri=' + this.configurationService.loginProviders.linkedInConfiguration.redirectUri
+ '&state=' + this.configurationService.loginProviders.linkedInConfiguration.state
+ '&scope=r_emailaddress';
}
public linkedInLoginUser(code: string, state: string) {
if (state !== this.configurationService.loginProviders.linkedInConfiguration.state) {
this.router.navigate(['/login']);
}
this.httpClient.post(this.configurationService.server + 'auth/linkedInRequestToken', { code: code, provider: AuthProvider.LinkedIn })
.pipe(takeUntil(this._destroyed))
.subscribe((data: any) => {
this.authLogin({ ticket: data.payload.accessToken, provider: AuthProvider.LinkedIn, data: null });
});
}
public twitterAuthorize() {
let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json');
headers = headers.set('Accept', 'application/json');
this.httpClient.get(this.configurationService.server + 'auth/twitterRequestToken', { headers: headers })
.pipe(takeUntil(this._destroyed))
.subscribe((data: any) => {
this.twitterUrl.next(this.configurationService.loginProviders.twitterConfiguration.oauthUrl + '?oauth_token=' + data.payload.value);
});
}
public twitterLoginUser(token: string, verifier: string) {
const data = {
email: this.emailFormControl.value, verifier: verifier
};
this.authLogin({ ticket: token, provider: AuthProvider.Twitter, data: data });
}
private getB2AccessUrl() {
return this.configurationService.loginProviders.b2accessConfiguration.oauthUrl
+ '?response_type=code&client_id=' + this.configurationService.loginProviders.b2accessConfiguration.clientId
+ '&redirect_uri=' + this.configurationService.loginProviders.b2accessConfiguration.redirectUri
+ '&state=' + this.configurationService.loginProviders.b2accessConfiguration.state
+ '&scope=USER_PROFILE';
}
public b2AccessLoginUser(code: String) {
let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json');
headers = headers.set('Accept', 'application/json');
this.httpClient.post(this.configurationService.server + 'auth/b2AccessRequestToken', { code: code }, { headers: headers })
.pipe(takeUntil(this._destroyed))
.subscribe((data: any) => {
this.authLogin({ ticket: data.payload.accessToken, provider: AuthProvider.B2Access, data: null });
});
}
private getORCIDUrl() {
return this.configurationService.loginProviders.orcidConfiguration.oauthUrl
+ '?client_id='
+ this.configurationService.loginProviders.orcidConfiguration.clientId
+ '&response_type=code&scope=/authenticate&redirect_uri='
+ this.configurationService.loginProviders.orcidConfiguration.redirectUri;
}
public orcidLoginUser(code: string) {
let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json');
headers = headers.set('Accept', 'application/json');
this.httpClient.post(this.configurationService.server + 'auth/orcidRequestToken', { code: code }, { headers: headers })
.pipe(takeUntil(this._destroyed))
.subscribe((responseData: any) => {
this.orcidUser = new OrcidUser();
this.orcidUser.orcidId = responseData.payload.orcidId
this.orcidUser.name = responseData.payload.name
this.accessToken = responseData.payload.accessToken;
this.authLogin({ ticket: this.accessToken, provider: AuthProvider.ORCID, data: this.orcidUser });
});
}
private getOpenAireUrl() {
return this.configurationService.loginProviders.openAireConfiguration.oauthUrl
+ '?response_type=code&client_id=' + this.configurationService.loginProviders.openAireConfiguration.clientId
+ '&redirect_uri=' + this.configurationService.loginProviders.openAireConfiguration.redirectUri
+ '&state=' + this.configurationService.loginProviders.openAireConfiguration.state
+ '&scope=openid profile email';
}
public openaireLoginUser(code: string, state: string) {
if (state !== this.configurationService.loginProviders.openAireConfiguration.state) {
this.router.navigate(['/login'])
}
this.httpClient.post(this.configurationService.server + 'auth/openAireRequestToken', { code: code, provider: AuthProvider.OpenAire })
.pipe(takeUntil(this._destroyed))
.subscribe((data: any) => {
this.authLogin({ ticket: data.payload.accessToken, provider: AuthProvider.OpenAire, data: null });
});
}
private getZenodoUrl() {
return this.configurationService.loginProviders.zenodoConfiguration.oauthUrl
+ '?client_id='
+ this.configurationService.loginProviders.zenodoConfiguration.clientId
+ '&response_type=code&scope=deposit:write+deposit:actions+user:email&state=astate&redirect_uri='
+ this.configurationService.loginProviders.zenodoConfiguration.redirectUri;
}
public zenodoLoginUser(code: string) {
let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json');
headers = headers.set('Accept', 'application/json');
this.httpClient.post(this.configurationService.server + 'auth/zenodoRequestToken', { code: code }, { headers: headers })
.pipe(takeUntil(this._destroyed))
.subscribe((responseData: any) => {
this.zenodoToken = new ZenodoToken();
this.zenodoToken.userId = responseData.payload.userId;
this.zenodoToken.expiresIn = responseData.payload.expiresIn;
this.accessToken = this.zenodoToken.accessToken = responseData.payload.accessToken;
this.zenodoToken.email = responseData.payload.email;
this.zenodoToken.refreshToken = responseData.payload.refreshToken;
this.authLogin({ ticket: this.accessToken, provider: AuthProvider.Zenodo, data: this.zenodoToken });
});
}
private authLogin(loginInfo: LoginInfo) {
if (this.mergeUsers) {
this.authService.mergeLogin(loginInfo)
.pipe(takeUntil(this._destroyed))
.subscribe(
res => this.mergeLoginService.setRequest({email: res.payload.email, userId: res.payload.id, provider: loginInfo.provider})
);
} else {
this.authService.login(loginInfo)
.pipe(takeUntil(this._destroyed))
.subscribe(
res => this.loginService.onLogInSuccess(res, this.returnUrl),
error => this.loginService.onLogInError(error)
);
}
}
}