oidc-provider
Advanced tools
Comparing version 8.5.1 to 8.5.2
@@ -1,3 +0,1 @@ | ||
import * as url from 'node:url'; | ||
import upperFirst from '../../helpers/_/upper_first.js'; | ||
@@ -132,3 +130,3 @@ import camelCase from '../../helpers/_/camel_case.js'; | ||
{ | ||
path: url.parse(destination).pathname, | ||
path: new URL(destination, ctx.oidc.issuer).pathname, | ||
...cookieOptions, | ||
@@ -145,3 +143,3 @@ maxAge: ttl * 1000, | ||
...cookieOptions, | ||
path: url.parse(returnTo).pathname, | ||
path: new URL(returnTo).pathname, | ||
domain: undefined, | ||
@@ -148,0 +146,0 @@ httpOnly: true, |
@@ -1,3 +0,1 @@ | ||
import * as url from 'node:url'; | ||
import upperFirst from '../../helpers/_/upper_first.js'; | ||
@@ -82,3 +80,3 @@ import camelCase from '../../helpers/_/camel_case.js'; | ||
...cookieOptions, | ||
path: url.parse(ctx.oidc.urlFor(resumeRouteName, { uid: interactionSession.uid })).pathname, | ||
path: new URL(ctx.oidc.urlFor(resumeRouteName, { uid: interactionSession.uid })).pathname, | ||
}; | ||
@@ -85,0 +83,0 @@ ssHandler.set( |
import { strict as assert } from 'node:assert'; | ||
import * as url from 'node:url'; | ||
import * as querystring from 'node:querystring'; | ||
@@ -37,3 +36,3 @@ import { inspect } from 'node:util'; | ||
instance(provider).configuration('interactions').url = async function interactionUrl(ctx, interaction) { | ||
return url.parse(ctx.oidc.urlFor('interaction', { uid: interaction.uid })).pathname; | ||
return new URL(ctx.oidc.urlFor('interaction', { uid: interaction.uid })).pathname; | ||
}; | ||
@@ -40,0 +39,0 @@ |
@@ -1,3 +0,1 @@ | ||
import * as url from 'node:url'; | ||
import { CLIENT_ATTRIBUTES } from '../consts/index.js'; | ||
@@ -523,4 +521,5 @@ | ||
let protocol; | ||
let hash; | ||
try { | ||
({ hostname, protocol } = new URL(redirectUri)); | ||
({ hostname, protocol, hash } = new URL(redirectUri)); | ||
} catch (err) { | ||
@@ -530,4 +529,2 @@ this.invalidate(`${label} must only contain valid uris`); | ||
const { hash } = url.parse(redirectUri); | ||
if (hash) { | ||
@@ -534,0 +531,0 @@ this.invalidate(`${label} must not contain fragments`); |
import * as events from 'node:events'; | ||
import * as url from 'node:url'; | ||
@@ -97,3 +96,3 @@ import ctxRef from '../models/ctx_ref.js'; | ||
return url.resolve(this.ctx.href, provider.pathFor(name, { mountPath, ...opt })); | ||
return new URL(provider.pathFor(name, { mountPath, ...opt }), this.ctx.href).href; | ||
} | ||
@@ -100,0 +99,0 @@ |
@@ -1,23 +0,16 @@ | ||
import * as url from 'node:url'; | ||
import * as querystring from 'node:querystring'; | ||
export default function redirectUri(uri, payload, mode) { | ||
const parsed = url.parse(uri, true); | ||
const parsed = new URL(uri); | ||
parsed.search = null; | ||
// handles a case where url module adds unintended / to the pathname | ||
// i.e. http://www.example.com => http://www.example.com/ | ||
if (parsed.pathname === '/' && !uri.endsWith('/')) parsed.pathname = null; | ||
switch (mode) { | ||
case 'fragment': | ||
parsed.hash = querystring.stringify(payload); | ||
parsed.hash = new URLSearchParams(payload).toString(); | ||
break; | ||
default: | ||
Object.assign(parsed.query, payload); | ||
for (const [k, v] of Object.entries(payload)) { | ||
parsed.searchParams.set(k, v); | ||
} | ||
break; | ||
} | ||
return url.format(parsed); | ||
return parsed.href; | ||
} |
/* eslint-disable max-classes-per-file */ | ||
import { format } from 'node:url'; | ||
import * as crypto from 'node:crypto'; | ||
@@ -40,2 +39,14 @@ import { STATUS_CODES } from 'node:http'; | ||
function URLparse(url) { | ||
if (URL.parse) { | ||
return URL.parse(url); | ||
} | ||
try { | ||
return new URL(url); | ||
} catch { | ||
return null; | ||
} | ||
} | ||
const validateJWKS = (jwks) => { | ||
@@ -115,6 +126,2 @@ if (jwks !== undefined) { | ||
function stripFragment(uri) { | ||
return format(new URL(uri), { fragment: false }); | ||
} | ||
function deriveEncryptionKey(secret, length) { | ||
@@ -510,12 +517,8 @@ const digest = length <= 32 ? 'sha256' : length <= 48 ? 'sha384' : length <= 64 ? 'sha512' : false; // eslint-disable-line no-nested-ternary | ||
redirectUriAllowed(value) { | ||
let parsed; | ||
try { | ||
parsed = new URL(value); | ||
} catch (err) { | ||
return false; | ||
} | ||
const parsed = URLparse(value); | ||
if (!parsed) return false; | ||
const match = this.redirectUris.includes(value); | ||
const match = this.redirectUris.find((allowed) => URLparse(allowed)?.href === parsed.href); | ||
if ( | ||
match | ||
!!match | ||
|| this.applicationType !== 'native' | ||
@@ -525,3 +528,3 @@ || parsed.protocol !== 'http:' | ||
) { | ||
return match; | ||
return !!match; | ||
} | ||
@@ -532,4 +535,5 @@ | ||
return !!this.redirectUris | ||
.find((registeredUri) => { | ||
const registered = new URL(registeredUri); | ||
.find((allowed) => { | ||
const registered = URLparse(allowed); | ||
if (!registered) return false; | ||
registered.port = ''; | ||
@@ -541,8 +545,18 @@ return parsed.href === registered.href; | ||
requestUriAllowed(uri) { | ||
const requested = stripFragment(uri); | ||
return !!(this.requestUris || []).find((enabled) => requested === stripFragment(enabled)); | ||
const requested = URLparse(uri); | ||
if (!requested) return false; | ||
requested.hash = ''; | ||
return !!this.requestUris?.find((enabled) => { | ||
const parsed = URLparse(enabled); | ||
if (!parsed) return false; | ||
parsed.hash = ''; | ||
return requested.href === parsed.href; | ||
}); | ||
} | ||
postLogoutRedirectUriAllowed(uri) { | ||
return this.postLogoutRedirectUris.includes(uri); | ||
postLogoutRedirectUriAllowed(value) { | ||
const parsed = URLparse(value); | ||
if (!parsed) return false; | ||
return !!this.postLogoutRedirectUris | ||
.find((allowed) => URLparse(allowed)?.href === parsed.href); | ||
} | ||
@@ -549,0 +563,0 @@ |
// eslint-disable-next-line import/order | ||
import * as attention from './helpers/attention.js'; | ||
import * as url from 'node:url'; | ||
import { strict as assert } from 'node:assert'; | ||
@@ -104,7 +103,9 @@ import * as events from 'node:events'; | ||
const components = url.parse(issuer); | ||
assert(components.host, 'Issuer Identifier must have a host component'); | ||
assert(components.protocol, 'Issuer Identifier must have an URI scheme component'); | ||
assert(!components.search, 'Issuer Identifier must not have a query component'); | ||
assert(!components.hash, 'Issuer Identifier must not have a fragment component'); | ||
const { | ||
host, protocol, search, hash, href, | ||
} = new URL(issuer); | ||
assert(host, 'Issuer Identifier must have a host component'); | ||
assert(protocol, 'Issuer Identifier must have an URI scheme component'); | ||
assert(!search && !href.endsWith('?'), 'Issuer Identifier must not have a query component'); | ||
assert(!hash && !href.endsWith('#'), 'Issuer Identifier must not have a fragment component'); | ||
@@ -156,3 +157,3 @@ super(); | ||
this.#OIDCContext = getContext(this); | ||
const { pathname } = url.parse(this.issuer); | ||
const { pathname } = new URL(this.issuer); | ||
this.#mountPath = pathname.endsWith('/') ? pathname.slice(0, -1) : pathname; | ||
@@ -169,3 +170,5 @@ instance(this).requestUriCache = new RequestUriCache(this); | ||
urlFor(name, opt) { return url.resolve(this.issuer, this.pathFor(name, opt)); } | ||
urlFor(name, opt) { | ||
return new URL(this.pathFor(name, opt), this.issuer).href; | ||
} | ||
@@ -172,0 +175,0 @@ registerGrantType(name, handler, params, dupes) { |
{ | ||
"name": "oidc-provider", | ||
"version": "8.5.1", | ||
"version": "8.5.2", | ||
"description": "OAuth 2.0 Authorization Server implementation for Node.js with OpenID Connect", | ||
@@ -60,7 +60,7 @@ "keywords": [ | ||
"@koa/cors": "^5.0.0", | ||
"@koa/router": "^12.0.1", | ||
"debug": "^4.3.5", | ||
"eta": "^3.4.0", | ||
"@koa/router": "^13.1.0", | ||
"debug": "^4.3.7", | ||
"eta": "^3.5.0", | ||
"got": "^13.0.0", | ||
"jose": "^5.6.2", | ||
"jose": "^5.9.4", | ||
"jsesc": "^3.0.2", | ||
@@ -72,6 +72,6 @@ "koa": "^2.15.3", | ||
"quick-lru": "^7.0.0", | ||
"raw-body": "^2.5.2" | ||
"raw-body": "^3.0.0" | ||
}, | ||
"devDependencies": { | ||
"@fastify/middie": "^8.3.1", | ||
"@fastify/middie": "^8.3.3", | ||
"@hapi/hapi": "^21.3.10", | ||
@@ -84,17 +84,16 @@ "@koa/ejs": "^5.1.0", | ||
"desm": "^1.3.1", | ||
"eslint": "^8.57.0", | ||
"eslint": "^8.57.1", | ||
"eslint-config-airbnb-base": "^15.0.0", | ||
"eslint-plugin-import": "^2.29.1", | ||
"express": "^4.19.2", | ||
"fastify": "^4.28.0", | ||
"helmet": "^7.1.0", | ||
"eslint-plugin-import": "^2.31.0", | ||
"express": "^4.21.1", | ||
"fastify": "^4.28.1", | ||
"helmet": "^7.2.0", | ||
"koa-body": "^6.0.1", | ||
"koa-mount": "^4.0.0", | ||
"koa-router": "^12.0.1", | ||
"lodash": "^4.17.21", | ||
"mocha": "^10.5.2", | ||
"mocha": "^10.7.3", | ||
"moment": "^2.30.1", | ||
"nock": "^13.5.4", | ||
"nock": "^13.5.5", | ||
"selfsigned": "^2.4.1", | ||
"sinon": "^18.0.0", | ||
"sinon": "^18.0.1", | ||
"supertest": "^7.0.0", | ||
@@ -101,0 +100,0 @@ "timekeeper": "^2.3.1" |
@@ -62,2 +62,3 @@ # oidc-provider | ||
## Certification | ||
[<img width="184" height="96" align="right" src="https://cdn.jsdelivr.net/gh/panva/node-oidc-provider@acd3ebf2f5ebbb5605463cb681a1fb2ab9742ace/OpenID_Certified.png" alt="OpenID Certification">][openid-certified-link] | ||
@@ -75,4 +76,10 @@ Filip Skokan has [certified][openid-certified-link] that [oidc-provider][npm-url] | ||
[<img height="65" align="left" src="https://cdn.auth0.com/blog/github-sponsorships/brand-evolution-logo-Auth0-horizontal-Indigo.png" alt="auth0-logo">][sponsor-auth0] If you want to quickly add OpenID Connect authentication to Node.js apps, feel free to check out Auth0's Node.js SDK and free plan. [Create an Auth0 account; it's free!][sponsor-auth0]<br><br> | ||
<picture> | ||
<source media="(prefers-color-scheme: dark)" srcset="./sponsor/Auth0byOkta_dark.png"> | ||
<source media="(prefers-color-scheme: light)" srcset="./sponsor/Auth0byOkta_light.png"> | ||
<img height="65" align="left" alt="Auth0 by Okta" src="./sponsor/Auth0byOkta_light.png"> | ||
</picture> | ||
If you want to quickly add OpenID Connect authentication to Node.js apps, feel free to check out Auth0's Node.js SDK and free plan. [Create an Auth0 account; it's free!][sponsor-auth0]<br><br> | ||
## Support | ||
@@ -89,30 +96,33 @@ | ||
```js | ||
import Provider from 'oidc-provider'; | ||
import Provider from 'oidc-provider' | ||
const configuration = { | ||
// refer to the documentation for other available configuration | ||
clients: [{ | ||
client_id: 'foo', | ||
client_secret: 'bar', | ||
redirect_uris: ['http://lvh.me:8080/cb'], | ||
// ... other client properties | ||
}], | ||
}; | ||
clients: [ | ||
{ | ||
client_id: 'foo', | ||
client_secret: 'bar', | ||
redirect_uris: ['http://lvh.me:8080/cb'], | ||
// ... other client properties | ||
}, | ||
], | ||
} | ||
const oidc = new Provider('http://localhost:3000', configuration); | ||
const oidc = new Provider('http://localhost:3000', configuration) | ||
oidc.listen(3000, () => { | ||
console.log('oidc-provider listening on port 3000, check http://localhost:3000/.well-known/openid-configuration'); | ||
}); | ||
console.log( | ||
'oidc-provider listening on port 3000, check http://localhost:3000/.well-known/openid-configuration', | ||
) | ||
}) | ||
``` | ||
## Recipes | ||
## Recipes | ||
Collection of useful configuration use cases are available over at [recipes](/recipes). | ||
## Events | ||
## Events | ||
oidc-provider instances are event emitters, using event handlers you can hook into the various | ||
actions and i.e. emit metrics that react to specific triggers. See the list of available emitted [event names](/docs/events.md) and their description. | ||
[npm-url]: https://www.npmjs.com/package/oidc-provider | ||
@@ -137,3 +147,3 @@ [openid-certified-link]: https://openid.net/certification/ | ||
[jwt-introspection]: https://tools.ietf.org/html/draft-ietf-oauth-jwt-introspection-response-10 | ||
[sponsor-auth0]: https://a0.to/try-auth0 | ||
[sponsor-auth0]: https://auth0.com/signup?utm_source=external_sites&utm_medium=panva&utm_campaign=devn_signup | ||
[mtls]: https://www.rfc-editor.org/rfc/rfc8705.html | ||
@@ -140,0 +150,0 @@ [dpop]: https://www.rfc-editor.org/rfc/rfc9449.html |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
549283
24
14146
159
+ Added@koa/router@13.1.0(transitive)
+ Addediconv-lite@0.6.3(transitive)
+ Addedraw-body@3.0.0(transitive)
- Removed@koa/router@12.0.2(transitive)
- Removediconv-lite@0.4.24(transitive)
- Removedmethods@1.1.2(transitive)
- Removedraw-body@2.5.2(transitive)
Updated@koa/router@^13.1.0
Updateddebug@^4.3.7
Updatedeta@^3.5.0
Updatedjose@^5.9.4
Updatedraw-body@^3.0.0