Skip to content

Commit 6b6219e

Browse files
milanmajchrakMajoBergervidiecanjm
authored
Iteration 5 (DSpace#426)
* by default only deploy to INSTANCE=5 * give more time for postgres init * add even more time * Update action.yml (DSpace#405) Run import from main branch * ufal/fe-update-json-messages Added missing tranlates and updated messages after running the script * ufal/fe-initiated-login-not-redirecting-from-collection Redirect to login with `redirectUrl` param because it is lost after click on `local` login button. (DSpace#404) * [devOps] add dspace commands after import * ufal/fe-add-default-static-pages (DSpace#406) * Added static pages from the lindat git * Fixed redirection and created safeHtml pipe. * Could redirect out of namespace url, small refactoring. * Updated tests. * Added images into the static pages. * ufal/fe-shibboleth-validate-emails * Encoded query params (DSpace#407) * placeholder configs to be mounted into docker * change entrypoint so that containers has less logs and restarts (DSpace#412) * ufal/fe-get-user-ip-address (DSpace#420) * The clients IP address is fetched from the BE API. * Replace LegacyBitstreamUrlResolver by BitstreamBreadcrumbResolver because the first one throws errors to the console. * ufal/fe-fix-static-page-redirect (DSpace#421) * Fixed static page redirects. * Refactored processing links. * ufal/fe-download-bitstream-back-to-item (DSpace#423) * Separated toggling of DiscoJuice popup from the workign with redirect URL * The downloading page is loaded before downloading. * Login redirect works. * Removed storing cookies in the aai.js --------- Co-authored-by: MajoBerger <88670521+MajoBerger@users.noreply.github.com> Co-authored-by: Jozef Misutka <332350+vidiecan@users.noreply.github.com> Co-authored-by: jm <jm@maz> Co-authored-by: MajoBerger <marian.berger@dataquest.sk>
1 parent 6ff0f0a commit 6b6219e

6 files changed

Lines changed: 119 additions & 35 deletions

File tree

src/app/bitstream-page/bitstream-page-routing.module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations';
4747
// component: BitstreamDownloadPageComponent,
4848
resolve: {
4949
bitstream: BitstreamPageResolver,
50-
breadcrumb: LegacyBitstreamUrlResolver
50+
breadcrumb: BitstreamBreadcrumbResolver
5151
},
5252
},
5353
{

src/app/bitstream-page/clarin-bitstream-download-page/clarin-bitstream-download-page.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ export class ClarinBitstreamDownloadPageComponent implements OnInit {
126126
// bitstreamURL = 'http://localhost:8080/server/api/core/bitstreams/d9a41f84-a470-495a-8821-20e0a18e9276/content';
127127
if ((isAuthorized || isAuthorizedByClarin) && isLoggedIn && isNotEmpty(fileLink)) {
128128
this.downloadStatus.next(RequestEntryState.Success);
129-
this.hardRedirectService.redirect(fileLink);
129+
window.location.replace(fileLink);
130130
} else if ((isAuthorized || isAuthorizedByClarin) && !isLoggedIn) {
131131
this.downloadStatus.next(RequestEntryState.Success);
132-
this.hardRedirectService.redirect(bitstreamURL);
132+
window.location.replace(bitstreamURL);
133133
} else if (!(isAuthorized || isAuthorizedByClarin) && isLoggedIn &&
134134
this.downloadStatus.value === RequestEntryState.Error) {
135135
// this.downloadStatus is `ERROR` - no CLARIN exception is thrown up

src/app/bitstream-page/clarin-license-agreement-page/clarin-license-agreement-page.component.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ClarinUserMetadata } from '../../core/shared/clarin/clarin-user-metadat
88
import { getFirstCompletedRemoteData, getFirstSucceededRemoteListPayload } from '../../core/shared/operators';
99
import { RequestParam } from '../../core/cache/models/request-param.model';
1010
import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
11-
import { PostRequest } from '../../core/data/request.models';
11+
import { GetRequest, PostRequest } from '../../core/data/request.models';
1212
import { EPerson } from '../../core/eperson/models/eperson.model';
1313
import { AuthService } from '../../core/auth/auth.service';
1414
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model';
@@ -384,9 +384,29 @@ export class ClarinLicenseAgreementPageComponent implements OnInit {
384384
);
385385
}
386386

387+
/**
388+
* Load the user IP Address by API
389+
* */
387390
private loadIPAddress() {
388-
this.http.get('http://api.ipify.org/?format=json').subscribe((res: any) => {
389-
this.ipAddress$.next(res.ip);
391+
const requestId = this.requestService.generateRequestId();
392+
393+
const url = this.halService.getRootHref() + '/userinfo/ipaddress';
394+
const getRequest = new GetRequest(requestId, url);
395+
// Send GET request
396+
this.requestService.send(getRequest);
397+
// Get response
398+
const response = this.rdbService.buildFromRequestUUID(requestId);
399+
response
400+
.pipe(getFirstCompletedRemoteData())
401+
.subscribe((responseRD$: RemoteData<IPAddress>) => {
402+
if (hasFailed(responseRD$.state)) {
403+
this.error$.value.push('Cannot load the IP Address');
404+
return;
405+
}
406+
if (isEmpty(responseRD$?.payload)) {
407+
return;
408+
}
409+
this.ipAddress$.next(responseRD$?.payload?.ipAddress);
390410
});
391411
}
392412

@@ -411,3 +431,7 @@ export class ClarinLicenseAgreementPageComponent implements OnInit {
411431
this.helpDesk$ = this.configurationDataService.findByPropertyName(HELP_DESK_PROPERTY);
412432
}
413433
}
434+
435+
interface IPAddress {
436+
ipAddress: string;
437+
}

src/app/shared/log-in/methods/password/log-in-password.component.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export class LogInPasswordComponent implements OnInit {
138138

139139
// Load `dspace.ui.url` into `baseUrl` property.
140140
await this.assignBaseUrl();
141+
this.toggleDiscojuiceLogin();
141142
void this.setUpRedirectUrl();
142143
}
143144

@@ -155,13 +156,14 @@ export class LogInPasswordComponent implements OnInit {
155156
}
156157

157158
// Store the `redirectUrl` value from the url and then remove that value from url.
158-
if (isNotEmpty(this.route.snapshot.queryParams?.redirectUrl)) {
159-
// Overwrite `this.redirectUrl` only if it's not stored in the authService `redirectUrl` property.
160-
if (isEmpty(this.redirectUrl)) {
161-
this.redirectUrl = this.route.snapshot.queryParams?.redirectUrl;
162-
}
163-
} else {
164-
// Pop up discojuice login e.g. when the token is expired or the user is trying to download restricted bitstream.
159+
// Overwrite `this.redirectUrl` only if it's not stored in the authService `redirectUrl` property.
160+
if (isEmpty(this.redirectUrl)) {
161+
this.redirectUrl = this.route.snapshot.queryParams?.redirectUrl;
162+
}
163+
}
164+
165+
private toggleDiscojuiceLogin() {
166+
if (isEmpty(this.route.snapshot.queryParams?.redirectUrl)) {
165167
this.popUpDiscoJuiceLogin();
166168
}
167169
}
@@ -191,10 +193,16 @@ export class LogInPasswordComponent implements OnInit {
191193
email.trim();
192194
password.trim();
193195

194-
// Local authentication redirects to /login page and the user should be redirected to the page from where
195-
// was the login initiated.
196196
if (!this.isStandalonePage || isNotEmpty(this.redirectUrl)) {
197-
this.authService.setRedirectUrl(this.redirectUrl.replace(this.baseUrl, ''));
197+
// Create a URLSearchParams object
198+
const urlParams = new URLSearchParams(this.redirectUrl.split('?')[1]);
199+
// Get the value of the 'redirectUrl' parameter
200+
let redirectUrl = urlParams.get('redirectUrl');
201+
if (isEmpty(redirectUrl)) {
202+
redirectUrl = this.redirectUrl;
203+
}
204+
205+
this.authService.setRedirectUrl(redirectUrl.replace(this.baseUrl, ''));
198206
} else {
199207
this.authService.setRedirectUrlIfNotSet('/');
200208
}

src/app/static-page/static-page-routing-paths.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
*/
44
export const STATIC_PAGE_PATH = 'static';
55
export const STATIC_FILES_PROJECT_PATH = 'static-files';
6+
export const HTML_SUFFIX = '.html';
67
export const STATIC_FILES_DEFAULT_ERROR_PAGE_PATH = STATIC_FILES_PROJECT_PATH + '/' + 'error.html';

src/app/static-page/static-page.component.ts

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import { BehaviorSubject, firstValueFrom } from 'rxjs';
44
import { Router } from '@angular/router';
55
import { isEmpty, isNotEmpty } from '../shared/empty.util';
66
import { LocaleService } from '../core/locale/locale.service';
7-
import { STATIC_FILES_DEFAULT_ERROR_PAGE_PATH, STATIC_FILES_PROJECT_PATH } from './static-page-routing-paths';
7+
import {
8+
HTML_SUFFIX,
9+
STATIC_FILES_DEFAULT_ERROR_PAGE_PATH,
10+
STATIC_FILES_PROJECT_PATH, STATIC_PAGE_PATH
11+
} from './static-page-routing-paths';
812
import { APP_CONFIG, AppConfig } from '../../config/app-config.interface';
913

1014
/**
@@ -39,6 +43,8 @@ export class StaticPageComponent implements OnInit {
3943
// Compose url
4044
url = STATIC_FILES_PROJECT_PATH;
4145
url += isEmpty(language) ? '/' + this.htmlFileName : '/' + language + '/' + this.htmlFileName;
46+
// Add `.html` suffix to get the current html file
47+
url = url.endsWith(HTML_SUFFIX) ? url : url + HTML_SUFFIX;
4248
let potentialContent = await firstValueFrom(this.htmlContentService.fetchHtmlContent(url));
4349
if (isNotEmpty(potentialContent)) {
4450
this.htmlContent.next(potentialContent);
@@ -57,25 +63,70 @@ export class StaticPageComponent implements OnInit {
5763
await this.loadErrorPage();
5864
}
5965

60-
processLinks(e) {
61-
const element: HTMLElement = e.target;
62-
if (element.nodeName === 'A') {
63-
e.preventDefault();
64-
const href = element.getAttribute('href')?.replace('/', '');
65-
let redirectUrl = window.location.origin + this.appConfig.ui.nameSpace + '/static/';
66-
// Start with `#` - redirect to the fragment
67-
if (href.startsWith('#')) {
68-
redirectUrl += this.htmlFileName + href;
69-
} else if (href.startsWith('.')) {
70-
// Redirect using namespace e.g. `./test.html` -> `<UI_PATH>/namespace/static/test.html`
71-
redirectUrl += href.replace('.', '') + '.html';
72-
} else {
73-
// Redirect without using namespace e.g. `/test.html` -> `<UI_PATH>/test.html`
74-
redirectUrl = redirectUrl.replace(this.appConfig.ui.nameSpace, '') + href;
75-
}
76-
// Call redirect
77-
window.location.href = redirectUrl;
66+
/**
67+
* Handle click on links in the static page.
68+
* @param event
69+
*/
70+
processLinks(event: Event): void {
71+
const targetElement = event.target as HTMLElement;
72+
73+
if (targetElement.nodeName !== 'A') {
74+
return;
7875
}
76+
77+
event.preventDefault();
78+
79+
const href = targetElement.getAttribute('href');
80+
const { nameSpace } = this.appConfig.ui;
81+
const namespacePrefix = nameSpace === '/' ? '' : nameSpace;
82+
83+
const redirectUrl = this.composeRedirectUrl(href, namespacePrefix);
84+
85+
if (this.isFragmentLink(href)) {
86+
this.redirectToFragment(redirectUrl, href);
87+
} else if (this.isRelativeLink(href)) {
88+
this.redirectToRelativeLink(redirectUrl, href);
89+
} else if (this.isExternalLink(href)) {
90+
this.redirectToExternalLink(href);
91+
} else {
92+
this.redirectToAbsoluteLink(redirectUrl, href, namespacePrefix);
93+
}
94+
}
95+
96+
private composeRedirectUrl(href: string | null, namespacePrefix: string): string {
97+
const staticPagePath = STATIC_PAGE_PATH;
98+
const baseUrl = new URL(window.location.origin);
99+
baseUrl.pathname = `${namespacePrefix}/${staticPagePath}/`;
100+
return baseUrl.href;
101+
}
102+
103+
private isFragmentLink(href: string | null): boolean {
104+
return href?.startsWith('#') ?? false;
105+
}
106+
107+
private redirectToFragment(redirectUrl: string, href: string | null): void {
108+
window.location.href = `${redirectUrl}${this.htmlFileName}${href}`;
109+
}
110+
111+
private isRelativeLink(href: string | null): boolean {
112+
return href?.startsWith('.') ?? false;
113+
}
114+
115+
private redirectToRelativeLink(redirectUrl: string, href: string | null): void {
116+
window.location.href = new URL(href, redirectUrl).href;
117+
}
118+
119+
private isExternalLink(href: string | null): boolean {
120+
return (href?.startsWith('http') || href?.startsWith('www')) ?? false;
121+
}
122+
123+
private redirectToExternalLink(href: string | null): void {
124+
window.location.replace(href);
125+
}
126+
127+
private redirectToAbsoluteLink(redirectUrl: string, href: string | null, namespacePrefix: string): void {
128+
const absoluteUrl = new URL(href, redirectUrl.replace(namespacePrefix, ''));
129+
window.location.href = absoluteUrl.href;
79130
}
80131

81132
/**

0 commit comments

Comments
 (0)