diff --git a/dmp-frontend/src/app/core/core-service.module.ts b/dmp-frontend/src/app/core/core-service.module.ts index 3082ad593..02a2fca62 100644 --- a/dmp-frontend/src/app/core/core-service.module.ts +++ b/dmp-frontend/src/app/core/core-service.module.ts @@ -43,6 +43,7 @@ import { ConfigurationService } from './services/configuration/configuration.ser import { HttpClient } from '@angular/common/http'; import { LanguageInfoService } from './services/culture/language-info-service'; import { CurrencyService } from './services/currency/currency.service'; +import { MergeEmailConfirmationService } from './services/merge-email-confirmation/merge-email-confirmation.service'; // // // This is shared module that provides all the services. Its imported only once on the AppModule. @@ -107,6 +108,7 @@ export class CoreServiceModule { LockService, UserGuideService, CurrencyService, + MergeEmailConfirmationService, ConfigurationService, { provide: APP_INITIALIZER, diff --git a/dmp-frontend/src/app/core/services/auth/auth.service.ts b/dmp-frontend/src/app/core/services/auth/auth.service.ts index 66a52f3bc..4217d66e5 100644 --- a/dmp-frontend/src/app/core/services/auth/auth.service.ts +++ b/dmp-frontend/src/app/core/services/auth/auth.service.ts @@ -91,6 +91,13 @@ export class AuthService extends BaseService { })); } + public mergeLogin(loginInfo: LoginInfo): Observable { + this.actionUrl = this.configurationService.server + 'auth/'; + const url = this.actionUrl + 'externallogin'; + + return this.http.post(url, loginInfo, { headers: this.headers }); + } + public nativeLogin(credentials: Credential): Observable { this.actionUrl = this.configurationService.server + 'auth/'; const url = this.actionUrl + 'nativelogin'; diff --git a/dmp-frontend/src/app/ui/auth/login/b2access/b2access-login.component.ts b/dmp-frontend/src/app/ui/auth/login/b2access/b2access-login.component.ts index a5e2948f8..e60c04ae8 100644 --- a/dmp-frontend/src/app/ui/auth/login/b2access/b2access-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/b2access/b2access-login.component.ts @@ -1,6 +1,6 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Params } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { AuthProvider } from '@app/core/common/enum/auth-provider'; import { AuthService } from '@app/core/services/auth/auth.service'; import { LoginService } from '@app/ui/auth/login/utilities/login.service'; @@ -22,7 +22,8 @@ export class B2AccessLoginComponent extends BaseComponent implements OnInit { private authService: AuthService, private loginService: LoginService, private httpClient: HttpClient, - private configurationService: ConfigurationService + private configurationService: ConfigurationService, + private router: Router ) { super(); } @@ -31,9 +32,10 @@ export class B2AccessLoginComponent extends BaseComponent implements OnInit { this.route.queryParams .pipe(takeUntil(this._destroyed)) .subscribe((params: Params) => { - const returnUrl = params['returnUrl']; - if (returnUrl) { this.returnUrl = returnUrl; } - if (!params['code']) { this.b2AccessGetAuthCode(); } else { this.b2AccessLogin(params['code']); } + // const returnUrl = params['returnUrl']; + // if (returnUrl) { this.returnUrl = returnUrl; } + // if (!params['code']) { this.b2AccessGetAuthCode(); } else { this.b2AccessLogin(params['code']); } + this.router.navigate(['/oauth2'], {queryParams: params}); }); } diff --git a/dmp-frontend/src/app/ui/auth/login/linkedin-login/linkedin-login.component.ts b/dmp-frontend/src/app/ui/auth/login/linkedin-login/linkedin-login.component.ts index 6b87652c8..e2285ea4e 100644 --- a/dmp-frontend/src/app/ui/auth/login/linkedin-login/linkedin-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/linkedin-login/linkedin-login.component.ts @@ -32,9 +32,10 @@ export class LinkedInLoginComponent extends BaseComponent implements OnInit { this.route.queryParams .pipe(takeUntil(this._destroyed)) .subscribe((params: Params) => { - const returnUrl = params['returnUrl']; - if (returnUrl) { this.returnUrl = returnUrl; } - if (!params['code']) { this.linkedinAuthorize(); } else { this.linkedInLoginUser(params['code'], params['state']); } + // const returnUrl = params['returnUrl']; + // if (returnUrl) { this.returnUrl = returnUrl; } + // if (!params['code']) { this.linkedinAuthorize(); } else { this.linkedInLoginUser(params['code'], params['state']); } + this.router.navigate(['/oauth2'], {queryParams: params}); }); } diff --git a/dmp-frontend/src/app/ui/auth/login/login.component.ts b/dmp-frontend/src/app/ui/auth/login/login.component.ts index 7e7863268..12b6c3e50 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/login.component.ts @@ -9,6 +9,14 @@ 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'; /// /// @@ -27,6 +35,11 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn public auth2: any; private returnUrl: string; + private twitterUrl = new BehaviorSubject(undefined); + private emailFormControl = new FormControl(''); + private orcidUser: OrcidUser; + private zenodoToken: ZenodoToken; + private accessToken: string; //public cofigurableProviders: ConfigurableProvider[]; constructor( @@ -35,7 +48,10 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn private loginService: LoginService, private authService: AuthService, public configurableProviderService: ConfigurableProvidersService, - private configurationService: ConfigurationService + private configurationService: ConfigurationService, + private mergeLoginService: MergeLoginService, + private oauth2DialogService: Oauth2DialogService, + private httpClient: HttpClient ) { super(); } ngOnInit(): void { @@ -57,23 +73,58 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn } public linkedInLogin() { - this.router.navigate(['/login/linkedin']); + //this.router.navigate(['/login/linkedin']); + this.oauth2DialogService.login(this.getLinkedInUrl()).pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (result !== undefined) { + this.linkedInLoginUser(result.oauthCode, result.oauthState); + } + }); } public twitterLogin() { - this.router.navigate(['/login/twitter']); + // 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) { + this.twitterLoginUser(result.oauthToken, result.oauthVerifier); + } + }); + } + }); + this.twitterAuthorize(); } public b2AccessLogin() { - this.router.navigate(['/login/external/b2access']); + //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) { + this.b2AccessLoginUser(result.oauthCode); + } + }); } public orcidLogin() { - this.router.navigate(['/login/external/orcid']); + //this.router.navigate(['/login/external/orcid']); + this.oauth2DialogService.login(this.getORCIDUrl()).pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (result !== undefined) { + this.orcidLoginUser(result.oauthCode); + } + }); } public openaireLogin() { - this.router.navigate(['/login/openaire']); + //this.router.navigate(['/login/openaire']); + this.oauth2DialogService.login(this.getOpenAireUrl()).pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (result !== undefined) { + this.openaireLoginUser(result.oauthCode, result.oauthState); + } + }); } public configurableLogin(provider: ConfigurableProvider) { @@ -81,7 +132,13 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn } public zenodoLogin() { - this.router.navigate(['/login/external/zenodo']); + //this.router.navigate(['/login/external/zenodo']); + this.oauth2DialogService.login(this.getZenodoUrl()).pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (result !== undefined) { + this.zenodoLoginUser(result.oauthCode); + } + }); } public hasFacebookOauth(): boolean { @@ -166,12 +223,7 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn (googleUser) => { const id_token = googleUser.getAuthResponse().id_token; if (id_token) { - this.authService.login({ ticket: id_token, provider: AuthProvider.Google }) - .pipe(takeUntil(this._destroyed)) - .subscribe( - res => this.loginService.onLogInSuccess(res, this.returnUrl), - error => this.loginService.onLogInError(error) - ); + this.authLogin({ ticket: id_token, provider: AuthProvider.Google }); } }, (error) => { }); @@ -192,12 +244,7 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn public facebookLogin() { FB.login((response: any) => { if (response.status === 'connected' || 'not_authorized') { - this.authService.login({ ticket: response.authResponse.accessToken, provider: AuthProvider.Facebook }) - .pipe(takeUntil(this._destroyed)) - .subscribe( - res => this.loginService.onLogInSuccess(res, this.returnUrl), - error => this.loginService.onLogInError(error) - ); + this.authLogin({ ticket: response.authResponse.accessToken, provider: AuthProvider.Facebook }); } }, { scope: 'email' }); } @@ -205,4 +252,144 @@ export class LoginComponent extends BaseComponent implements OnInit, AfterViewIn 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.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}) + ); + } else { + this.authService.login(loginInfo) + .pipe(takeUntil(this._destroyed)) + .subscribe( + res => this.loginService.onLogInSuccess(res, this.returnUrl), + error => this.loginService.onLogInError(error) + ); + } + } } diff --git a/dmp-frontend/src/app/ui/auth/login/login.module.ts b/dmp-frontend/src/app/ui/auth/login/login.module.ts index 74b78a5fb..160a28e16 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.module.ts +++ b/dmp-frontend/src/app/ui/auth/login/login.module.ts @@ -12,6 +12,7 @@ import { ConfigurableProvidersService } from '@app/ui/auth/login/utilities/confi import { LoginService } from '@app/ui/auth/login/utilities/login.service'; import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; +import { MergeLoginService } from './utilities/merge-login.service'; import { ZenodoLoginComponent } from './zenodo-login/zenodo-login.component'; @NgModule({ @@ -34,6 +35,6 @@ import { ZenodoLoginComponent } from './zenodo-login/zenodo-login.component'; exports: [ LoginComponent ], - providers: [LoginService, ConfigurableProvidersService] + providers: [LoginService, MergeLoginService, ConfigurableProvidersService] }) export class LoginModule { } diff --git a/dmp-frontend/src/app/ui/auth/login/openaire-login/openaire-login.component.ts b/dmp-frontend/src/app/ui/auth/login/openaire-login/openaire-login.component.ts index f54db7cc6..cc5acc9e7 100644 --- a/dmp-frontend/src/app/ui/auth/login/openaire-login/openaire-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/openaire-login/openaire-login.component.ts @@ -31,9 +31,10 @@ export class OpenAireLoginComponent extends BaseComponent implements OnInit { this.route.queryParams .pipe(takeUntil(this._destroyed)) .subscribe((params: Params) => { - const returnUrlFromParams = params['returnUrl']; - if (returnUrlFromParams) { this.returnUrl = returnUrlFromParams; } - if (!params['code']) { this.openaireAuthorize(); } else { this.openaireLoginUser(params['code'], params['state']) } + // const returnUrlFromParams = params['returnUrl']; + // if (returnUrlFromParams) { this.returnUrl = returnUrlFromParams; } + // if (!params['code']) { this.openaireAuthorize(); } else { this.openaireLoginUser(params['code'], params['state']) } + this.router.navigate(['/oauth2'], {queryParams: params}); }) } diff --git a/dmp-frontend/src/app/ui/auth/login/orcid-login/orcid-login.component.ts b/dmp-frontend/src/app/ui/auth/login/orcid-login/orcid-login.component.ts index bfa846180..fc477826b 100644 --- a/dmp-frontend/src/app/ui/auth/login/orcid-login/orcid-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/orcid-login/orcid-login.component.ts @@ -1,7 +1,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; -import { ActivatedRoute, Params } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { AuthProvider } from '@app/core/common/enum/auth-provider'; import { OrcidUser } from '@app/core/model/orcid/orcidUser'; import { AuthService } from '@app/core/services/auth/auth.service'; @@ -28,7 +28,8 @@ export class OrcidLoginComponent extends BaseComponent implements OnInit { private authService: AuthService, private loginService: LoginService, private httpClient: HttpClient, - private configurationService: ConfigurationService + private configurationService: ConfigurationService, + private router: Router ) { super(); this.orcidUser = new OrcidUser; @@ -38,9 +39,10 @@ export class OrcidLoginComponent extends BaseComponent implements OnInit { this.route.queryParams .pipe(takeUntil(this._destroyed)) .subscribe((params: Params) => { - const returnUrl = params['returnUrl']; - if (returnUrl) { this.returnUrl = returnUrl; } - if (!params['code']) { this.orcidAccessGetAuthCode(); } else { this.orcidLogin(params['code']); } + // const returnUrl = params['returnUrl']; + // if (returnUrl) { this.returnUrl = returnUrl; } + // if (!params['code']) { this.orcidAccessGetAuthCode(); } else { this.orcidLogin(params['code']); } + this.router.navigate(['/oauth2'], {queryParams: params}); }); } diff --git a/dmp-frontend/src/app/ui/auth/login/twitter-login/twitter-login.component.ts b/dmp-frontend/src/app/ui/auth/login/twitter-login/twitter-login.component.ts index 2fe80b094..a15fefe2c 100644 --- a/dmp-frontend/src/app/ui/auth/login/twitter-login/twitter-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/twitter-login/twitter-login.component.ts @@ -1,6 +1,6 @@ import { HttpHeaders } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Params } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { AuthProvider } from '@app/core/common/enum/auth-provider'; import { AuthService } from '@app/core/services/auth/auth.service'; import { BaseHttpService } from '@app/core/services/http/base-http.service'; @@ -26,7 +26,8 @@ export class TwitterLoginComponent extends BaseComponent implements OnInit { private authService: AuthService, private httpClient: BaseHttpService, private loginService: LoginService, - private configurationService: ConfigurationService + private configurationService: ConfigurationService, + private router: Router ) { super(); } @@ -35,9 +36,10 @@ export class TwitterLoginComponent extends BaseComponent implements OnInit { this.route.queryParams .pipe(takeUntil(this._destroyed)) .subscribe((params: Params) => { - const returnUrl = params['returnUrl']; - if (returnUrl) { this.returnUrl = returnUrl; } - if (!params['oauth_token'] && !params['oauth_verifier']) { this.twitterAuthorize(); } else { this.twitterLogin(params['oauth_token'], params['oauth_verifier']); } + // const returnUrl = params['returnUrl']; + // if (returnUrl) { this.returnUrl = returnUrl; } + // if (!params['oauth_token'] && !params['oauth_verifier']) { this.twitterAuthorize(); } else { this.twitterLogin(params['oauth_token'], params['oauth_verifier']); } + this.router.navigate(['/oauth2'], {queryParams: params}); }); } diff --git a/dmp-frontend/src/app/ui/auth/login/utilities/merge-login.service.ts b/dmp-frontend/src/app/ui/auth/login/utilities/merge-login.service.ts new file mode 100644 index 000000000..7ca95970a --- /dev/null +++ b/dmp-frontend/src/app/ui/auth/login/utilities/merge-login.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { UserMergeRequestModel } from '@app/core/model/merge/user-merge-request'; +import { Observable, Subject } from 'rxjs'; + +@Injectable() +export class MergeLoginService { + private serviceStore = new Subject(); + + getObservable(): Observable { + return this.serviceStore.asObservable(); + } + + setRequest(request: UserMergeRequestModel) { + this.serviceStore.next(request); + } +} diff --git a/dmp-frontend/src/app/ui/auth/login/zenodo-login/zenodo-login.component.ts b/dmp-frontend/src/app/ui/auth/login/zenodo-login/zenodo-login.component.ts index b58a77974..17a260e1d 100644 --- a/dmp-frontend/src/app/ui/auth/login/zenodo-login/zenodo-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/zenodo-login/zenodo-login.component.ts @@ -1,7 +1,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; -import { ActivatedRoute, Params } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { AuthProvider } from '@app/core/common/enum/auth-provider'; import { OrcidUser } from '@app/core/model/orcid/orcidUser'; import { AuthService } from '@app/core/services/auth/auth.service'; @@ -29,7 +29,8 @@ export class ZenodoLoginComponent extends BaseComponent implements OnInit { private authService: AuthService, private loginService: LoginService, private httpClient: HttpClient, - private configurationService: ConfigurationService + private configurationService: ConfigurationService, + private router: Router ) { super(); this.zenodoToken = new ZenodoToken; @@ -39,9 +40,10 @@ export class ZenodoLoginComponent extends BaseComponent implements OnInit { this.route.queryParams .pipe(takeUntil(this._destroyed)) .subscribe((params: Params) => { - const returnUrl = params['returnUrl']; - if (returnUrl) { this.returnUrl = returnUrl; } - if (!params['code']) { this.zenodoAccessGetAuthCode(); } else { this.zenodoLogin(params['code']); } + // const returnUrl = params['returnUrl']; + // if (returnUrl) { this.returnUrl = returnUrl; } + // if (!params['code']) { this.zenodoAccessGetAuthCode(); } else { this.zenodoLogin(params['code']); } + this.router.navigate(['/oauth2'], {queryParams: params}); }); } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index f54f3ae64..2e93d9bb8 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -526,9 +526,9 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { showOauth2Dialog(url: string, dmp: DmpOverviewModel) { this.oauth2DialogService.login(url) .pipe(takeUntil(this._destroyed)) - .subscribe(code => { - if (!isNullOrUndefined(code)) { - this.userService.registerDOIToken(code, this.configurationService.app + 'oauth2') + .subscribe(result => { + if (result.oauthCode !== undefined && result.oauthCode !== null) { + this.userService.registerDOIToken(result.oauthCode, this.configurationService.app + 'oauth2') .pipe(takeUntil(this._destroyed)) .subscribe(() => { this.hasDOIToken = true; diff --git a/dmp-frontend/src/app/ui/misc/oauth2-dialog/oauth2-dialog.component.ts b/dmp-frontend/src/app/ui/misc/oauth2-dialog/oauth2-dialog.component.ts index c73a6c673..346afc5d6 100644 --- a/dmp-frontend/src/app/ui/misc/oauth2-dialog/oauth2-dialog.component.ts +++ b/dmp-frontend/src/app/ui/misc/oauth2-dialog/oauth2-dialog.component.ts @@ -24,7 +24,7 @@ export class Oauth2DialogComponent extends BaseComponent implements OnInit{ this.route.queryParams.pipe(takeUntil(this._destroyed)) .subscribe((params: Params) => { const url = params['url']; - if (!params['code']) { this.loadUrl(url) } else { this.sendCode(params['code']); } + if (!params['code'] && (!params['oauth_token'] && !params['oauth_verifier'])) { this.loadUrl(url) } else { this.sendCode(params); } }); } @@ -32,8 +32,16 @@ export class Oauth2DialogComponent extends BaseComponent implements OnInit{ window.location.href = url; } - private sendCode(code: string) { - localStorage.setItem('oauthCode', code); + private sendCode(params: Params) { + if (params['code']) { + localStorage.setItem('oauthCode', params['code']); + } + if (params['state']) { + localStorage.setItem('oauthState', params['state']); + } + if (params['oauth_token'] && params['oauth_verifier']) { + localStorage.setItem('oauthObject', JSON.stringify({oauth_token: params['oauth_token'], oauth_verifier: params['oauth_verifier']})); + } window.close(); } diff --git a/dmp-frontend/src/app/ui/misc/oauth2-dialog/service/oauth2-dialog.service.ts b/dmp-frontend/src/app/ui/misc/oauth2-dialog/service/oauth2-dialog.service.ts index 14491196b..13455de5c 100644 --- a/dmp-frontend/src/app/ui/misc/oauth2-dialog/service/oauth2-dialog.service.ts +++ b/dmp-frontend/src/app/ui/misc/oauth2-dialog/service/oauth2-dialog.service.ts @@ -8,7 +8,7 @@ import { takeUntil } from 'rxjs/operators'; @Injectable() export class Oauth2DialogService extends BaseService{ - private code: BehaviorSubject = new BehaviorSubject(undefined); + private code: BehaviorSubject = new BehaviorSubject(undefined); constructor(private configurationService: ConfigurationService) { super(); @@ -18,13 +18,29 @@ export class Oauth2DialogService extends BaseService{ this.code.next(code); } - public login(url: string): Observable { + public login(url: string): Observable { const windows = window.open(this.configurationService.app + 'oauth2?url=' + encodeURIComponent(url) ,'', `height=500px,width=500px,top=${(window.screen.height / 2) - 200}px,left=${(window.screen.width / 2) - 200}px`); const sub = interval(300).pipe(takeUntil(this._destroyed)).subscribe(() => { if (windows.closed) { - const oauthCode = localStorage.getItem('oauthCode'); - localStorage.removeItem('oauthCode'); - this.code.next(oauthCode); + let oauthCode; + let oauthState; + let oauthToken; + let oauthVerifier; + if (localStorage.getItem('oauthCode')) { + oauthCode = localStorage.getItem('oauthCode'); + localStorage.removeItem('oauthCode'); + } + if (localStorage.getItem('oauthState')) { + oauthState = localStorage.getItem('oauthState'); + localStorage.removeItem('oauthState'); + } + if (localStorage.getItem('oauthObject')) { + const oauthObject = JSON.parse(localStorage.getItem('oauthObject')); + localStorage.removeItem('oauthObject'); + oauthToken = oauthObject.oauth_token; + oauthVerifier = oauthObject.oauth_verifier; + } + this.code.next({oauthCode: oauthCode, oauthState: oauthState, oauthToken: oauthToken, oauthVerifier: oauthVerifier}); sub.unsubscribe(); } }); diff --git a/dmp-frontend/src/app/ui/user-profile/add-account/add-account-dialog.component.html b/dmp-frontend/src/app/ui/user-profile/add-account/add-account-dialog.component.html index b726f2564..2478e5925 100644 --- a/dmp-frontend/src/app/ui/user-profile/add-account/add-account-dialog.component.html +++ b/dmp-frontend/src/app/ui/user-profile/add-account/add-account-dialog.component.html @@ -3,16 +3,18 @@

