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

432 lines
16 KiB
TypeScript

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 { 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() 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.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.attachGoogleSignIn(document.getElementById('googleSignInButton'));
});
}
public attachGoogleSignIn(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)
);
}
}
}