Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
27d3c58
add referrer to pageview events
artlowel May 2, 2023
5aaa4ef
ensure the rel="noopener" attribute is only set when target="_blank" …
artlowel May 2, 2023
bd4dbcf
Merge branch 'add-referrer-to-pageview-event-7.0' into add-referrer-t…
artlowel May 2, 2023
f19daf5
Merge branch 'add-referrer-to-pageview-event-7.2' into add-referrer-t…
artlowel May 2, 2023
f44bdc9
fix an issue where the current page would be used instead of a third …
artlowel May 4, 2023
f8eb8e1
Merge branch 'add-referrer-to-pageview-event-7.0' into add-referrer-t…
artlowel May 30, 2023
2db6c96
Merge branch 'add-referrer-to-pageview-event-7.2' into add-referrer-t…
artlowel May 30, 2023
4717d6f
add referrer to pageview events
artlowel May 2, 2023
fcfdff7
ensure the rel="noopener" attribute is only set when target="_blank" …
artlowel May 2, 2023
3df0286
fix an issue where the current page would be used instead of a third …
artlowel May 4, 2023
5b37101
add the rel="noreferrer" attribute when target="_blank"
artlowel May 30, 2023
5723fcb
Merge branch 'add-referrer-to-pageview-event-7.0' into add-referrer-t…
artlowel May 30, 2023
ffdc7b3
Merge branch 'add-referrer-to-pageview-event-7.2' into add-referrer-t…
artlowel May 30, 2023
15493e2
Merge branch 'add-referrer-to-pageview-event-7.4' into add-referrer-t…
artlowel May 30, 2023
43e1e6d
add noreferrer to license link
artlowel Jun 1, 2023
d1dff05
fix lint error
artlowel Jun 1, 2023
42ba792
Merge branch 'add-referrer-to-pageview-event-7.0' into add-referrer-t…
artlowel Jun 1, 2023
f2cfab7
Merge branch 'add-referrer-to-pageview-event-7.2' into add-referrer-t…
artlowel Jun 1, 2023
ee04589
Merge branch 'add-referrer-to-pageview-event-7.4' into add-referrer-t…
artlowel Jun 1, 2023
8f536d3
Merge remote-tracking branch 'upstream/main' into add-referrer-to-pag…
artlowel Jun 6, 2023
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
68 changes: 68 additions & 0 deletions src/app/core/services/browser.referrer.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { of as observableOf } from 'rxjs';
import { RouteService } from './route.service';
import { BrowserReferrerService } from './browser.referrer.service';

describe(`BrowserReferrerService`, () => {
let service: BrowserReferrerService;
const documentReferrer = 'https://www.referrer.com';
const origin = 'https://www.dspace.org';
let routeService: RouteService;

beforeEach(() => {
routeService = {
getHistory: () => observableOf([])
} as any;
service = new BrowserReferrerService(
{ referrer: documentReferrer },
routeService,
{ getCurrentOrigin: () => origin } as any
);
});

describe(`getReferrer`, () => {
describe(`when the history is an empty`, () => {
beforeEach(() => {
spyOn(routeService, 'getHistory').and.returnValue(observableOf([]));
});

it(`should return document.referrer`, (done: DoneFn) => {
service.getReferrer().subscribe((emittedReferrer: string) => {
expect(emittedReferrer).toBe(documentReferrer);
done();
});
});
});

describe(`when the history only contains the current route`, () => {
beforeEach(() => {
spyOn(routeService, 'getHistory').and.returnValue(observableOf(['/current/route']));
});

it(`should return document.referrer`, (done: DoneFn) => {
service.getReferrer().subscribe((emittedReferrer: string) => {
expect(emittedReferrer).toBe(documentReferrer);
done();
});
});
});

describe(`when the history contains multiple routes`, () => {
const prevUrl = '/the/route/we/need';
beforeEach(() => {
spyOn(routeService, 'getHistory').and.returnValue(observableOf([
'/first/route',
'/second/route',
prevUrl,
'/current/route'
]));
});

it(`should return the last route before the current one combined with the origin from HardRedirectService`, (done: DoneFn) => {
service.getReferrer().subscribe((emittedReferrer: string) => {
expect(emittedReferrer).toBe(origin + prevUrl);
done();
});
});
});
});
});
54 changes: 54 additions & 0 deletions src/app/core/services/browser.referrer.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { ReferrerService } from './referrer.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { hasNoValue } from '../../shared/empty.util';
import { URLCombiner } from '../url-combiner/url-combiner';
import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { HardRedirectService } from './hard-redirect.service';
import { RouteService } from './route.service';

