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
14 changes: 13 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ RSD_ENVIRONMENT=prod
# consumed by services: authentication, frontend (api/fe)
# provide a list of supported OpenID auth providers
# the values should be separated by semicolon (;)
# Allowed values are: SURFCONEXT, HELMHOLTZID, ORCID or LOCAL
# Allowed values are: SURFCONEXT, ORCID, AZURE, LINKEDIN or LOCAL
# if env value is not provided default provider is set to be SURFCONEXT
# if you add the value "LOCAL", then local accounts are enabled, USE THIS FOR TESTING PURPOSES ONLY
RSD_AUTH_PROVIDERS=SURFCONEXT;ORCID;AZURE;LOCAL
Expand Down Expand Up @@ -121,6 +121,14 @@ AZURE_DESCRIPTION_HTML="Sign in with your institutional credentials"
# the organisation recorded for users logged in via this provider
AZURE_ORGANISATION=

# LINKEDIN
# consumed by: authentication, frontend/pages/api/fe/auth/
LINKEDIN_CLIENT_ID=
# consumed by: authentication, frontend/pages/api/fe/auth/
LINKEDIN_REDIRECT=http://localhost/auth/login/linkedin
# consumed by: authentication, frontend/pages/api/fe/auth/
LINKEDIN_WELL_KNOWN_URL=https://www.linkedin.com/oauth/.well-known/openid-configuration

# max requests to the GitHub API per run, runs 10 times per hour
# optional, comment out if not available, a default of 6 will be used
# consumed by: scrapers
Expand Down Expand Up @@ -170,6 +178,10 @@ AUTH_ORCID_CLIENT_SECRET=
# consumed by services: authentication
AUTH_AZURE_CLIENT_SECRET=

# LinkedIn
# consumed by services: authentication
AUTH_LINKEDIN_CLIENT_SECRET=

# consumed by: scrapers
# optional, comment out if not available, should be of the form username:token
# obtain the secret from GITHUB dashboard
Expand Down
14 changes: 13 additions & 1 deletion deployment/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ RSD_ENVIRONMENT=prod
# consumed by services: authentication, frontend (api/fe)
# provide a list of supported OpenID auth providers
# the values should be separated by semicolon (;)
# Allowed values are: SURFCONEXT, HELMHOLTZID, ORCID or LOCAL
# Allowed values are: SURFCONEXT, ORCID, AZURE, LINKEDIN or LOCAL
# if env value is not provided default provider is set to be SURFCONEXT
# if you add the value "LOCAL", then local accounts are enabled, USE THIS FOR TESTING PURPOSES ONLY
RSD_AUTH_PROVIDERS=SURFCONEXT;LOCAL
Expand Down Expand Up @@ -121,6 +121,14 @@ AZURE_DESCRIPTION_HTML="Sign in with your institutional credentials"
# the organisation recorded for users logged in via this provider
AZURE_ORGANISATION=

# LINKEDIN
# consumed by: authentication, frontend/pages/api/fe/auth/
LINKEDIN_CLIENT_ID=
# consumed by: authentication, frontend/pages/api/fe/auth/
LINKEDIN_REDIRECT=http://localhost/auth/login/linkedin
# consumed by: authentication, frontend/pages/api/fe/auth/
LINKEDIN_WELL_KNOWN_URL=https://www.linkedin.com/oauth/.well-known/openid-configuration

# max requests to the GitHub API per run, runs 10 times per hour
# optional, comment out if not available, a default of 6 will be used
# consumed by: scrapers
Expand Down Expand Up @@ -170,6 +178,10 @@ AUTH_ORCID_CLIENT_SECRET=
# consumed by services: authentication
AUTH_AZURE_CLIENT_SECRET=

# LinkedIn
# consumed by services: authentication
AUTH_LINKEDIN_CLIENT_SECRET=

# consumed by: scrapers
# optional, comment out if not available, should be of the form username:token
# obtain the secret from GITHUB dashboard
Expand Down
25 changes: 9 additions & 16 deletions deployment/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ services:

