Skip to content

Federated search#222

Open
rosemcc wants to merge 2100 commits intomasterfrom
federated-search
Open

Federated search#222
rosemcc wants to merge 2100 commits intomasterfrom
federated-search

Conversation

@rosemcc
Copy link
Copy Markdown
Contributor

@rosemcc rosemcc commented Feb 14, 2022

Feature

Include results from the Staff Intranet in the ResearchHub search results UI

Description

The Intranet contains documents that overlap with the material the Research Hub provides. It is helpful to be able to include results from the Intranet in the Research Hub search, enabling users to navigate directly to these documents from the Research Hub search results page.

Intranet search results are accessed via a Swiftype API, within a collection called "Staff Intranet". This feature provides an update to the search page UI so logged-in users can choose to view the Intranet results, as well as the implementation of the backend API wrapper to access the Swiftype API securely. More information around the technical and security considerations of adding this feature can be found here.

Solution

Swiftype API Wrapper - Lambda function

A new endpoint has been added to the Hub-Search-Proxy lambda function which acts as a middleware between the UI and the Swiftype API. The purpose of this is to provide a secure way to access the Intranet search results, which must be behind SSO, as well as keeping the Swiftype API key in a secure location which will never be exposed to the frontend.

The new endpoint function is implemented in a separate handler file (uoasearch.js). The endpoint path is /uoasearch, which is configured in the serverless.yml, along with an API Gateway Authorizer to enable Cognito user pool authorization of requests to the endpoint. Requests must contain a valid auth token or they will be blocked by API Gateway. Requests are authorized by checking the user is in the valid access group to be able to view Staff Intranet data.

Search UI Changes

A tabbed interface has been added to the search results page using Angular Material Tabs component. ResearchHub results are shown in the default tab, and Staff Intranet results are shown (if the user is logged in) in a second tab, as a separate list. Results are only returned when a search query is present. Search filters are not applied on the Intranet results.

New components/services:

  • IntranetSearchService
  • IntranetSearchComponent
  • IntranetSearchResultsListComponent

Cloudfront Function change

  • updated CSP to allow the new search endpoint

Screenshots

Before

image

After

image

Staff Intranet tab:
image

Testing

research-hub-web

IntranetSearchComponent:

  • should create
  • Initial search properties should be undefined
  • search should update search variables
  • should not call intranet search if not logged in

IntranetSearchResultsListComponent:

  • should create
  • should show skeleton when loading
  • should show 1 results card for each search result

IntranetSearchService

  • should be created
  • should make a POST request and return search result

hub-search-proxy

  • POST uoasearch request returns a response
  • POST uoasearch request with invalid sort option returns an error

Have the changes been checked in the following browsers?

  • Chrome
  • Safari
  • Firefox
  • Edge

rosemcc and others added 30 commits November 4, 2021 16:34
handle search result category chip with missing name
* initial autocomplete basic functionality

* dynamic autocomplete

* use all page titles for autocomplete, only include searchable items

* handle diacritics, PageTitles interface

* tidying

* autocomplete styles, click to search

* unit tests WIP

* autocomplete service tests

* clean up

* remove leading and trailing white space

* autocomplete tests

* material override style more specific, tidying up
…b-search-proxy/contentful-export-7.13.34

