`Strategy ${strategy.id} named ${profile.groups.length} group(s) for user ${userId}: ${matched.length} matched a wiki group (${matched.map((grp)=>grp.name).join(', ')||'none'})${unmatched.length>0?`, ${unmatched.length} did not (${unmatched.join(', ')})`:''}`
`${account.username} (${account.id}) signs in as <${account.email}>${groups?`, holding ${groups.length} mapped role(s): ${groups.join(', ')||'none'}`:', groups not mapped'}`
)
return{
id: String(account.id),
email: account.email,
@ -297,9 +340,9 @@ export default class DiscordAuthentication {
`has \`${tenantId}\` as its Directory (tenant) ID, which is a multi-tenant placeholder — this module needs the tenant's own ID, since it accepts tokens from that directory alone (see MULTI_TENANT)`
`the \`${emailClaim}\` claim carries no address — set Email Claim to \`preferred_username\`, or map the \`email\` optional claim on the app registration`
`is not configured: ${missingSettings({'LDAP URL':url,'Admin Bind DN':bindDn,'Search Base':searchBase,'Search Filter':searchFilter})}, so no login can be attempted`
)
thrownewError('ERR_STRATEGY_MISCONFIGURED')
}
if(!searchFilter.includes('{{username}}')){
strategyDebug(
this,
`cannot look anybody up: the Search Filter \`${searchFilter}\` has no {{username}} placeholder for the typed username to go in`
)
thrownewError('ERR_STRATEGY_MISCONFIGURED')
}
/*
@ -72,16 +81,46 @@ export default class LdapAuthentication {
`the directory refused the wiki's own bind as \`${bindDn}\` (Admin Bind Credentials ${this.conf.bindCredentials?'set':'empty'}): ${describeAuthError(err)}`
`${found.searchEntries.length} group entr${found.searchEntries.length===1?'y':'ies'} matched, ${names.length} named by \`${nameField}\`: ${names.join(', ')||'none'}`
)
returnnames
}
/**
@ -264,7 +391,14 @@ export default class LdapAuthentication {
// -> The first thing to fail on a new strategy, and it fails for reasons the log has to
// carry: an issuer that is not a URL, one publishing no discovery document, TLS
strategyDebug(
this,
`could not read the provider's metadata from ${issuer}: ${describeAuthError(err)}`
)
throwerr
}
constmeta=this.config.serverMetadata()
strategyDebug(
this,
`the provider is ${meta.issuer} — authorization at ${meta.authorization_endpoint}, token at ${meta.token_endpoint}, userinfo at ${meta.userinfo_endpoint??'nowhere (it publishes none)'}`
`has discovery turned off and is not configured: ${missingSettings({'Authorization Endpoint URL':this.conf.authorizationURL,'Token Endpoint URL':this.conf.tokenURL,'JWKS Endpoint URL':this.conf.jwksURL})}`
)
thrownewError('ERR_STRATEGY_MISCONFIGURED')
}
this.config=newclient.Configuration(
@ -146,13 +171,29 @@ export default class OidcAuthentication {
@ -51,6 +52,10 @@ export default class SamlAuthentication {
privatesaml(callbackUrl: string):SAML{
const{entryPoint,issuer,cert}=this.conf
if(!entryPoint||!issuer||!cert){
strategyDebug(
this,
`is not configured: ${missingSettings({'Login URL':entryPoint,'Issuer / Entity ID':issuer,"Identity Provider's Certificate":cert})}`
)
thrownewError('ERR_STRATEGY_MISCONFIGURED')
}
constidpCert=String(cert)
@ -59,8 +64,16 @@ export default class SamlAuthentication {
.filter((one)=>one.length>0)
.slice(0,MAX_CERTS)
if(idpCert.length<1){
strategyDebug(
this,
"the Identity Provider's Certificate holds no certificate, so no assertion can be verified"
)
thrownewError('ERR_STRATEGY_MISCONFIGURED')
}
strategyDebug(
this,
`assertions are expected from ${entryPoint} for audience \`${this.conf.audience||issuer}\`, verified against ${idpCert.length} certificate(s), posted back to ${callbackUrl}`
)
constoptions: SamlConfig={
callbackUrl,
@ -127,6 +140,10 @@ export default class SamlAuthentication {