auth:
container_name: auth
image: ghcr.io/research-software-directory/rsd-saas/auth:v2.17.0
image: ghcr.io/research-software-directory/rsd-saas/auth:v2.28.0
expose:
- 7000
environment:
Expand All @@ -56,28 +56,22 @@ services:
- SURFCONEXT_CLIENT_ID
- SURFCONEXT_REDIRECT
- SURFCONEXT_WELL_KNOWN_URL
- SURFCONEXT_SCOPES
- HELMHOLTZID_CLIENT_ID
- HELMHOLTZID_REDIRECT
- HELMHOLTZID_WELL_KNOWN_URL
- HELMHOLTZID_SCOPES
- HELMHOLTZID_USE_ALLOW_LIST
- HELMHOLTZID_ALLOW_LIST
- ORCID_CLIENT_ID
- ORCID_REDIRECT
- ORCID_REDIRECT_COUPLE
- ORCID_WELL_KNOWN_URL
- ORCID_SCOPES
- AZURE_CLIENT_ID
- AZURE_REDIRECT
- AZURE_WELL_KNOWN_URL
- AZURE_SCOPES
- AZURE_ORGANISATION
- HELMHOLTZID_ALLOW_EXTERNAL_USERS
- LINKEDIN_CLIENT_ID
- LINKEDIN_REDIRECT
- LINKEDIN_WELL_KNOWN_URL
- AUTH_SURFCONEXT_CLIENT_SECRET
- AUTH_HELMHOLTZID_CLIENT_SECRET
- AUTH_ORCID_CLIENT_SECRET
- AUTH_AZURE_CLIENT_SECRET
- AUTH_LINKEDIN_CLIENT_SECRET
- PGRST_JWT_SECRET
depends_on:
- database
Expand Down Expand Up @@ -125,11 +119,6 @@ services:
- SURFCONEXT_WELL_KNOWN_URL
- SURFCONEXT_SCOPES
- SURFCONEXT_RESPONSE_MODE
- HELMHOLTZID_CLIENT_ID
- HELMHOLTZID_REDIRECT
- HELMHOLTZID_WELL_KNOWN_URL
- HELMHOLTZID_SCOPES
- HELMHOLTZID_RESPONSE_MODE
- ORCID_CLIENT_ID
- ORCID_REDIRECT
- ORCID_REDIRECT_COUPLE
Expand All @@ -142,6 +131,10 @@ services:
- AZURE_LOGIN_PROMPT
- AZURE_DISPLAY_NAME
- AZURE_DESCRIPTION_HTML
- LINKEDIN_CLIENT_ID
- LINKEDIN_REDIRECT
- LINKEDIN_WELL_KNOWN_URL
- CROSSREF_CONTACT_EMAIL
expose:
- 3000
depends_on:
Expand Down
42 changes: 13 additions & 29 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,4 @@
# SPDX-FileCopyrightText: 2021 - 2023 Dusan Mijatovic (dv4all)
# SPDX-FileCopyrightText: 2021 - 2023 dv4all
# SPDX-FileCopyrightText: 2021 - 2024 Ewan Cahen (Netherlands eScience Center) <[email protected]>
# SPDX-FileCopyrightText: 2021 - 2024 Netherlands eScience Center
# SPDX-FileCopyrightText: 2022 - 2024 Christian Meeßen (GFZ) <[email protected]>
# SPDX-FileCopyrightText: 2022 - 2024 Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences
# SPDX-FileCopyrightText: 2022 Helmholtz Centre for Environmental Research (UFZ)
# SPDX-FileCopyrightText: 2022 Matthias Rüster (GFZ) <[email protected]>
# SPDX-FileCopyrightText: 2023 - 2024 Dusan Mijatovic (Netherlands eScience Center)
# SPDX-FileCopyrightText: 2023 Dusan Mijatovic (dv4all) (dv4all)
#
# SPDX-License-Identifier: Apache-2.0
# THIS DOCKER FILE REQUIRES .env FILE

# version: "3.0"

Expand Down Expand Up @@ -50,7 +39,7 @@ services:
- net

