Skip to content

Commit

Permalink
Multi IDP Support via config
Browse files Browse the repository at this point in the history
  • Loading branch information
Glitch (glitch-hello-node) committed Oct 17, 2023
1 parent 0b7b0d1 commit 4bcab70
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 39 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ RP:
FedCM specifics:

- FedCM [Browser API](https://fedidcg.github.io/FedCM/#browser-api)
- Default configuration will supply the set client_id, configURL as well as a random nonce to the API
- Support for multiple IDPs, configuration is contained in `config/idpConfig.json`. **Note** that multi-IDP support is not properly working at this time on the browser side. Random nonce is automatically added
- Configurable features (via UI) are session specific and can be changed at any given time
- [Usage Mode](https://github.com/fedidcg/FedCM/issues/442#issuecomment-1675007152) (On-click (mode=Widget), Pageload (mode=Widget), Button (mode=button - Experimental))
- [Mediation Mode](https://w3c.github.io/webappsec-credential-management/#dom-credentialrequestoptions-mediation) (optional, silent, required, conditional)
Expand Down
6 changes: 6 additions & 0 deletions config/idpConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"configURL": "http://localhost:8080/fedcm.json",
"clientId": "yourClientID"
}
]
34 changes: 18 additions & 16 deletions public/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,25 +176,27 @@ export const signout = account_id => async () => {
}
}

// create personlized button (IFrame served from IDP) at given div containerID
export const createIframe = (containerId, idpConfig) => {
const iframe = document.createElement('iframe')
const clientId = idpConfig.clientId
const origin_idp = new URL(idpConfig.configURL).origin

iframe.src = `${origin_idp}/fedcm/embedded?clientId=${encodeURIComponent(
clientId
)}`
iframe.referrerPolicy = 'origin'
iframe.allow = 'identity-credentials-get'

export const createIframes = (containerId, idpConfig) => {
const container = document.getElementById(containerId)

if (container) {
container.append(iframe)
} else {
if (!container) {
console.warn(
`Container with id ${containerId} not found. Appending iframe to body.`
`Container with id ${containerId} not found. Appending iframes to body.`
)
return
}

idpConfig.forEach(idp => {
const iframe = document.createElement('iframe')
const clientId = idp.clientId
const origin_idp = new URL(idp.configURL).origin

iframe.src = `${origin_idp}/fedcm/embedded?clientId=${encodeURIComponent(
clientId
)}`
iframe.referrerPolicy = 'origin'
iframe.allow = 'identity-credentials-get'

container.append(iframe)
})
}
17 changes: 7 additions & 10 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,19 @@ const { csrfCheck, sessionCheck, getUser } = require('./libs/common')
const app = express()

// IDP Config, replace with your own
const idpConfig = [
{
configURL: 'http://localhost:8080/fedcm1.json',
clientId: 'yourClientID1'
} /*,
{
configURL: 'http://localhost:8080/fedcm2.json',
clientId: 'yourClientID2'
}*/
]
const fs = require('fs')
const idpConfig = JSON.parse(fs.readFileSync('./config/idpConfig.json'))

// register the helper function
hbs.registerHelper('eq', function (a, b) {
return a === b
})

hbs.registerHelper('getOrigin', function (url) {
const origin = new URL(url).origin
return origin
})

app.set('view engine', 'html')
app.engine('html', hbs.__express)
app.set('views', './views')
Expand Down
18 changes: 6 additions & 12 deletions views/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ <h2>Settings</h2>
<mwc-button id="signOnButton" raised>Sign In</mwc-button>
{{/if}}
<!-- Add a button to link to the sign-in page -->
<a href="https://dry-lake-09460.herokuapp.com/" id="idp-link">
<mwc-button raised>Visit IDP</mwc-button>
{{#each config.idpConfig}}
<a href="{{getOrigin this.configURL}}" id="idp-link-{{@index}}">
<mwc-button raised>Visit IDP {{@index}}</mwc-button>
</a>
{{/each}}
</div>
{{#if config.userInfoEnabled}}
<div id="personalizedButton" class="iframe-container"></div>
Expand All @@ -133,7 +135,7 @@ <h2>Settings</h2>
getCredential,
handleConfigSave,
switchTab,
createIframe,
createIframes,
} from "./client.js";

$("#home").addEventListener("click", () => location.reload());
Expand All @@ -151,14 +153,6 @@ <h2>Settings</h2>
config = await configResponse.json();
const idpConfig = config.idpConfig

// Extract the scheme and origin from the first entry of the configURL array in idpConfig
const url = new URL(config.idpConfig[0].configURL);
const idpOrigin = url.protocol + '//' + url.hostname + (url.port ? ':' + url.port : '');

// Set the IDP link to the IDP origin
const idpLink = document.getElementById('idp-link');
idpLink.href = idpOrigin;

if ("IdentityCredential" in window) {
if (config && config.mode === "pageload") {
signIn();
Expand All @@ -172,7 +166,7 @@ <h2>Settings</h2>
}

if (config && config.userInfoEnabled) {
createIframe("personalizedButton", config.idpConfig);
createIframes("personalizedButton", config.idpConfig);
}
}

Expand Down

0 comments on commit 4bcab70

Please sign in to comment.