Bump contentful-export from 7.13.26 to 7.13.34 in /hub-search-proxy
Bumps [cypress-commands](https://github.com/Lakitna/cypress-commands) from 1.1.0 to 2.0.1.
- [Release notes](https://github.com/Lakitna/cypress-commands/releases)
- [Changelog](https://github.com/Lakitna/cypress-commands/blob/develop/CHANGELOG.md)
- [Commits](Lakitna/cypress-commands@1.1.0...2.0.1)

---
updated-dependencies:
- dependency-name: cypress-commands
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
* generated new components

* first version of contact card

* changed card title color

* fixed elevation

* first version of org unit card

* first version of document card

* moved cards module and components

* article simplification

* changed mouse pointer on card

* minor change to article page

* Revert "minor change to article page"

This reverts commit 4c66bf8.

* case-studys page refactor

* fixed width cards, minor article change

* changed equipment page

* changes to events

* changed fundings page

* changes to service page

* changes to software page

* changes to subhubs and standard card

* set image height

* removed app-cards from featured component

* removed old cards components

* fixed featured layout

* better spacing on featured component

* fixed lock icon size

* fixed article layout

* fixed mobile card width

* fixed clickable cards

* generated new components

* first version of contact card

* changed card title color

* fixed elevation

* first version of org unit card

* first version of document card

* moved cards module and components

* article simplification

* changed mouse pointer on card

* minor change to article page

* Revert "minor change to article page"

This reverts commit 4c66bf8.

* case-studys page refactor

* fixed width cards, minor article change

* changed equipment page

* changes to events

* changed fundings page

* changes to service page

* changes to software page

* changes to subhubs and standard card

* set image height

* removed app-cards from featured component

* removed old cards components

* fixed featured layout

* better spacing on featured component

* fixed lock icon size

* fixed article layout

* fixed mobile card width

* fixed clickable cards

* generated new components

* first version of contact card

* changed card title color

* fixed elevation

* first version of org unit card

* first version of document card

* moved cards module and components

* article simplification

* changed mouse pointer on card

* minor change to article page

* Revert "minor change to article page"

This reverts commit 4c66bf8.

* case-studys page refactor

* fixed width cards, minor article change

* changed equipment page

* changes to events

* changed fundings page

* changes to service page

* changes to software page

* changes to subhubs and standard card

* set image height

* removed app-cards from featured component

* removed old cards components

* fixed featured layout

* better spacing on featured component

* fixed lock icon size

* fixed article layout

* fixed mobile card width

* fixed clickable cards

* generated new components

* first version of contact card

* changed card title color

* fixed elevation

* first version of org unit card

* first version of document card

* moved cards module and components

* changed mouse pointer on card

* minor change to article page

* Revert "minor change to article page"

This reverts commit 4c66bf8.

* fixed width cards, minor article change

* fixed clickable cards

* minor fixes

* article layout fixes

* fixes for case studies layout

* more layout fixes

* fixed unit tests

* fix for equipment table

* upgraded e2e test with cypress types, fixed e2e tests

* fixed inconsistent bottom margin

* mat-icon white on subhub child card

* added missing case study references

* fixed 3 column layout being too narrow

* fixed you-might-be-interested-in id

* fixed featured layout

* fixed missing funding purpose

* fixed body media error

* fix nulls error on subhub pages

* fixed title underline

* Revert "fixed title underline"

This reverts commit d92ba98.

* fixed subhub child card underline

Co-authored-by: Rose McColl <rosemccoll@hotmail.com>
…search-hub-web/cypress-commands-2.0.1

Bump cypress-commands from 1.1.0 to 2.0.1 in /research-hub-web
@rosemcc
Copy link
Copy Markdown
Contributor Author

rosemcc commented Feb 21, 2022

@Trombach have addressed most comments, just haven't managed to fix the sticky filter bar. Also added some (very) basic error handling for if there's any issue with fetching search results. The error handling could be improved with adding more informative message for the user, but for now I think it is enough.

@rosemcc
Copy link
Copy Markdown
Contributor Author

rosemcc commented Feb 21, 2022

@Trombach also, if you have time could you please do a quick check of the interface in Safari? 🙏

rosemcc and others added 19 commits February 22, 2022 13:18
* Update versions

* Update f36 deps

* Update to use new methods

* Rewrite promises as async blocks

* Bump @types/react-dom version

* Run npm audit fix

* Add more instructions for deployment

* Add note about official release process

* Update package lock file to use v2
- Also remove unused imports
* add anchor tag over whole card, fix title styling

* Update research-hub-web/src/app/components/search-page/search-results-list/search-results-list.component.html

Co-authored-by: Lukas Trombach <19306765+Trombach@users.noreply.github.com>

* fix link

* fix link

Co-authored-by: Lukas Trombach <19306765+Trombach@users.noreply.github.com>
* boost titles

* Fix phrase query and fuzziness

* simplify containsOperators function

* update serverless-offline
…xy (#244)

* Bump serverless-domain-manager from 5.3.0 to 6.0.2 in /hub-search-proxy

Bumps [serverless-domain-manager](https://github.com/amplify-education/serverless-domain-manager) from 5.3.0 to 6.0.2.
- [Release notes](https://github.com/amplify-education/serverless-domain-manager/releases)
- [Changelog](https://github.com/amplify-education/serverless-domain-manager/blob/master/CHANGELOG.md)
- [Commits](https://github.com/amplify-education/serverless-domain-manager/commits)

---
updated-dependencies:
- dependency-name: serverless-domain-manager
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* npm audit fix

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rose <31844476+rosemcc@users.noreply.github.com>
Co-authored-by: rosemcc <rosemccoll@hotmail.com>
* WIP

* WIP

* set graphql server as ecypress env variable, clean up

* bodyMediaList should be a class, fix naming style also, give body media specific ids for testing

* improvements,  .should('not.be.empty') to .should('exist')

* add more funding tests

* add caseStudy mock and tests

* subhub mock data and tests

* article mock and tests, remove console logs

* software mock and tests, remove example.json

* events mock and tests

* service mock data and tests

* equipment mock data and tests

* improved homepage tests

* set wider viewport for testing

* rename basic-functionality to navbar, add navbar tests

* add sso content test

* categories and activities pages tests

* add search page tests

* minor changes for routing tests

* try to fix e2e fixtures on ci

* still fixing ci

* comments, remove unneeded log message

* wording

Co-authored-by: Lukas Trombach <19306765+Trombach@users.noreply.github.com>

* Update research-hub-web/cypress/utils/graphql-utils.ts

Co-authored-by: Lukas Trombach <19306765+Trombach@users.noreply.github.com>

* Update research-hub-web/cypress/integration/navbar.e2e.ts

Co-authored-by: Lukas Trombach <19306765+Trombach@users.noreply.github.com>

* minor fix

Co-authored-by: Lukas Trombach <19306765+Trombach@users.noreply.github.com>
…hub-web (#232)

* Bump @contentful/rich-text-types in /research-hub-web

Bumps [@contentful/rich-text-types](https://github.com/contentful/rich-text) from 14.1.2 to 15.11.1.
- [Release notes](https://github.com/contentful/rich-text/releases)
- [Changelog](https://github.com/contentful/rich-text/blob/master/CHANGELOG.md)
- [Commits](contentful/rich-text@v14.1.2...v15.11.1)

---
updated-dependencies:
- dependency-name: "@contentful/rich-text-types"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* also update ngx-contentful-rich-text

* CommonJs warning

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: rosemcc <rosemccoll@hotmail.com>
Co-authored-by: Rose <31844476+rosemcc@users.noreply.github.com>
* still render page if a draft image is linked to

* handle no image on activities page
@lugn621 lugn621 force-pushed the federated-search branch from 5f77e22 to c17dff4 Compare April 2, 2026 02:11
Comment on lines +15 to +36
name: Run linters
runs-on: ubuntu-latest

steps:
- name: Check out Git repository
uses: actions/checkout@v2

- name: Set up Node.js
uses: actions/setup-node@v1
with:
node-version: 14

- name: Install Node.js dependencies
working-directory: ./research-hub-web
run: npm ci

- name: Install Angular CLI
run: npm install -g @angular/cli

- name: ng lint
working-directory: ./research-hub-web
run: ng lint

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 9 days ago

In general, the fix is to explicitly define a permissions block in the workflow (either at the top level or per job) that grants only the minimal required scopes for the job. For a lint-only Node/Angular job that just checks out code and runs npm/ng lint, read-only access to repository contents is sufficient.

The best fix here is to add a workflow-level permissions block just after the name: Lint line, setting contents: read. This will apply to all jobs in this workflow (currently just run-linters) and ensures the GITHUB_TOKEN cannot perform write operations. No other scopes (such as pull-requests or issues) are required by the shown steps, so they should not be added.

Concretely, in .github/workflows/linting.yml, insert:

permissions:
  contents: read

between lines 1 and 3 (after name: Lint and before the on: block). No imports or additional definitions are needed.

Suggested changeset 1
.github/workflows/linting.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml
--- a/.github/workflows/linting.yml
+++ b/.github/workflows/linting.yml
@@ -1,5 +1,8 @@
 name: Lint
 
+permissions:
+  contents: read
+
 on:
   # Trigger the workflow on push or pull request,
   # but only for the main branch
EOF
@@ -1,5 +1,8 @@
name: Lint

permissions:
contents: read

on:
# Trigger the workflow on push or pull request,
# but only for the main branch
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +14 to +33
name: Create Sentry Release
runs-on: ubuntu-latest

steps:
- name: Check out Git repository
uses: actions/checkout@v2
- name: Get Branch
id: var
run: echo ::set-output name=branch::${GITHUB_REF#refs/*/}
- name: Output Branch
run: echo ${{ steps.var.outputs.branch }}
- name: Notify Sentry
# https://github.com/getsentry/action-release
uses: getsentry/action-release@v1.1.6
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: university-of-auckland-7o
SENTRY_PROJECT: research-hub
with:
environment: ${{ steps.var.outputs.branch }} No newline at end of file

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 9 days ago

In general, the fix is to explicitly declare a permissions block in the workflow (either at the root level or for the specific job) that grants only the minimal access required. Since this workflow only checks out the code and talks to Sentry, it needs at most read access to repository contents and does not appear to require write access to any GitHub resources.

The best minimal change without altering existing functionality is to add permissions: contents: read at the job level for sentry-release. This limits the GITHUB_TOKEN to read-only access to repository contents for that job, regardless of the repository’s default token permissions. Concretely, in .github/workflows/sentry.yml, under jobs: sentry-release: name: Create Sentry Release, add a permissions: block aligned with runs-on: and steps:. No imports or other definitions are needed, as this is purely a YAML configuration change.

Suggested changeset 1
.github/workflows/sentry.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/sentry.yml b/.github/workflows/sentry.yml
--- a/.github/workflows/sentry.yml
+++ b/.github/workflows/sentry.yml
@@ -13,6 +13,8 @@
   sentry-release:
     name: Create Sentry Release
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
 
     steps:
       - name: Check out Git repository
EOF
@@ -13,6 +13,8 @@
sentry-release:
name: Create Sentry Release
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Check out Git repository
Copilot is powered by AI and may make mistakes. Always verify output.
run: echo ${{ steps.var.outputs.branch }}
- name: Notify Sentry
# https://github.com/getsentry/action-release
uses: getsentry/action-release@v1.1.6

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Sentry Release' step
Uses Step
uses 'getsentry/action-release' with ref 'v1.1.6', not a pinned commit hash

module.exports.search = async (event, context) => {
try {
console.log(`Received query: ${event.body}`);

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.

Copilot Autofix

AI 9 days ago

In general, to fix log injection you should sanitize or normalize user input before writing it to logs. For plain text logs, this typically means removing or replacing newline (\n) and carriage return (\r) characters (and optionally other control characters) from any user-controlled values. It also helps to clearly label logged user input.

For this specific case in hub-search-proxy/handler.js, the safest minimal change is to avoid logging event.body verbatim. Instead, create a sanitized version that strips newline and carriage-return characters before logging. A concise approach is to convert event.body to a string (to avoid issues if it’s not already) and then call replace with a regular expression like /[\r\n]/g or a broader control-character pattern. Then log that sanitized value. This keeps existing behavior (logging the raw request body) while preventing log entries from being split or forged by malicious content.

Concretely, within module.exports.search right before the log or replacing the current log line, introduce a small sanitization step:

  • Define const bodyForLog = String(event.body).replace(/[\r\n]/g, ' ');
  • Use bodyForLog in the console.log message: console.log(`Received query: ${bodyForLog}`);

This change only touches the shown snippet in hub-search-proxy/handler.js, requires no new helper functions, and no new imports.

Suggested changeset 1
hub-search-proxy/handler.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/hub-search-proxy/handler.js b/hub-search-proxy/handler.js
--- a/hub-search-proxy/handler.js
+++ b/hub-search-proxy/handler.js
@@ -51,7 +51,8 @@
 
 module.exports.search = async (event, context) => {
   try {
-    console.log(`Received query: ${event.body}`);
+    const bodyForLog = String(event.body).replace(/[\r\n]/g, ' ');
+    console.log(`Received query: ${bodyForLog}`);
     const requestBody = JSON.parse(event.body);
     let queryString = '';
     let size = 10;
EOF
@@ -51,7 +51,8 @@

module.exports.search = async (event, context) => {
try {
console.log(`Received query: ${event.body}`);
const bodyForLog = String(event.body).replace(/[\r\n]/g, ' ');
console.log(`Received query: ${bodyForLog}`);
const requestBody = JSON.parse(event.body);
let queryString = '';
let size = 10;
Copilot is powered by AI and may make mistakes. Always verify output.
* UoA Swiftype Search handler
*/
module.exports.search = async (event) => {
console.log(`Received query: ${event.body}`);

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.

Copilot Autofix

AI 9 days ago

In general, fix log injection by sanitizing user-controlled values before logging them: remove or escape newline (\n) and carriage return (\r) characters (and optionally other control characters), and clearly label the user input in the log message. This prevents an attacker from breaking the log format or injecting fake entries while preserving useful context.

For this specific file, the minimal and safest change is to avoid logging event.body raw. A good approach is:

  • Create a sanitized version of event.body by converting it to a string (in case it isn’t already) and removing \r and \n.
  • Log only that sanitized value.
  • Keep the rest of the logic unchanged.

Concretely:

  • In hub-search-proxy/uoasearch.js, above the existing console.log on line 12, introduce a new variable, e.g. const safeBodyForLog = String(event.body).replace(/[\r\n]/g, '');.
  • Replace the existing console.log(\Received query: ${event.body}`);withconsole.log(`Received query: ${safeBodyForLog}`);. No new imports or dependencies are needed since we rely on built-in Stringandreplace`.
Suggested changeset 1
hub-search-proxy/uoasearch.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/hub-search-proxy/uoasearch.js b/hub-search-proxy/uoasearch.js
--- a/hub-search-proxy/uoasearch.js
+++ b/hub-search-proxy/uoasearch.js
@@ -9,7 +9,8 @@
  * UoA Swiftype Search handler
  */
 module.exports.search = async (event) => {
-  console.log(`Received query: ${event.body}`);
+  const safeBodyForLog = String(event.body).replace(/[\r\n]/g, '');
+  console.log(`Received query: ${safeBodyForLog}`);
   try {
     var ssmParams = {
       Names: [
EOF
@@ -9,7 +9,8 @@
* UoA Swiftype Search handler
*/
module.exports.search = async (event) => {
console.log(`Received query: ${event.body}`);
const safeBodyForLog = String(event.body).replace(/[\r\n]/g, '');
console.log(`Received query: ${safeBodyForLog}`);
try {
var ssmParams = {
Names: [
Copilot is powered by AI and may make mistakes. Always verify output.
}
)
} catch(error) {
console.log(error);

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.

Copilot Autofix

AI 9 days ago

Generally, to fix log injection, any data that may originate from users (directly or indirectly) should be sanitized before being written to logs. For plain-text logs, it is usually sufficient to strip carriage returns and newlines from the string representation of the data, and to clearly mark user-controlled content. Instead of logging raw objects that may stringify to multi-line strings, log a sanitized subset such as the error name and a cleaned-up message.

In this specific case, we should avoid passing the raw error object directly to console.log. Instead, in hub-search-proxy/uoasearch.js inside the catch block, we can construct a safe log line that includes error.name and a sanitized version of error.message, with \r and \n removed. We can also add a small helper within this file to sanitize strings for logging, or just perform inline replace operations. No changes are needed in helpers.js. Concretely: modify line 82 to log a single-line, sanitized message, and avoid logging arbitrary additional properties or stacks that may contain newlines. We do not need extra imports; we can rely on String.prototype.replace.

Suggested changeset 1
hub-search-proxy/uoasearch.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/hub-search-proxy/uoasearch.js b/hub-search-proxy/uoasearch.js
--- a/hub-search-proxy/uoasearch.js
+++ b/hub-search-proxy/uoasearch.js
@@ -79,10 +79,12 @@
       }
     )
   } catch(error) {
-    console.log(error);
+    const errorName = (error && error.name ? String(error.name) : "Error").replace(/[\r\n]/g, " ");
+    const errorMessage = (error && error.message ? String(error.message) : "").replace(/[\r\n]/g, " ");
+    console.log(`Search handler error: ${errorName}: ${errorMessage}`);
     return formatResponse(
       500,
-      { result: `${error.name}: ${error.message}` }
+      { result: `${errorName}: ${errorMessage}` }
     );
   }
 }
EOF
@@ -79,10 +79,12 @@
}
)
} catch(error) {
console.log(error);
const errorName = (error && error.name ? String(error.name) : "Error").replace(/[\r\n]/g, " ");
const errorMessage = (error && error.message ? String(error.message) : "").replace(/[\r\n]/g, " ");
console.log(`Search handler error: ${errorName}: ${errorMessage}`);
return formatResponse(
500,
{ result: `${error.name}: ${error.message}` }
{ result: `${errorName}: ${errorMessage}` }
);
}
}
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants