Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/codescan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ jobs:

# Perform GitHub Code Scanning.
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v3
51 changes: 50 additions & 1 deletion cypress/e2e/item-edit.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,27 @@ describe('Edit Item > Edit Metadata tab', () => {
// Wait for any loading spinners to disappear
cy.get('ds-edit-item-page ds-loading').should('not.exist');

// wait for all the tabs to be rendered on this page
cy.get('ds-edit-item-page ul[role="tablist"]').each(($row: HTMLUListElement) => {
cy.wrap($row).find('a[role="tab"]').should('be.visible');
});

// wait for all the ds-dso-edit-metadata-value components to be rendered
cy.get('ds-dso-edit-metadata-value div[role="row"]').each(($row: HTMLDivElement) => {
cy.wrap($row).find('div[role="cell"]').should('be.visible');
});

// Analyze <ds-edit-item-page> for accessibility issues
testA11y('ds-edit-item-page');
testA11y('ds-edit-item-page', {
rules: {
// Edit-metadata uses nested role="table" wrappers (per-field value lists) which
// briefly contain no rows while values are hydrating, causing a flaky
// "aria-required-children" violation. Same ng-bootstrap / nested-table
// limitation as DSpace issue #2216 (see health-page.cy.ts which waives
// this rule for the same reason).
'aria-required-children': { enabled: false },
},
} as Options);
});
});