auth:
image: ghcr.io/research-software-directory/rsd-saas/auth:v2.17.0
image: ghcr.io/research-software-directory/rsd-saas/auth:v2.28.0
ports:
- 5005:5005
expose:
Expand All @@ -65,28 +54,22 @@ services:
- SURFCONEXT_CLIENT_ID
- SURFCONEXT_REDIRECT
- SURFCONEXT_WELL_KNOWN_URL
- SURFCONEXT_SCOPES
- HELMHOLTZID_CLIENT_ID
- HELMHOLTZID_REDIRECT
- HELMHOLTZID_WELL_KNOWN_URL
- HELMHOLTZID_SCOPES
- HELMHOLTZID_USE_ALLOW_LIST
- HELMHOLTZID_ALLOW_LIST
- ORCID_CLIENT_ID
- ORCID_REDIRECT
- ORCID_REDIRECT_COUPLE
- ORCID_WELL_KNOWN_URL
- ORCID_SCOPES
- AZURE_CLIENT_ID
- AZURE_REDIRECT
- AZURE_WELL_KNOWN_URL
- AZURE_SCOPES
- AZURE_ORGANISATION
- HELMHOLTZID_ALLOW_EXTERNAL_USERS
- LINKEDIN_CLIENT_ID
- LINKEDIN_REDIRECT
- LINKEDIN_WELL_KNOWN_URL
- AUTH_SURFCONEXT_CLIENT_SECRET
- AUTH_HELMHOLTZID_CLIENT_SECRET
- AUTH_ORCID_CLIENT_SECRET
- AUTH_AZURE_CLIENT_SECRET
- AUTH_LINKEDIN_CLIENT_SECRET
- PGRST_JWT_SECRET
depends_on:
- database
Expand Down Expand Up @@ -127,7 +110,7 @@ services:
# dockerfile to use for build
dockerfile: Dockerfile
# update version number to correspond to frontend/package.json
image: kin-rpd/frontend:0.0.1
image: kin-rpd/frontend:0.0.2
environment:
# it uses values from .env file
- POSTGREST_URL
Expand All @@ -142,11 +125,6 @@ services:
- SURFCONEXT_WELL_KNOWN_URL
- SURFCONEXT_SCOPES
- SURFCONEXT_RESPONSE_MODE
- HELMHOLTZID_CLIENT_ID
- HELMHOLTZID_REDIRECT
- HELMHOLTZID_WELL_KNOWN_URL
- HELMHOLTZID_SCOPES
- HELMHOLTZID_RESPONSE_MODE
- ORCID_CLIENT_ID
- ORCID_REDIRECT
- ORCID_REDIRECT_COUPLE
Expand All @@ -159,12 +137,18 @@ services:
- AZURE_LOGIN_PROMPT
- AZURE_DISPLAY_NAME
- AZURE_DESCRIPTION_HTML
- LINKEDIN_CLIENT_ID
- LINKEDIN_REDIRECT
- LINKEDIN_WELL_KNOWN_URL
- CROSSREF_CONTACT_EMAIL
expose:
- 3000
depends_on:
- database
- backend
- auth
volumes:
- ./frontend/public:/app/public
# volumes:
# - ./deployment/hmz/styles:/app/public/styles
# - ./deployment/hmz/data:/app/public/data
Expand Down
73 changes: 73 additions & 0 deletions frontend/auth/api/authEndpoint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-FileCopyrightText: 2024 - 2025 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2024 - 2025 Netherlands eScience Center
// SPDX-FileCopyrightText: 2025 Ewan Cahen (Netherlands eScience Center) <[email protected]>
//
// SPDX-License-Identifier: Apache-2.0

import logger from '~/utils/logger'
import {getAuthorisationEndpoint} from './authHelpers'

type providers = 'surfconext'|'helmholtzid'|'orcid'|'azure'|'linkedin'
// how often we refresh auth endpoint
const refreshInterval = 60*60*1000
// save timer as public variable
let timer:NodeJS.Timeout
// save authorisation endpoint info
const cache:{
[key:string]:{
authEndpoint?: string
wellknownUrl: string
}
}={}

