Skip to content

Commit 10e97a5

Browse files
committed
Merged dspace-cris-2025_02_x into task/dspace-cris-2025_02_x/DSC-2637
2 parents 3570457 + a350ba1 commit 10e97a5

File tree

52 files changed

+490
-87
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+490
-87
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dspace-angular",
3-
"version": "2024.02.03-SNAPSHOT",
3+
"version": "2024.02.04-SNAPSHOT",
44
"scripts": {
55
"ng": "ng",
66
"config:watch": "nodemon",
@@ -138,6 +138,7 @@
138138
"markdown-it": "^13.0.1",
139139
"mirador": "^3.4.3",
140140
"mirador-dl-plugin": "^0.13.0",
141+
"mirador-imagecropper": "^0.1.9",
141142
"mirador-share-plugin": "^0.16.0",
142143
"morgan": "^1.10.0",
143144
"ng2-file-upload": "5.0.0",

src/app/access-control/epeople-registry/eperson-form/eperson-form.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
307307
name: 'email',
308308
validators: {
309309
required: null,
310-
pattern: '^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$',
310+
pattern: '^\\s*[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}\\s*$',
311311
},
312312
required: true,
313313
errorMessages: {
@@ -426,7 +426,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
426426
},
427427
],
428428
},
429-
email: this.email.value,
429+
email: (this.email.value as string)?.trim(),
430430
canLogIn: this.canLogIn.value,
431431
requireCertificate: this.requireCertificate.value,
432432
};