{{'USER-PROFILE.ACTIONS.LINK-NEW-ACCOUNT' | translate}}

close - - +
+
+ + +
+
+ diff --git a/dmp-frontend/src/app/ui/user-profile/add-account/add-account-dialog.component.ts b/dmp-frontend/src/app/ui/user-profile/add-account/add-account-dialog.component.ts index 498e17c9b..fe2ffbb76 100644 --- a/dmp-frontend/src/app/ui/user-profile/add-account/add-account-dialog.component.ts +++ b/dmp-frontend/src/app/ui/user-profile/add-account/add-account-dialog.component.ts @@ -1,6 +1,8 @@ import { Component, Inject, OnInit } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { UserMergeRequestModel } from '@app/core/model/merge/user-merge-request'; +import { MergeLoginService } from '@app/ui/auth/login/utilities/merge-login.service'; import { DatasetDescriptionFormEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model'; @Component({ @@ -13,8 +15,11 @@ export class AddAccountDialogComponent implements OnInit { datasetProfileDefinitionModel: DatasetDescriptionFormEditorModel; datasetProfileDefinitionFormGroup: FormGroup; progressIndication = false; + public hasEmail = true; + private request: UserMergeRequestModel; constructor( + private mergeLoginService: MergeLoginService, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any ) { @@ -22,11 +27,21 @@ export class AddAccountDialogComponent implements OnInit { } ngOnInit(): void { - + this.mergeLoginService.getObservable().subscribe(result => { + if (result !== undefined) { + if (!(result.email !== undefined && result.email !== null)) { + this.request = result; + this.hasEmail = false; + } else { + this.dialogRef.close(result); + } + } + }); } add(): void { - this.dialogRef.close(true); + this.request.email = 'email'; + this.dialogRef.close(this.request); } cancel(): void { diff --git a/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts b/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts index 80aa79033..d0826a26b 100644 --- a/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts +++ b/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts @@ -26,6 +26,7 @@ import { AddAccountDialogComponent } from './add-account/add-account-dialog.comp import { MatDialog } from '@angular/material'; import { UserCredentialModel } from '@app/core/model/user/user-credential'; import { AuthProvider } from '@app/core/common/enum/auth-provider'; +import { MergeEmailConfirmationService } from '@app/core/services/merge-email-confirmation/merge-email-confirmation.service'; const availableLanguages: any[] = require('../../../assets/resources/language.json'); @@ -71,7 +72,8 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes private configurationService: ConfigurationService, private oauth2DialogService: Oauth2DialogService, private dialog: MatDialog, - public enumUtils: EnumUtils + public enumUtils: EnumUtils, + private mergeEmailConfirmation: MergeEmailConfirmationService ) { super(); } ngOnInit() { @@ -234,9 +236,9 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes showOauth2Dialog(url: string) { this.oauth2DialogService.login(url) .pipe(takeUntil(this._destroyed)) - .subscribe(code => { - if (!isNullOrUndefined(code)) { - this.userService.registerDOIToken(code, this.configurationService.app + 'oauth2') + .subscribe(result => { + if (result.oauthCode !== undefined && result.oauthCode !== null) { + this.userService.registerDOIToken(result.oauthCode, this.configurationService.app + 'oauth2') .pipe(takeUntil(this._destroyed)) .subscribe(() => this.router.navigate(['/reload']).then(() => this.router.navigate(['/profile']))); } @@ -263,6 +265,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { if (result) { + this.mergeEmailConfirmation.sendConfirmationEmail(result); } }); }