Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lmendoza/9422 email domains interstitial oauth #2386

Merged
merged 4 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions guides/example-tx-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,11 @@ filters:
source_file: src/locale/properties/account/account.en.properties
# path expression to translation files, must contain <lang> placeholder
translation_files_expression: src/locale/properties/account/account.<lang>.properties

- filter_type: file
# all supported i18n types: https://docs.transifex.com/formats
file_format: UNICODEPROPERTIES
source_language: en
source_file: src/locale/properties/interstitials/interstitials.en.properties
# path expression to translation files, must contain <lang> placeholder
translation_files_expression: src/locale/properties/interstitials/interstitials.<lang>.properties
3 changes: 3 additions & 0 deletions src/app/authorize/authorize.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { AuthorizeRoutingModule } from './authorize-routing.module'
import { OauthErrorComponent } from './components/oauth-error/oauth-error.component'
import { AuthorizeComponent } from './pages/authorize/authorize.component'
import { FormAuthorizeComponent } from './components/form-authorize/form-authorize.component'
import { ShareEmailsDomainsComponent } from '../cdk/interstitials/share-emails-domains/share-emails-domains.component'
import { InterstitialsModule } from '../cdk/interstitials/interstitials.module'

@NgModule({
declarations: [
Expand All @@ -35,6 +37,7 @@ import { FormAuthorizeComponent } from './components/form-authorize/form-authori
TrustedIndividualsDropdownModule,
InfoDropDownModule,
MatProgressBarModule,
InterstitialsModule
],
})
export class AuthorizeModule {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'
import {
Component,
EventEmitter,
Inject,
Input,
OnDestroy,
OnInit,
Output,
} from '@angular/core'
import { Router } from '@angular/router'
import { forkJoin, Observable, Subject } from 'rxjs'
import { catchError, map, take, takeUntil } from 'rxjs/operators'
Expand Down Expand Up @@ -31,6 +39,8 @@ import { Title } from '@angular/platform-browser'
preserveWhitespaces: true,
})
export class FormAuthorizeComponent implements OnInit, OnDestroy {
@Output() redirectUrl = new EventEmitter<string>()
@Output() organizationName = new EventEmitter<string>()
environment = environment
$destroy: Subject<boolean> = new Subject<boolean>()
orcidUrl: string
Expand All @@ -57,7 +67,9 @@ export class FormAuthorizeComponent implements OnInit, OnDestroy {
private _errorHandler: ErrorHandlerService,
private _trustedIndividuals: TrustedIndividualsService,
private _titleService: Title
) {
) {}

ngOnInit(): void {
this._platformInfo
.get()
.pipe(take(1))
Expand All @@ -73,6 +85,8 @@ export class FormAuthorizeComponent implements OnInit, OnDestroy {
this.loadingUserInfo = false
this.loadingTrustedIndividuals = false
this.oauthRequest = userInfo.oauthSession
this.organizationName.emit(this.oauthRequest.clientName)
console.log('this ', this.oauthRequest.clientName)
if (userInfo.loggedIn) {
this.userName = userInfo.displayName
this.orcidUrl = userInfo.effectiveOrcidUrl
Expand All @@ -92,9 +106,7 @@ export class FormAuthorizeComponent implements OnInit, OnDestroy {
this._trustedIndividuals.getTrustedIndividuals().subscribe((value) => {
this.trustedIndividuals = value
})
}

ngOnInit(): void {
setTimeout(() => {
this._titleService.setTitle(
this.authorizeAccessFor +
Expand Down Expand Up @@ -141,8 +153,8 @@ export class FormAuthorizeComponent implements OnInit, OnDestroy {
)
)
.subscribe(
() => (this.window as any).outOfRouterNavigation(data.redirectUrl),
() => (this.window as any).outOfRouterNavigation(data.redirectUrl)
() => this.redirectUrl.next(data.redirectUrl),
() => this.redirectUrl.next(data.redirectUrl)
)
})
}
Expand Down
12 changes: 9 additions & 3 deletions src/app/authorize/pages/authorize/authorize.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@
>
<app-form-authorize
*ngIf="showAuthorizationComponent"
(redirectUrl)="handleRedirect($event)"
(organizationName)="organizationName = $event"
></app-form-authorize>
<app-oauth-error
*ngIf="!showAuthorizationComponent"
></app-oauth-error>
<app-share-emails-domains
*ngIf="showInterstital"
(finish)="finishRedirect()"
[userEmailsJson]="originalEmailsBackendCopy"
[organizationName]="organizationName"
></app-share-emails-domains>
<app-oauth-error *ngIf="showAuthorizationError"></app-oauth-error>
</mat-card>
</div>
</div>
Expand Down
66 changes: 63 additions & 3 deletions src/app/authorize/pages/authorize/authorize.component.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
import { Component } from '@angular/core'
import { Component, Inject } from '@angular/core'
import { cloneDeep } from 'lodash'
import { first, take, tap } from 'rxjs/operators'
import { PlatformInfo, PlatformInfoService } from 'src/app/cdk/platform-info'
import { WINDOW } from 'src/app/cdk/window'
import { UserService } from 'src/app/core'
import { RecordEmailsService } from 'src/app/core/record-emails/record-emails.service'
import { TogglzService } from 'src/app/core/togglz/togglz.service'
import { AssertionVisibilityString, EmailsEndpoint } from 'src/app/types'

@Component({
templateUrl: './authorize.component.html',
styleUrls: ['./authorize.component.scss'],
preserveWhitespaces: true,
})
export class AuthorizeComponent {
redirectUrl: string

platform: PlatformInfo
showAuthorizationComponent: boolean
showAuthorizationError: boolean
showInterstital: boolean
originalEmailsBackendCopy: EmailsEndpoint
userHasPrivateDomains = false
oauthDomainsInterstitialEnabled: boolean
organizationName: string

constructor(_user: UserService, private _platformInfo: PlatformInfoService) {
constructor(
_user: UserService,
private _platformInfo: PlatformInfoService,
private _recordEmails: RecordEmailsService,
private _togglz: TogglzService,
@Inject(WINDOW) private window: Window
) {
_user.getUserSession().subscribe((session) => {
if (session.oauthSession && session.oauthSession.error) {
this.showAuthorizationComponent = false
this.showAuthorizationError = true
} else {
this.showAuthorizationComponent = true
}
Expand All @@ -23,4 +43,44 @@ export class AuthorizeComponent {
this.platform = platformInfo
})
}

ngOnInit() {
this._togglz
.getStateOf('OAUTH_DOMAINS_INTERSTITIAL')
.pipe(take(1))
.subscribe((value) => {
this.oauthDomainsInterstitialEnabled = value
})
this._recordEmails
.getEmails()
.pipe(
tap((value) => {
this.originalEmailsBackendCopy = cloneDeep(value)
this.userHasPrivateDomains = this.userHasPrivateEmails(value)
}),
first()
)
.subscribe()
}

userHasPrivateEmails(value: EmailsEndpoint): boolean {
return !!value.emailDomains.find((domain) => domain.visibility !== 'PUBLIC')
}

handleRedirect(url: string) {
if (
url &&
this.userHasPrivateDomains &&
this.oauthDomainsInterstitialEnabled
) {
this.redirectUrl = url
this.showAuthorizationComponent = false
this.showInterstital = true
} else {
this.finishRedirect()
}
}
finishRedirect() {
;(this.window as any).outOfRouterNavigation(this.redirectUrl)
}
}
11 changes: 11 additions & 0 deletions src/app/cdk/info-panel/info-panel.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { NgModule } from '@angular/core'
import { CommonModule } from '@angular/common'
import { InfoPanelComponent } from './info-panel/info-panel.component'
import { MatIcon, MatIconModule } from '@angular/material/icon'

@NgModule({
declarations: [InfoPanelComponent],
imports: [CommonModule, MatIconModule],
exports: [InfoPanelComponent],
})
export class InfoPanelModule {}
10 changes: 10 additions & 0 deletions src/app/cdk/info-panel/info-panel/info-panel.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="info">
<div class="col">
<img src="/assets/vectors/check-window.svg" role="presentation" />
</div>
<div>
<p>
<ng-content></ng-content>
</p>
</div>
</div>
16 changes: 16 additions & 0 deletions src/app/cdk/info-panel/info-panel/info-panel.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.info {
padding: 16px;
margin-top: 16px;
margin-bottom: 16px;
border: solid 2px;
border-radius: 4px;
display: flex;

p {
margin: 0;
}
.col {
align-items: start;
padding-left: 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@use '@angular/material' as mat;
@import 'src/assets/scss/material.orcid-theme.scss';

@mixin theme($theme) {
$primary: map-get($theme, primary);
$accent: map-get($theme, accent);
$warn: map-get($theme, accent);
$foreground: map-get($theme, foreground);
$background: map-get($theme, background);

.info {
border-color: mat.get-color-from-palette(
$foreground,
'state-info-darkest'
) !important;
background-color: mat.get-color-from-palette(
$background,
'state-info-lightest'
) !important;
}
}

@include theme($orcid-app-theme);
21 changes: 21 additions & 0 deletions src/app/cdk/info-panel/info-panel/info-panel.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { InfoPanelComponent } from './info-panel.component';

describe('InfoPanelComponent', () => {
let component: InfoPanelComponent;
let fixture: ComponentFixture<InfoPanelComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [InfoPanelComponent]
});
fixture = TestBed.createComponent(InfoPanelComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
10 changes: 10 additions & 0 deletions src/app/cdk/info-panel/info-panel/info-panel.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Component } from '@angular/core';

@Component({
selector: 'app-info-panel',
templateUrl: './info-panel.component.html',
styleUrls: ['./info-panel.component.scss', './info-panel.component.scss-theme.scss']
})
export class InfoPanelComponent {

}
32 changes: 32 additions & 0 deletions src/app/cdk/interstitials/interstitials.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { NgModule } from '@angular/core'
import { CommonModule } from '@angular/common'
import { ShareEmailsDomainsComponent } from './share-emails-domains/share-emails-domains.component'
import { MatLegacyCardModule } from '@angular/material/legacy-card'
import { MatIconModule } from '@angular/material/icon'
import { MatDividerModule } from '@angular/material/divider'
import { InfoDropDownModule } from '../info-drop-down/info-drop-down.module'
import { MatProgressBarModule } from '@angular/material/progress-bar'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { MatCheckboxModule } from '@angular/material/checkbox'
import { MatLegacyCheckboxModule } from '@angular/material/legacy-checkbox'
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button'
import { InfoPanelModule } from '../info-panel/info-panel.module'

@NgModule({
declarations: [ShareEmailsDomainsComponent],
imports: [
CommonModule,
MatLegacyCardModule,
MatIconModule,
MatDividerModule,
InfoDropDownModule,
MatProgressBarModule,
ReactiveFormsModule,
FormsModule,
MatLegacyCheckboxModule,
MatButtonModule,
InfoPanelModule,
],
exports: [ShareEmailsDomainsComponent],
})
export class InterstitialsModule {}
Loading
Loading