Expand All @@ -49,6 +63,11 @@ describe('Edit Item > Status tab', () => {
// <ds-item-status> tag must be loaded
cy.get('ds-item-status').should('be.visible');

// wait for all the tabs to be rendered on this page
cy.get('ds-edit-item-page ul[role="tablist"]').each(($row: HTMLUListElement) => {
cy.wrap($row).find('a[role="tab"]').should('be.visible');
});

// Analyze for accessibility issues
testA11y('ds-item-status');
});
Expand All @@ -67,6 +86,11 @@ describe('Edit Item > Bitstreams tab', () => {
// <ds-item-bitstreams> tag must be loaded
cy.get('ds-item-bitstreams').should('be.visible');

// wait for all the tabs to be rendered on this page
cy.get('ds-edit-item-page ul[role="tablist"]').each(($row: HTMLUListElement) => {
cy.wrap($row).find('a[role="tab"]').should('be.visible');
});

// Table of item bitstreams must also be loaded
cy.get('div.item-bitstreams').should('be.visible');

Expand Down Expand Up @@ -96,6 +120,11 @@ describe('Edit Item > Curate tab', () => {
// <ds-item-curate> tag must be loaded
cy.get('ds-item-curate').should('be.visible');

// wait for all the tabs to be rendered on this page
cy.get('ds-edit-item-page ul[role="tablist"]').each(($row: HTMLUListElement) => {
cy.wrap($row).find('a[role="tab"]').should('be.visible');
});

// Analyze for accessibility issues
testA11y('ds-item-curate');
});
Expand All @@ -114,6 +143,11 @@ describe('Edit Item > Relationships tab', () => {
// <ds-item-relationships> tag must be loaded
cy.get('ds-item-relationships').should('be.visible');

// wait for all the tabs to be rendered on this page
cy.get('ds-edit-item-page ul[role="tablist"]').each(($row: HTMLUListElement) => {
cy.wrap($row).find('a[role="tab"]').should('be.visible');
});

// Analyze for accessibility issues
testA11y('ds-item-relationships');
});
Expand All @@ -132,6 +166,11 @@ describe('Edit Item > Version History tab', () => {
// <ds-item-version-history> tag must be loaded
cy.get('ds-item-version-history').should('be.visible');

// wait for all the tabs to be rendered on this page
cy.get('ds-edit-item-page ul[role="tablist"]').each(($row: HTMLUListElement) => {
cy.wrap($row).find('a[role="tab"]').should('be.visible');
});

// Analyze for accessibility issues
testA11y('ds-item-version-history');
});
Expand All @@ -150,6 +189,11 @@ describe('Edit Item > Access Control tab', () => {
// <ds-item-access-control> tag must be loaded
cy.get('ds-item-access-control').should('be.visible');

// wait for all the tabs to be rendered on this page
cy.get('ds-edit-item-page ul[role="tablist"]').each(($row: HTMLUListElement) => {
cy.wrap($row).find('a[role="tab"]').should('be.visible');
});

// Analyze for accessibility issues
testA11y('ds-item-access-control');
});
Expand All @@ -168,6 +212,11 @@ describe('Edit Item > Collection Mapper tab', () => {
// <ds-item-collection-mapper> tag must be loaded
cy.get('ds-item-collection-mapper').should('be.visible');

// wait for all the tabs to be rendered on this page
cy.get('ds-edit-item-page ul[role="tablist"]').each(($row: HTMLUListElement) => {
cy.wrap($row).find('a[role="tab"]').should('be.visible');
});

// Analyze entire page for accessibility issues
testA11y('ds-item-collection-mapper');

Expand Down
36 changes: 18 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dspace-angular",
"version": "8.2.0",
"version": "8.3.0",
"scripts": {
"ng": "ng",
"config:watch": "nodemon",
Expand Down Expand Up @@ -67,7 +67,7 @@
"@angular/platform-server": "^17.3.11",
"@angular/router": "^17.3.11",
"@angular/ssr": "^17.3.17",
"@babel/runtime": "7.27.6",
"@babel/runtime": "7.28.4",
"@kolkov/ngx-gallery": "^2.0.1",
"@ng-bootstrap/ng-bootstrap": "^11.0.0",
"@ng-dynamic-forms/core": "^16.0.0",
Expand All @@ -78,14 +78,14 @@
"@ngx-translate/core": "^14.0.0",
"@nicky-lenaers/ngx-scroll-to": "^14.0.0",
"angulartics2": "^12.2.0",
"axios": "^1.10.0",
"axios": "^1.13.2",
"bootstrap": "^4.6.1",
"cerialize": "0.1.18",
"cli-progress": "^3.12.0",
"colors": "^1.4.0",
"compression": "^1.8.0",
"compression": "^1.8.1",
"cookie-parser": "1.4.7",
"core-js": "^3.42.0",
"core-js": "^3.47.0",
"date-fns": "^2.29.3",
"date-fns-tz": "^1.3.7",
"deepmerge": "^4.3.1",
Expand All @@ -96,9 +96,9 @@
"filesize": "^6.1.0",
"http-proxy-middleware": "^2.0.9",
"http-terminator": "^3.2.0",
"isbot": "^5.1.28",
"isbot": "^5.1.32",
"js-cookie": "2.2.1",
"js-yaml": "^4.1.0",
"js-yaml": "^4.1.1",
"json5": "^2.2.3",
"jsonschema": "1.5.0",
"jwt-decode": "^3.1.2",
Expand All @@ -109,7 +109,7 @@
"mirador": "^3.4.3",
"mirador-dl-plugin": "^0.13.0",
"mirador-share-plugin": "^0.16.0",
"morgan": "^1.10.0",
"morgan": "^1.10.1",
"ng2-file-upload": "9.0.0",
"ng2-nouislider": "^2.0.0",
"ngx-infinite-scroll": "^16.0.0",
Expand Down Expand Up @@ -147,28 +147,28 @@
"@types/grecaptcha": "^3.0.9",
"@types/jasmine": "~3.6.0",
"@types/js-cookie": "2.2.6",
"@types/lodash": "^4.17.17",
"@types/lodash": "^4.17.21",
"@types/node": "^14.14.9",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@typescript-eslint/rule-tester": "^7.2.0",
"@typescript-eslint/utils": "^7.2.0",
"axe-core": "^4.10.3",
"axe-core": "^4.11.0",
"compression-webpack-plugin": "^9.2.0",
"copy-webpack-plugin": "^6.4.1",
"cross-env": "^7.0.3",
"csstype": "^3.1.3",
"csstype": "^3.2.3",
"cypress": "^13.17.0",
"cypress-axe": "^1.6.0",
"cypress-axe": "^1.7.0",
"deep-freeze": "0.0.1",
"eslint": "^8.39.0",
"eslint-plugin-deprecation": "^1.4.1",
"eslint-plugin-dspace-angular-html": "link:./lint/dist/src/rules/html",
"eslint-plugin-dspace-angular-ts": "link:./lint/dist/src/rules/ts",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-import-newlines": "^1.3.1",
"eslint-plugin-jsdoc": "^45.0.0",
"eslint-plugin-jsonc": "^2.20.1",
"eslint-plugin-jsonc": "^2.21.0",
"eslint-plugin-lodash": "^7.4.0",
"eslint-plugin-rxjs": "^5.0.3",
"eslint-plugin-simple-import-sort": "^10.0.0",
Expand All @@ -183,7 +183,7 @@
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"karma-mocha-reporter": "2.2.5",
"ng-mocks": "^14.13.5",
"ng-mocks": "^14.14.0",
"ngx-mask": "14.2.4",
"nodemon": "^2.0.22",
"postcss": "^8.5",
Expand All @@ -195,13 +195,13 @@
"react-copy-to-clipboard": "^5.1.0",
"react-dom": "^16.14.0",
"rimraf": "^3.0.2",
"sass": "~1.89.2",
"sass": "~1.94.2",
"sass-loader": "^12.6.0",
"sass-resources-loader": "^2.2.5",
"ts-node": "^8.10.2",
"typescript": "~5.4.5",
"webpack": "5.99.9",
"webpack": "5.101.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
"webpack-dev-server": "^5.2.2"
}
}
12 changes: 7 additions & 5 deletions scripts/sync-i18n-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ function parseCliInput() {
.usage('([-d <output-dir>] [-s <source-file>]) || (-t <target-file> (-i | -o <output>) [-s <source-file>])')
.parse(process.argv);

if (!program.targetFile) {
const sourceFile = program.opts().sourceFile;

if (!program.targetFile) {
fs.readdirSync(projectRoot(LANGUAGE_FILES_LOCATION)).forEach(file => {
if (!program.sourceFile.toString().endsWith(file)) {
if (!sourceFile.toString().endsWith(file)) {
const targetFileLocation = projectRoot(LANGUAGE_FILES_LOCATION + "/" + file);
console.log('Syncing file at: ' + targetFileLocation + ' with source file at: ' + program.sourceFile);
console.log('Syncing file at: ' + targetFileLocation + ' with source file at: ' + sourceFile);
if (program.outputDir) {
Comment thread
milanmajchrak marked this conversation as resolved.
if (!fs.existsSync(program.outputDir)) {
fs.mkdirSync(program.outputDir);
Expand All @@ -67,7 +69,7 @@ function parseCliInput() {
console.log(program.outputHelp());
process.exit(1);
}
if (!checkIfFileExists(program.sourceFile)) {
if (!checkIfFileExists(sourceFile)) {
console.error('Path of source file is not valid.');
console.log(program.outputHelp());
process.exit(1);
Expand Down Expand Up @@ -101,7 +103,7 @@ function syncFileWithSource(pathToTargetFile, pathToOutputFile) {
targetLines.push(line.trim());
}));
progressBar.update(10);
const sourceFile = readFileIfExists(program.sourceFile);
const sourceFile = readFileIfExists(program.opts().sourceFile);
sourceFile.toString().split("\n").forEach((function (line) {
sourceLines.push(line.trim());
}));
Expand Down
33 changes: 25 additions & 8 deletions server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ function serverSideRender(req, res, next, sendToUser: boolean = true) {
],
})
.then((html) => {
// If headers were already sent, then do nothing else, it is probably a
// redirect response
if (res.headersSent) {
return;
}

if (hasValue(html)) {
// Replace REST URL with UI URL
if (environment.ssr.replaceRestUrl && REST_BASE_URL !== environment.rest.baseUrl) {
Expand Down Expand Up @@ -304,13 +310,24 @@ function serverSideRender(req, res, next, sendToUser: boolean = true) {
});
}

/**
* Send back response to user to trigger direct client-side rendering (CSR)
* @param req current request
* @param res current response
*/
// Read file once at startup
const indexHtmlContent = readFileSync(indexHtml, 'utf8');

function clientSideRender(req, res) {
res.sendFile(indexHtml);
const namespace = environment.ui.nameSpace || '/';
let html = indexHtmlContent;
// Replace base href dynamically
html = html.replace(
/<base href="[^"]*">/,
`<base href="${namespace.endsWith('/') ? namespace : namespace + '/'}">`
);

// Replace REST URL with UI URL
if (environment.ssr.replaceRestUrl && REST_BASE_URL !== environment.rest.baseUrl) {
html = html.replace(new RegExp(REST_BASE_URL, 'g'), environment.rest.baseUrl);
}

res.send(html);
}


Expand Down Expand Up @@ -561,8 +578,8 @@ function createHttpsServer(keys) {
* Create an HTTP server with the configured port and host.
*/
function run() {
const port = environment.ui.port || 4000;
const host = environment.ui.host || '/';
const port = environment.ui.port;
const host = environment.ui.host;

// Start up the Node server
const server = app();
Expand Down
7 changes: 5 additions & 2 deletions src/app/app-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { COLLECTION_MODULE_PATH } from './collection-page/collection-page-routin
import { COMMUNITY_MODULE_PATH } from './community-page/community-page-routing-paths';
import { authBlockingGuard } from './core/auth/auth-blocking.guard';
import { authenticatedGuard } from './core/auth/authenticated.guard';
import { notAuthenticatedGuard } from './core/auth/not-authenticated.guard';
import { groupAdministratorGuard } from './core/data/feature-authorization/feature-authorization-guard/group-administrator.guard';
import { siteAdministratorGuard } from './core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
import { siteRegisterGuard } from './core/data/feature-authorization/feature-authorization-guard/site-register.guard';
Expand Down Expand Up @@ -98,13 +99,13 @@ export const APP_ROUTES: Route[] = [
path: REGISTER_PATH,
loadChildren: () => import('./register-page/register-page-routes')
.then((m) => m.ROUTES),
canActivate: [siteRegisterGuard],
canActivate: [notAuthenticatedGuard, siteRegisterGuard],
},
{
path: FORGOT_PASSWORD_PATH,
loadChildren: () => import('./forgot-password/forgot-password-routes')
.then((m) => m.ROUTES),
canActivate: [endUserAgreementCurrentUserGuard, forgotPasswordCheckGuard],
canActivate: [notAuthenticatedGuard, endUserAgreementCurrentUserGuard, forgotPasswordCheckGuard],
},
{
path: COMMUNITY_MODULE_PATH,
Expand Down Expand Up @@ -178,11 +179,13 @@ export const APP_ROUTES: Route[] = [
path: 'login',
loadChildren: () => import('./login-page/login-page-routes')
.then((m) => m.ROUTES),
canActivate: [notAuthenticatedGuard],
},
{
path: 'logout',
loadChildren: () => import('./logout-page/logout-page-routes')
.then((m) => m.ROUTES),
canActivate: [authenticatedGuard],
},
{
path: 'submit',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export class CollectionItemMapperComponent implements OnInit {

this.collectionName$ = this.collectionRD$.pipe(
map((rd: RemoteData<Collection>) => {
return this.dsoNameService.getName(rd.payload);
return this.dsoNameService.getName(rd.payload, true);
}),
);
this.searchOptions$ = this.searchConfigService.paginatedSearchOptions;
Expand Down
1 change: 0 additions & 1 deletion src/app/core/auth/models/auth.method-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ export enum AuthMethodType {
Shibboleth = 'shibboleth',
Ldap = 'ldap',
Ip = 'ip',
X509 = 'x509',
Oidc = 'oidc',
Orcid = 'orcid'
}
4 changes: 0 additions & 4 deletions src/app/core/auth/models/auth.method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ export class AuthMethod {
this.location = location;
break;
}
case 'x509': {
this.authMethodType = AuthMethodType.X509;
break;
}
case 'password': {
this.authMethodType = AuthMethodType.Password;
break;
Expand Down
Loading
Loading