/**
* A service to determine the referrer
*
* The browser implementation will get the referrer from document.referrer, in the event that the
* previous page visited was not an angular URL. If it was, the route history in the store must be
* used, since document.referrer doesn't get updated on route changes
*/
@Injectable()
export class BrowserReferrerService extends ReferrerService {

constructor(
@Inject(DOCUMENT) protected document: any,
protected routeService: RouteService,
protected hardRedirectService: HardRedirectService,
) {
super();
}

/**
* Return the referrer
*
* Return the referrer URL based on the route history in the store. If there is no route history
* in the store yet, document.referrer will be used
*/
public getReferrer(): Observable<string> {
return this.routeService.getHistory().pipe(
map((history: string[]) => {
const currentURL = history[history.length - 1];
// if the current URL isn't set yet, or the only URL in the history is the current one,
// return document.referrer (note that that may be empty too, e.g. if you've just opened a
// new browser tab)
if (hasNoValue(currentURL) || history.every((url: string) => url === currentURL)) {
return this.document.referrer;
} else {
// reverse the history
const reversedHistory = [...history].reverse();
// and find the first URL that differs from the current one
const prevUrl = reversedHistory.find((url: string) => url !== currentURL);
return new URLCombiner(this.hardRedirectService.getCurrentOrigin(), prevUrl).toString();
}
})
);
}
}
15 changes: 15 additions & 0 deletions src/app/core/services/referrer.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

/**
* A service to determine the referrer, i.e. the previous URL that led the user to the current one
*/
@Injectable()
export abstract class ReferrerService {

/**
* Return the referrer
*/
abstract getReferrer(): Observable<string>;

}
34 changes: 34 additions & 0 deletions src/app/core/services/server.referrer.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ServerReferrerService } from './server.referrer.service';

describe(`ServerReferrerService`, () => {
let service: ServerReferrerService;
const referrer = 'https://www.referrer.com';

describe(`getReferrer`, () => {
describe(`when the referer header is set`, () => {
beforeEach(() => {
service = new ServerReferrerService({ headers: { referer: referrer }});
});

it(`should return the referer header`, (done: DoneFn) => {
service.getReferrer().subscribe((emittedReferrer: string) => {
expect(emittedReferrer).toBe(referrer);
done();
});
});
});

describe(`when the referer header is not set`, () => {
beforeEach(() => {
service = new ServerReferrerService({ headers: {}});
});

it(`should return an empty string`, (done: DoneFn) => {
service.getReferrer().subscribe((emittedReferrer: string) => {
expect(emittedReferrer).toBe('');
done();
});
});
});
});
});
31 changes: 31 additions & 0 deletions src/app/core/services/server.referrer.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ReferrerService } from './referrer.service';
import { Observable, of as observableOf } from 'rxjs';
import { Inject, Injectable } from '@angular/core';
import { REQUEST } from '@nguniversal/express-engine/tokens';

