Skip to content

Commit

Permalink
feat: add linkedin login
Browse files Browse the repository at this point in the history
chore: bump fe version
  • Loading branch information
dmijatovic committed Jan 23, 2025
1 parent 8bf2529 commit ffd8604
Show file tree
Hide file tree
Showing 12 changed files with 259 additions and 121 deletions.
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

0 comments on commit ffd8604

Please sign in to comment.