/**
* We save authorization_endpoint in memory to avoid repeating calls
* refreshInterval defined how often we refresh auth endpoint info.
*
*/
export async function getAuthEndpoint(wellknownUrl:string,provider:providers){
try{
// if already present return existing value
if (cache?.[provider]?.authEndpoint) {
// console.log('getAuthEndpoint...CACHE used...', new Date())
return cache[provider].authEndpoint
}
// if not present request endpoint info
cache[provider] = {
wellknownUrl,
authEndpoint: await getAuthorisationEndpoint(wellknownUrl)
}
// we set timer only in the production because hot-reloading creates multiple instances
if (process.env.NODE_ENV==='production'){
// clear previous timer to avoid mem leaks
if (timer){
// console.log('getAuthEndpoint...CLEAR INTERVAL...', new Date())
clearInterval(timer)
}
// create refresh interval and store it
timer = setInterval(async()=>{
// console.log('getAuthEndpoint...REFRESH INFO...', new Date())
// refresh all cached providers
const providers = Object.keys(cache)
const requests = providers.map(provider=>{
return getAuthorisationEndpoint(cache[provider].wellknownUrl)
})
// perform all requests in parallel
const endpoints = await Promise.all(requests)
// update all providers
providers.forEach((provider,pos)=>{
// update only if there is info
if (endpoints[pos]) {
// console.log(`getAuthEndpoint...${provider}...`, endpoints[pos])
cache[provider].authEndpoint = endpoints[pos]
}
})
},refreshInterval)
}
// console.log('getAuthEndpoint...REQUEST made...', new Date())
return cache[provider]?.authEndpoint
}catch(e:any){
logger(`getAuthEndpoint: ${e.message}`, 'error')
return undefined
}
}
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kin-rpd-frontend",
"version": "0.0.1",
"version": "0.0.2",
"private": true,
"scripts": {
"dev": "next dev",
Expand Down
19 changes: 10 additions & 9 deletions frontend/pages/api/fe/auth/azure.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2022 - 2023 Netherlands eScience Center
// SPDX-FileCopyrightText: 2022 - 2025 Ewan Cahen (Netherlands eScience Center) <[email protected]>
// SPDX-FileCopyrightText: 2022 - 2025 Netherlands eScience Center
// SPDX-FileCopyrightText: 2022 Dusan Mijatovic (dv4all)
// SPDX-FileCopyrightText: 2022 Ewan Cahen (Netherlands eScience Center) <[email protected]>
// SPDX-FileCopyrightText: 2022 Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences
// SPDX-FileCopyrightText: 2022 Matthias Rüster (GFZ) <[email protected]>
// SPDX-FileCopyrightText: 2022 dv4all
// SPDX-FileCopyrightText: 2023 Dusan Mijatovic (Netherlands eScience Center)
// SPDX-FileCopyrightText: 2023 - 2024 Dusan Mijatovic (Netherlands eScience Center)
//
// SPDX-License-Identifier: Apache-2.0

Expand All @@ -15,18 +15,19 @@

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from 'next'
import {getAuthorisationEndpoint, RedirectToProps, getRedirectUrl} from '~/auth/api/authHelpers'
import logger from '~/utils/logger'
import {RedirectToProps, getRedirectUrl} from '~/auth/api/authHelpers'
import {getAuthEndpoint} from '~/auth/api/authEndpoint'
import {Provider, ApiError} from '.'

type Data = Provider | ApiError

export async function azureRedirectProps() {
// extract wellknow url from env
// extract wellknown url from env
const wellknownUrl = process.env.AZURE_WELL_KNOWN_URL ?? null
if (wellknownUrl) {
// extract authorisation endpoint from wellknow response
const authorization_endpoint = await getAuthorisationEndpoint(wellknownUrl)
// get (cached) authorisation endpoint from wellknown url
const authorization_endpoint = await getAuthEndpoint(wellknownUrl, 'azure')
if (authorization_endpoint) {
// construct all props needed for redirectUrl
const props: RedirectToProps = {
Expand All @@ -51,7 +52,7 @@ export async function azureRedirectProps() {
}

export async function azureInfo() {
// extract all props from env and wellknow endpoint
// extract all props from env and wellknown endpoint
const redirectProps = await azureRedirectProps()
if (redirectProps) {
// create return url and the name to use in login button
Expand All @@ -71,7 +72,7 @@ export default async function handler(
res: NextApiResponse<Data>
) {
try {
// extract all props from env and wellknow endpoint
// extract all props from env and wellknown endpoint
// and create return url and the name to use in login button
const loginInfo = await azureInfo()
if (loginInfo) {
Expand Down
Loading