src/app/app-routes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,12 @@ export const APP_ROUTES: Route[] = [
182182
canActivate: [authenticatedGuard, endUserAgreementCurrentUserGuard],
183183
},
184184
{
185-
path: 'standard-login',
185+
path: 'admin-only-login',
186186
loadChildren: () => import('./login-page/login-page-routes').then((m) => m.ROUTES),
187187
data: {
188188
isBackDoor: true,
189189
},
190-
canMatch: [() => !environment.auth.disableStandardLogin],
190+
canMatch: [() => environment.auth.isPasswordLoginEnabledForAdminsOnly],
191191
},
192192
{
193193
path: 'login',

src/app/app.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import { AuthInterceptor } from './core/auth/auth.interceptor';
5757
import { DspaceRestInterceptor } from './core/dspace-rest/dspace-rest.interceptor';
5858
import { LocaleInterceptor } from './core/locale/locale.interceptor';
5959
import { LogInterceptor } from './core/log/log.interceptor';
60+
import { schemaModels } from './core/metadata/schema-json-ld/schema-types/provide-schema';
6061
import {
6162
models,
6263
provideCore,
@@ -169,3 +170,4 @@ const metadataRepresentations = METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP;
169170
const startsWithDecoratorMap = STARTS_WITH_DECORATOR_MAP;
170171
const browseByDecoratorMap = BROWSE_BY_DECORATOR_MAP;
171172
const authMethodForDecoratorMap = AUTH_METHOD_FOR_DECORATOR_MAP;
173+
const schemaModelList = schemaModels;

src/app/core/metadata/schema-json-ld/schema-json-ld.service.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Inject,
44
Injectable,
55
} from '@angular/core';
6+
import { DomSanitizer } from '@angular/platform-browser';
67

78
import {
89
isEmpty,
@@ -20,7 +21,10 @@ import {
2021
export class SchemaJsonLDService {
2122
static scriptType = 'application/ld+json';
2223

23-
constructor(@Inject(DOCUMENT) private _document: Document) {}
24+
constructor(
25+
@Inject(DOCUMENT) private _document: Document,
26+
protected sanitizer: DomSanitizer,
27+
) {}
2428

2529
removeStructuredData(): void {
2630
const els = [];
@@ -66,7 +70,7 @@ export class SchemaJsonLDService {
6670
}
6771

6872
if (isNotEmpty(constructor)) {
69-
const provider: SchemaType = new constructor();
73+
const provider: SchemaType = new constructor(this.sanitizer);
7074
return provider.getSchema(item);
7175
} else {
7276
return null;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { PersonSchemaType } from './Person/person-schema-type';
2+
import { ProductCreativeWorkSchemaType } from './product/product-creative-work-schema-type';
3+
import { ProductDatasetSchemaType } from './product/product-dataset-schema-type';
4+
import { PublicationBookSchemaType } from './publication/publication-book-schema-type';
5+
import { PublicationChapterSchemaType } from './publication/publication-chapter-schema-type';
6+
import { PublicationCreativeWorkSchemaType } from './publication/publication-creative-work-schema-type';
7+
import { PublicationReportSchemaType } from './publication/publication-report-schema-type';
8+
import { PublicationScholarlyArticleSchemaType } from './publication/publication-scholarly-article-schema-type';
9+
import { PublicationThesisSchemaType } from './publication/publication-thesis-schema-type';
10+
11+
/**
12+
* Declaration needed to make sure all decorator functions are called in time
13+
*/
14+
export const schemaModels = [
15+
PersonSchemaType,
16+
ProductCreativeWorkSchemaType,
17+
ProductDatasetSchemaType,
18+
PublicationBookSchemaType,
19+
PublicationChapterSchemaType,
20+
PublicationCreativeWorkSchemaType,
21+
PublicationReportSchemaType,
22+
PublicationScholarlyArticleSchemaType,
23+
PublicationThesisSchemaType,
24+
];

src/app/core/metadata/schema-json-ld/schema-types/schema-type.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
import { SecurityContext } from '@angular/core';
2+
import { DomSanitizer } from '@angular/platform-browser';
13
import isObject from 'lodash/isObject';
24

35
import { isNotEmpty } from '../../../../shared/empty.util';
46
import { Item } from '../../../shared/item.model';
57

68
export abstract class SchemaType {
9+
constructor(protected sanitizer: DomSanitizer) {}
10+
711
protected abstract createSchema(item: Item): Record<string, any>;
812
protected abstract createSchema(item: Item): Record<string, any>;
913

@@ -31,7 +35,35 @@ export abstract class SchemaType {
3135
}
3236
}
3337

38+
protected sanitizeSchema(obj: any): Record<string, any> {
39+
if (Array.isArray(obj)) {
40+
return obj.map(v =>
41+
typeof v === 'string'
42+
? this.sanitizer.sanitize(SecurityContext.HTML, v)
43+
: this.sanitizeSchema(v),
44+
);
45+
}
46+
47+
if (typeof obj === 'object' && obj !== null) {
48+
const sanitized: Record<string, any> = {};
49+
for (const key in obj) {
50+
if (obj.hasOwnProperty(key)) {
51+
const value = obj[key];
52+
sanitized[key] =
53+
typeof value === 'string'
54+
? this.sanitizer.sanitize(SecurityContext.HTML, value)
55+
: this.sanitizeSchema(value);
56+
}
57+
}
58+
return sanitized;
59+
}
60+
61+
return obj;
62+
}
63+
64+
3465
getSchema(item: Item): Record<string, any> {
35-
return SchemaType.removeEmpty(this.createSchema(item));
66+
const sanitizedRaw = this.sanitizeSchema(this.createSchema(item));
67+
return SchemaType.removeEmpty(sanitizedRaw);
3668
}
3769
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<ds-item-page-cc-license-field
2+
[item]="item"
3+
[variant]="'full'"
4+
[ccLicenseUriField]="dcRightsUri"
5+
[ccLicenseNameField]="dcRights"
6+
[showLabel]="false"
7+
[showUrl]="true">
8+
</ds-item-page-cc-license-field>

src/app/cris-layout/cris-layout-matrix/cris-layout-box-container/boxes/metadata/rendering-types/cc-license-large/cc-license-large.component.scss

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
ComponentFixture,
3+
TestBed,
4+
} from '@angular/core/testing';
5+
import { TranslateModule } from '@ngx-translate/core';
6+
7+
import { CcLicenseLargeComponent } from './cc-license-large.component';
8+
9+
describe('CcLicenseLargeComponent', () => {
10+
let component: CcLicenseLargeComponent;
11+
let fixture: ComponentFixture<CcLicenseLargeComponent>;
12+
13+
const mockItem = {
14+
firstMetadataValue: jasmine.createSpy('firstMetadataValue').and.returnValue(''),
15+
metadata: {},
16+
findMetadataSortedByPlace: jasmine.createSpy('findMetadataSortedByPlace').and.returnValue([]),
17+
};
18+
19+
const mockField = {
20+
metadataGroup: { elements: [] },
21+
styleValue: '',
22+
};
23+
24+
beforeEach(async () => {
25+
await TestBed.configureTestingModule({
26+
imports: [
27+
CcLicenseLargeComponent,
28+
TranslateModule.forRoot(),
29+
],
30+
providers: [
31+
{ provide: 'fieldProvider', useValue: mockField },
32+
{ provide: 'itemProvider', useValue: mockItem },
33+
{ provide: 'metadataValueProvider', useValue: {} },
34+
{ provide: 'renderingSubTypeProvider', useValue: '' },
35+
{ provide: 'tabNameProvider', useValue: '' },
36+
],
37+
}).compileComponents();
38+
39+
fixture = TestBed.createComponent(CcLicenseLargeComponent);
40+
component = fixture.componentInstance;
41+
42+
component.componentsToBeRenderedMap.set(0, [
43+
{ field: { metadata: 'dc.rights' } as any, value: {} as any },
44+
{ field: { metadata: 'dc.rights.uri' } as any, value: {} as any },
45+
] as any);
46+
47+
fixture.detectChanges();
48+
});
49+
50+
it('should create', () => {
51+
expect(component).toBeTruthy();
52+
});
53+
});

0 commit comments

Comments
 (0)