/**
* A service to determine the referrer
*
* The server implementation will get the referrer from the 'Referer' header of the request sent to
* the express server
*/
@Injectable()
export class ServerReferrerService extends ReferrerService {

constructor(
@Inject(REQUEST) protected request: any,
) {
super();
}

/**
* Return the referrer
*
* Return the 'Referer' header from the request, or an empty string if the header wasn't set
* (for consistency with the document.referrer property on the browser side)
*/
public getReferrer(): Observable<string> {
const referrer = this.request.headers.referer || '';
return observableOf(referrer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>
<a *ngIf="linkType != linkTypes.None"
[target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
<div>
<ds-themed-thumbnail [thumbnail]="dso?.thumbnail | async" [limitWidth]="false">
Expand Down Expand Up @@ -36,7 +36,7 @@ <h4 class="card-title" [innerHTML]="dsoTitle"></h4>
</p>
<div *ngIf="linkType != linkTypes.None" class="text-center">
<a [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="lead btn btn-primary viewButton">{{ 'search.results.view-result' | translate}}</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>
<a *ngIf="linkType != linkTypes.None"
[target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
<div>
<ds-themed-thumbnail [thumbnail]="dso?.thumbnail | async" [limitWidth]="false">
Expand Down Expand Up @@ -36,7 +36,7 @@ <h4 class="card-title" [innerHTML]="dsoTitle"></h4>
</p>
<div *ngIf="linkType != linkTypes.None" class="text-center">
<a [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="lead btn btn-primary viewButton">{{ 'search.results.view-result' | translate}}</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>
<a *ngIf="linkType != linkTypes.None"
[target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
<div>
<ds-themed-thumbnail [thumbnail]="dso?.thumbnail | async" [limitWidth]="false">
Expand Down Expand Up @@ -40,7 +40,7 @@ <h4 class="card-title" [innerHTML]="dsoTitle"></h4>
</p>
<div *ngIf="linkType != linkTypes.None" class="text-center">
<a [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="lead btn btn-primary viewButton">{{ 'search.results.view-result' | translate}}</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="row">
<div *ngIf="showThumbnails" class="col-3 col-md-2">
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out">
<ds-thumbnail [thumbnail]="dso?.thumbnail | async" [limitWidth]="true">
</ds-thumbnail>
Expand All @@ -15,7 +15,7 @@
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
<ds-truncatable [id]="dso.id">
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out"
[innerHTML]="dsoTitle"></a>
<span *ngIf="linkType == linkTypes.None"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="row">
<div *ngIf="showThumbnails" class="col-3 col-md-2">
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out">
<ds-thumbnail [thumbnail]="dso?.thumbnail | async" [limitWidth]="true">
</ds-thumbnail>
Expand All @@ -15,7 +15,7 @@
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
<ds-truncatable [id]="dso.id">
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out"
[innerHTML]="dsoTitle"></a>
<span *ngIf="linkType == linkTypes.None"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="row">
<div *ngIf="showThumbnails" class="col-3 col-md-2">
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer"
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" [attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out">
<ds-thumbnail [thumbnail]="dso?.thumbnail | async" [limitWidth]="true">
</ds-thumbnail>
Expand All @@ -13,7 +13,7 @@
<div [ngClass]="showThumbnails ? 'col-9' : 'col-md-12'">
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
<ds-truncatable [id]="dso.id">
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer"
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" [attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
[routerLink]="[itemPageRoute]" class="lead item-list-title dont-break-out"
[innerHTML]="dsoTitle"></a>
<span *ngIf="linkType == linkTypes.None"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>
<a *ngIf="linkType != linkTypes.None"
[target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
<div>
<ds-themed-thumbnail [thumbnail]="dso?.thumbnail | async" [limitWidth]="false">
Expand Down Expand Up @@ -42,7 +42,7 @@ <h4 class="card-title" [innerHTML]="dsoTitle"></h4>
</p>
<div *ngIf="linkType != linkTypes.None" class="text-center">
<a [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="lead btn btn-primary viewButton">{{ 'search.results.view-result' | translate}}</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>
<a *ngIf="linkType != linkTypes.None"
[target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
<div>
<ds-themed-thumbnail [thumbnail]="dso?.thumbnail | async" [limitWidth]="false">
Expand Down Expand Up @@ -35,7 +35,7 @@ <h4 class="card-title" [innerHTML]="dsoTitle"></h4>
</p>
<div *ngIf="linkType != linkTypes.None" class="text-center">
<a [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="lead btn btn-primary viewButton">{{ 'search.results.view-result' | translate}}</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</div>
<a *ngIf="linkType != linkTypes.None"
[target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
<div>
<ds-themed-thumbnail [thumbnail]="dso?.thumbnail | async" [limitWidth]="false">
Expand All @@ -30,7 +30,7 @@ <h4 class="card-title" [innerHTML]="dsoTitle"></h4>
</p>
<div *ngIf="linkType != linkTypes.None" class="text-center">
<a [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer" [routerLink]="[itemPageRoute]"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null" [routerLink]="[itemPageRoute]"
class="lead btn btn-primary viewButton">{{ 'search.results.view-result' | translate}}</a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="row">
<div *ngIf="showThumbnails" class="col-3 col-md-2">
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
[routerLink]="[itemPageRoute]" class="dont-break-out">
<ds-thumbnail [thumbnail]="dso?.thumbnail | async"
[defaultImage]="'assets/images/orgunit-placeholder.svg'"
Expand All @@ -21,7 +21,7 @@
<ds-themed-badges *ngIf="showLabel" [object]="dso" [context]="context"></ds-themed-badges>
<ds-truncatable [id]="dso.id">
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'"
rel="noopener noreferrer"
[attr.rel]="(linkType == linkTypes.ExternalLink) ? 'noopener noreferrer' : null"
[routerLink]="[itemPageRoute]" class="lead"
[innerHTML]="dsoTitle || ('orgunit.listelement.no-title' | translate)"></a>
<span *ngIf="linkType == linkTypes.None"
Expand Down
Loading