{"_id":"keycloak-express-middleware","_rev":"37-a580e2b5ae7609746c98691e46a20198","name":"keycloak-express-middleware","dist-tags":{"latest":"6.3.4"},"versions":{"2.0.1":{"name":"keycloak-express-middleware","version":"2.0.1","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@2.0.1","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/aromanino/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/aromanino/keycloak-express-middleware/issues"},"dist":{"shasum":"843eb4a1b061381b0d4c6722b9dfbbf1835e7473","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-2.0.1.tgz","fileCount":11,"integrity":"sha512-ZL+R3C30AcabBHyZigv15szvfu083KrLkm5slTI9KNLcOVqKSMivOF95WxRakCtBoUI74OTKn3fBSvjdf6zVUg==","signatures":[{"sig":"MEQCIB8ecAeFbnXYu8VGc55BkX1E56PGWoMgMZfdCxqqvIsXAiBaXyimxe1ie9DuBP+sR+RtkrE0AqDXBS/WP8B9snolbw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191553},"main":"index.js","gitHead":"aed324a7d98b2ddb2603e0464aef55036ea2d86e","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/aromanino/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_2.0.1_1759747124435_0.08174937318057673","host":"s3://npm-registry-packages-npm-production"}},"2.0.2":{"name":"keycloak-express-middleware","version":"2.0.2","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@2.0.2","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/aromanino/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/aromanino/keycloak-express-middleware/issues"},"dist":{"shasum":"456b539c2bcb0573e446276c836912894e1dfaaa","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-2.0.2.tgz","fileCount":11,"integrity":"sha512-Z+EI3lBlYsBVtpkHkzIKyOyj5PZJ1yywYajlCEcyZO5kVPt+VpWT5HidKJK8ZXLIxT93mPUx6DSznq3bjYILPg==","signatures":[{"sig":"MEUCIFBVwx8bx5OyKELD23XZ24mgJqzcgy0dom2APleWbFTSAiEAk5DsGhbajnQb9r9rV1aPx6DTSTKTG/XCxPRN07MgNoo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191553},"main":"index.js","gitHead":"2abe4fd181938d55bb01157adc13912860ffd18a","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/aromanino/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_2.0.2_1759747210767_0.8772433178637773","host":"s3://npm-registry-packages-npm-production"}},"2.0.3":{"name":"keycloak-express-middleware","version":"2.0.3","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@2.0.3","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/aromanino/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/aromanino/keycloak-express-middleware/issues"},"dist":{"shasum":"0ee6ad2bbcc9756d9a2eaa386087cfa49441d46c","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-2.0.3.tgz","fileCount":11,"integrity":"sha512-IbFv92NnN1SbG9K7oT63WHSmYPM/OydikkK00taPnkwi3RMjbu9XKdy7yJzSsjpLg81pZjMdalV1JZWl+ghfFw==","signatures":[{"sig":"MEYCIQCU7Bz1uzDcMVV3KI+mqQ8NqN8aTj1XrXJWXLJMf85TAQIhALPYifzRRnLAeiqDmuMhpEYxFPse5m/XYCDg8FWZMHfv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191567},"main":"index.js","gitHead":"f581cc22db4085d638a0e70ecdfb5f4361c52ec7","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/aromanino/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_2.0.3_1759747563053_0.746749410689536","host":"s3://npm-registry-packages-npm-production"}},"2.0.4":{"name":"keycloak-express-middleware","version":"2.0.4","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@2.0.4","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/aromanino/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/aromanino/keycloak-express-middleware/issues"},"dist":{"shasum":"30bbfa47abe8624629617ae9c13cd0333ffe0c1d","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-2.0.4.tgz","fileCount":11,"integrity":"sha512-hNqJ/QDY4tTdQ+q5YiDX4rLwhlnVb1uDN63nJXiWsftAH5sWLULhWpIIs7z12gU3kPO+C+HYG/PgTReAS6qLrA==","signatures":[{"sig":"MEYCIQChnCMat+fBukBGhj07GjIBBJQTj6D9oHQI3iUXF7gh0QIhAJkebgGNYrIDW1gqqQM4FvjNls/wp64XX9qehk8Sc+PZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":191533},"main":"index.js","gitHead":"feed3904eb1b1c80a4f26fe5365ae9f4196e1eec","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/aromanino/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_2.0.4_1759748404137_0.9663812933756015","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"keycloak-express-middleware","version":"3.0.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@3.0.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/aromanino/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/aromanino/keycloak-express-middleware/issues"},"dist":{"shasum":"b09d3e3afd127a4ced13d3f710b2457672203ea6","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-3.0.0.tgz","fileCount":11,"integrity":"sha512-Q9vbs8BsyjZHPVBwo39R0cbUmzM/iHOlFxT3lvmXZCK4D2I+AhKgrGAJlYy+ILtVMC5ex2D3tPGQFy373oifRw==","signatures":[{"sig":"MEUCIQCvU3m3iNKqsTg+1ZEXq6I9PMynwDSdP+B3acefR7d5SwIgNx2eVROnwlFzfKQLnVs3u6IxWXfyKDHQKLhAdCNga+M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":190173},"main":"index.js","gitHead":"b2d47933c154ebc051e8affe815b274bdd9eacca","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/aromanino/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_3.0.0_1759761784621_0.2958267448592262","host":"s3://npm-registry-packages-npm-production"}},"3.0.5":{"name":"keycloak-express-middleware","version":"3.0.5","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@3.0.5","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"2c897d71900d656bf99c036e3b7dc4d19d77cbca","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-3.0.5.tgz","fileCount":10,"integrity":"sha512-4qpT1t01p+nCapPh1VwAY3yjAKurrdys3Mmmsj0HwnernvrfJC229xBxVjjomHG3FjBqHCM8kkbekTevS2WpLg==","signatures":[{"sig":"MEQCICcAhuYidb+zQDLDglE5SJGsLAtYUKBG3FTDr85InYuuAiBJFw08JpITGd8gTK/ofoqAqwM/18e1OmTlaFYw3h5Khw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":139959},"main":"index.js","gitHead":"ea67ffc7322d54ba047191648986179d4b01ee6e","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_3.0.5_1759930912148_0.5662573859029718","host":"s3://npm-registry-packages-npm-production"}},"3.0.6":{"name":"keycloak-express-middleware","version":"3.0.6","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@3.0.6","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"d7557025e2f5999e7793e654ec74f70cbee9dc6d","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-3.0.6.tgz","fileCount":10,"integrity":"sha512-7dGm+Cu/zUiOtJ0DpAcLACuMo7VR0j5gZcydlp8r05luYE2pcLD70t9uLEX++HTt7xaQcQG6m3YKN7SZF+WcOw==","signatures":[{"sig":"MEQCIDW1ZmtszWUarYpt8JT60M2wN0mzBwBpoGEXXqC7zs8FAiBDqIKkf9yDOctVS71PXV9ssgr32d2XIIsjKVRI8ZbUwA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":139931},"main":"index.js","gitHead":"f575064ef361a1add37942c10bb4617c30185fe0","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_3.0.6_1759932181237_0.1281010913074554","host":"s3://npm-registry-packages-npm-production"}},"3.0.7":{"name":"keycloak-express-middleware","version":"3.0.7","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@3.0.7","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"d70dcf2182e2e36aa362dd8a1c6feda14803a329","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-3.0.7.tgz","fileCount":10,"integrity":"sha512-pbD/B2YIGY7WegruimzAX8AJ5coMDOGyeGPgh4YhWOH1d86pWVqR64HL2p14t8qRXbHCffRfy8oa/F5ITLKaSg==","signatures":[{"sig":"MEQCIGxoBXtLeIXNX5hDTX9sVFkikM3/JaD7dJTDUw29zQxsAiApkiZk2XgDfH3rCdWLJfGFrnBKdA5gXCmAw7MLxuHcYg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":139938},"main":"index.js","gitHead":"9b6a051ae3a1b099c0cc676f23e947bb7e45896e","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_3.0.7_1760434271517_0.9069800922356779","host":"s3://npm-registry-packages-npm-production"}},"3.0.8":{"name":"keycloak-express-middleware","version":"3.0.8","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@3.0.8","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"c5a843e065261ff5e26b1960306c3af171132fb8","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-3.0.8.tgz","fileCount":10,"integrity":"sha512-0W18H8RmrfV4f1Hdb8Hf7sIkS8EMXpCYS9AFv015Wpzh1xKmQudrqauZkzQXMxW/ks45Qw7i+d0ENCvJ/mPxiQ==","signatures":[{"sig":"MEQCIC46Ami+0X4j7RySeUhDWxeJdF/bNgDczcEra1DdwH9PAiBGhnq5TmAeXax53RIq26yhPeckuIZXEq0Okwv7CvPESw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":139937},"main":"index.js","gitHead":"b329bcfaae28719bd623988e4cfcb802add94744","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_3.0.8_1760434337791_0.11082039807886268","host":"s3://npm-registry-packages-npm-production"}},"3.0.9":{"name":"keycloak-express-middleware","version":"3.0.9","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@3.0.9","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"22aa1ccb14b9bc5aa09578edbfaca72cc299579a","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-3.0.9.tgz","fileCount":10,"integrity":"sha512-WKXe1v9gTeC9Xa81i/wPHub8aSGBqLzfgNlCdslqawExDbgLCWuzgcr7TPxlQ6NTLvBhha4Mur1sFt7dGfE47A==","signatures":[{"sig":"MEUCIQD3PCQbS0CgnaZkJEZplWWKFryKSfQFjFG1t8r66eAfvAIgHXJ9wCkh4xk/ufhl4FGFY3kQ+AAH7C3vKL6jdxMyPHk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":140358},"main":"index.js","gitHead":"61e34b84946839a647c88fd90f7a68329528cca9","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_3.0.9_1760547318622_0.5411767128428784","host":"s3://npm-registry-packages-npm-production"}},"4.0.0":{"name":"keycloak-express-middleware","version":"4.0.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.0.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"916d2f1e60acb1e6b8ca2947b19ea1d9156a6b82","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.0.0.tgz","fileCount":10,"integrity":"sha512-BvbRZq4ZZn/pLMApB3USs+oEMySJQKOQ3D29d2XKngjiObDGZI+Cth93YScYNTEkQdF4sNQNH/4WsGOh9vJB3Q==","signatures":[{"sig":"MEUCIFNlyUaPQ1Jn7K46IkmQThzBt0+FMqXYoKU+kA++2gPdAiEAsPHtxDfbnATUleFpaTeteJGhlGvLjPOlmjpGNIMA8ns=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":150121},"main":"index.js","gitHead":"9edc34900cb68ca9a849c57cfd884b5edb531738","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.0.0_1761735910813_0.753289313296662","host":"s3://npm-registry-packages-npm-production"}},"4.1.0":{"name":"keycloak-express-middleware","version":"4.1.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.1.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"ee04106aa3eb0ad71d8e53c6d4fcc004fdb0698c","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.1.0.tgz","fileCount":10,"integrity":"sha512-yQK6OLPnQgrL3fnG6MrhXCzZeO8K6GlKvpatta95ipbRGwaVUjJoE1BdVKMjuI2LyNGzSrfQC88UcyuREh8HSg==","signatures":[{"sig":"MEUCICO66neJCXjVwsd1LBXWHsl1VZi7Gv6PXVp7a/rDvzuDAiEA6YWbTBven8h3vvyondtBhS6GuYzvZ9Yte+Piun1bjW4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":150121},"main":"index.js","gitHead":"fdb3debe70ad2be929b9224d0b9433e9ca66ee51","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.1.0_1761737071026_0.521397281829205","host":"s3://npm-registry-packages-npm-production"}},"4.1.1":{"name":"keycloak-express-middleware","version":"4.1.1","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.1.1","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"6bdb858db312e4b2dac276bec73a76953001af15","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.1.1.tgz","fileCount":10,"integrity":"sha512-xI1eiILOYPlFpP3r9Tu6DfUfPLVzMmXr0D7ECFY1eWx6Oe/HwqqWocqb7nx1aCDoOb5gruPOG5rFhwT8gaj3gQ==","signatures":[{"sig":"MEQCIGEdo36zMKjQasszxOPeusTOMm1IYEh3S8f503OpmEDRAiBNlI6SaTE6vaH0Q8L8+p/miX02mwfnHRmPA/GYEbra0A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":150220},"main":"index.js","gitHead":"14416979684eefc666ec646429ef7cefe19fcd39","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.1.1_1761737361333_0.8878034814525471","host":"s3://npm-registry-packages-npm-production"}},"4.2.0":{"name":"keycloak-express-middleware","version":"4.2.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.2.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"03ae43a15f6bb170ab6cc41c12476ee8f38be331","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.2.0.tgz","fileCount":10,"integrity":"sha512-vgd/S0Rc/8eHams55jH63X9AcyecpX+qSyDiUm9Q4r6UVSeMq9YD7CfNReWZaWzTn3o21BkVtQc5/yABHpbtUw==","signatures":[{"sig":"MEUCIESCRt7+d8IMqo0ZcnzzBahUvYsfxqMmAtTbO7FcF/uBAiEA5AbMHPmNAwoAO7IXcuD4p5zBXo2hffga8qKpG0kx3nk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":150549},"main":"index.js","gitHead":"f5db590ad1e0dd2363c082fd69fb4187bb828b2b","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.2.0_1762255088546_0.00812063401713603","host":"s3://npm-registry-packages-npm-production"}},"4.2.1":{"name":"keycloak-express-middleware","version":"4.2.1","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.2.1","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"475c8d35e7dc7a29e2a6645dbfaf1121b9c3c74e","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.2.1.tgz","fileCount":10,"integrity":"sha512-DaLjcHiHMu3rNXu9GKw70zxq50HvI1fTcsB7erkYCstkr/axy8uq15oVo52+IchnGI2YhiCltGD1eCjWjxJYrA==","signatures":[{"sig":"MEQCIFklMmZGQY+h16W912X8jzm5fKjLW3znqgYDU2qLztntAiBEzBZhilQ43ymb0Od4VIb2OCqaruYq3LMcrw4X//m5Zg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":152187},"main":"index.js","gitHead":"98992f8fee7a5fd90bce1d6688d0d69b87216aea","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"10.9.0","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.2.1_1762257045574_0.11724525508408434","host":"s3://npm-registry-packages-npm-production"}},"4.3.0":{"name":"keycloak-express-middleware","version":"4.3.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.3.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"18dc4392c5120222ecd2f9e017c0f12f6a9a4253","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.3.0.tgz","fileCount":10,"integrity":"sha512-nNH1ksZb6b3638f9CsfQr4wi1iLadj6SGwgL94av4SoDdF/VLIW7o2/SfsIDTVVXy2wQIa9p/RX7VZViF4doDg==","signatures":[{"sig":"MEYCIQDGkWV5sBmL6hQ3x/Da2Urz7kIxKay/5KCO5Jd4slqm3wIhAInlvI11A9Aqkw1bhTOka6DGiZyPPeOi1l0lZliXnRIC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":152395},"main":"index.js","gitHead":"650c197aec56885a90ebddbd8ee6195846ac2c4e","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.3.0_1762450662079_0.5736278889740181","host":"s3://npm-registry-packages-npm-production"}},"4.4.0":{"name":"keycloak-express-middleware","version":"4.4.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.4.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"ba37a5179285b75e598d5af3d79dda73172c8878","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.4.0.tgz","fileCount":10,"integrity":"sha512-or+/IMM1TE1IfOPCsdguIX19mA+fiQ3XA90tdox0+E4ys6ZCP7Sol//smNUqoCFc0ppNB5V7zOQHTVqBi1DnMg==","signatures":[{"sig":"MEYCIQCogNhnos1hQLh0FNCvKk2s0Jk4KW1XeAoidbcGdx4VSgIhAItM9HSh1aFnbf3ZjLn6MJhfGAkE7jcv1jic/9XCeXWI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":152533},"main":"index.js","gitHead":"ddd7c099a2bad927c403f9c4b4e2edd0c6c279c9","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.4.0_1762450972475_0.09609050382711803","host":"s3://npm-registry-packages-npm-production"}},"4.4.1":{"name":"keycloak-express-middleware","version":"4.4.1","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.4.1","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"b70bc168f4ca964f10f7ce707d7dcd5e4a7b0485","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.4.1.tgz","fileCount":10,"integrity":"sha512-4LCioaD3HdLUQYGo00QPZmuyetNH/u3iLU6+uYD3cqHc/M3LlPMiSj3aP4H/ilsgIhvvfXvJHEeTx2fmvFo1Sg==","signatures":[{"sig":"MEUCID8rPUPJwMmEJSUiCvDSVopRcuILHZwejH/y50ozJM+3AiEAvhCIB2tZm+WGOhLaeSRuQxTGkApsuJyI+HWHtoE7Pdg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":152526},"main":"index.js","gitHead":"8d2d5ccfd8a95cde566195d63f67c4c2e6975297","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.4.1_1762453585584_0.7542810817674293","host":"s3://npm-registry-packages-npm-production"}},"4.4.2":{"name":"keycloak-express-middleware","version":"4.4.2","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.4.2","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"cb55b720fed377f4513b5b297e1db08bc3d2a283","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.4.2.tgz","fileCount":10,"integrity":"sha512-rWfXMf/99xcG6jTyfXZ2rKCssyCGeolxpuqVoWsgVC9pStCFZlH+vEb3EZ5PNOy7lJD1wl3G+edAMGJ1WgG3PQ==","signatures":[{"sig":"MEUCIQCuDul2dWyCNYD8fYWTD8wY69tRpMof1/SedPq+Ih9ecgIgPjQ/p+21nZJzuTVDR01hsWSC1o8Ew+A/wmTyb3Kvu2g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":153196},"main":"index.js","gitHead":"a20b30103a2ad5d71b1ac928f1272564f143cb0a","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.4.2_1762454342099_0.8847598930479417","host":"s3://npm-registry-packages-npm-production"}},"4.5.0":{"name":"keycloak-express-middleware","version":"4.5.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.5.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"51d91a989043f63025a239b7b449a26c20d489c1","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.5.0.tgz","fileCount":10,"integrity":"sha512-bn5nI/pRt9xdvHyNXiKN+H1nNW/7E04n+WHUMsSKsvmQzRRMndPLKCXrq024jzcI93shpzw2pbOe+jzkP78oyw==","signatures":[{"sig":"MEQCIHInBV+eNSg7qkNW36hHXr6njmiSAl56TxDEQ1snT9sjAiBemVNfyXUylZtJ2vLdSixo6fvWDvxpBWMxqZ4S5bwCsg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":153715},"main":"index.js","gitHead":"7dc711c52cd987fb04d751f2945e01e292dafc70","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","request":"^2.88.2","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^1.1.8","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"devDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.5.0_1762459446957_0.9078541246167429","host":"s3://npm-registry-packages-npm-production"}},"4.5.1":{"name":"keycloak-express-middleware","version":"4.5.1","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@4.5.1","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"ba3c490f9186c49e21d5a77d957859dd8421d55e","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-4.5.1.tgz","fileCount":10,"integrity":"sha512-GsGqh80EoCrTzwqDtfBKjZH3M5H168o2C1NzPcF1qEllMiZz0qWlTcPutrYOHS+MndHpeyRSL2/T/jl3HzJtUg==","signatures":[{"sig":"MEYCIQC85UEnOa9QluOPdzSDgKov5Nz4Vlyq2vS/RpeDNI6emQIhAPJvf6g8EJURM4gjBSxf7b1fi4aU6aE8s6xsuUsHKlRv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":153664},"main":"index.js","gitHead":"293d5af8be6ec3c8b33c892b06e42d432aaf2a5d","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_4.5.1_1762760515897_0.5244141048078577","host":"s3://npm-registry-packages-npm-production"}},"6.0.0":{"name":"keycloak-express-middleware","version":"6.0.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.0.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"6ab00688dcdf002d2ce6840285630cbb30149722","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.0.0.tgz","fileCount":10,"integrity":"sha512-56y2veRV4iiovcXlxftqSYFZA+ixVLHrUEsQaXY4vwvWQgUfolaFEcVZBtUlTMSUMBeVOuRJqQMfabTWWcL2Zw==","signatures":[{"sig":"MEYCIQD6bD8wHeZVbeEZWA6Pt1pDLkpXQMKI/qDW0IK/kJ+lQAIhAOOOleF6+nA4iKjogkY3K8kyPnE7uJLWDVD7GeTHH+wW","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":156323},"main":"index.js","gitHead":"2a5d1f0f0ee94d52761eb38ef8da8777780dca0e","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.0.0_1762946558819_0.3920224490866695","host":"s3://npm-registry-packages-npm-production"}},"6.0.1":{"name":"keycloak-express-middleware","version":"6.0.1","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.0.1","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"cb093f4ab4eeb761dade8e649b0b9d6bdf6a94b5","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.0.1.tgz","fileCount":10,"integrity":"sha512-/WZapveoIrP9ZuBRb+RWfWwbni2qAdI06XXQEz4gGdVGNGZ+NBs2PKqFSzL4Lwbq9BCujLPaNyjRWr80CGAP3Q==","signatures":[{"sig":"MEUCIQDb7ecTB/soTs8yZIwmmU41NRA2GI2iHm2jHwpBob2pZQIgQzrES1AjpWfSvujUXUYvfpAMEOAitxg5xRbav9PvgrQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":157082},"main":"index.js","gitHead":"71867375e101b241bf98a56f289a7cbf3667b903","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.0.1_1762955521362_0.4423887890871492","host":"s3://npm-registry-packages-npm-production"}},"6.0.2":{"name":"keycloak-express-middleware","version":"6.0.2","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.0.2","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"0209a5f6651fcc1dccc70af40c862e5c603dd9dd","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.0.2.tgz","fileCount":10,"integrity":"sha512-1YcVer4w+IS/y+dLuaObsn7Gmt8vp9bx7rhE3ceSWIrGQVvinnL+torwkQVPl7+j+sFdLEpHdiLssLw0aQnP/w==","signatures":[{"sig":"MEQCIGg9MEWqmpcLzeOjU1mXsj/8+hnQyg1twSCt6VJI4iLuAiB+PfItAcg1FCSsDlEF3citOj+IiHgDGYYye5Cp6TUEAw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":159698},"main":"index.js","gitHead":"56dcec096f528beb6a954c632824f534ccd8119c","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.0.2_1763116068469_0.09124510795402507","host":"s3://npm-registry-packages-npm-production"}},"6.0.3":{"name":"keycloak-express-middleware","version":"6.0.3","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.0.3","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"39e4602fafe5e9fc842ad0f7883dfe030e02f250","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.0.3.tgz","fileCount":10,"integrity":"sha512-4tKUM64lpY14R8JIgHQ4B8Cw5KvzMNhRcwAukjLPjdYQpNSzsZPx+twR1FARhj4ZtmoMp0hWWK4vcTyvx8Dk5Q==","signatures":[{"sig":"MEQCIGO/vB34MR5xmR4EfSzHAhj2TUwz0v9eKUuVNyKa1I9+AiA89ajbLREgV1MUglpDLFdTzC/P5dRWlO+wBouNJz6LTA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":157958},"main":"index.js","gitHead":"b14169d2a46f546b1ce1a534b079f8dc9fb3bb23","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.0.3_1770714751195_0.08538097384153231","host":"s3://npm-registry-packages-npm-production"}},"6.0.4":{"name":"keycloak-express-middleware","version":"6.0.4","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.0.4","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"13d96ae81c31ac82d5494954864c30b4d8d7906e","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.0.4.tgz","fileCount":10,"integrity":"sha512-BgDhowgDk83B8RBUHs6NrsP2hn1TOBpeefgJoYJqFt8VrvNBGN7xMizbhd1s8YjYDMAoX1pdDlwfvYS38Wtivw==","signatures":[{"sig":"MEUCIBiNmN0EaJn2v1R4Ctm5KcFlfdoPS5hHWnpSLfgR1JhuAiEAyGLYqRDnjb6RkIQv00TZs3avjm8LVfgAI/E6qjMWQV0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":158149},"main":"index.js","gitHead":"c5a143cbeae5a87ce7deb32ca5a38c5dc839e0f4","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.0.4_1770718788227_0.7300603885564372","host":"s3://npm-registry-packages-npm-production"}},"6.0.5":{"name":"keycloak-express-middleware","version":"6.0.5","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.0.5","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"03ee34251e416baea30b489a8586cf9b16029fad","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.0.5.tgz","fileCount":10,"integrity":"sha512-1tU0gWIJipAJdCmMJs17flES/5eKyNm1oxEEgHRuIV562d4WTFtqsMqXh18FbrhhunLMNlWcta2u85cLqXgQTA==","signatures":[{"sig":"MEYCIQD9fmeeIZbA3nzIe4BpOPsqAATivzmqq8wIqTC1RiPdOgIhAOr9d4v8jr1zV5dtMEgfVBJYREmvUaBUYcZYDSOEonRm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":162187},"main":"index.js","gitHead":"2bb3b1f88f0313b06a8bb92fd4689fd24c3dea37","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.0.5_1770731485155_0.08804038788419222","host":"s3://npm-registry-packages-npm-production"}},"6.1.0":{"name":"keycloak-express-middleware","version":"6.1.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.1.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"ea502be2d320fc0d1ed5189b08a87382ee9bf743","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.1.0.tgz","fileCount":14,"integrity":"sha512-UKHw7CNcJHggtLyh7BIq3L6Jm59xi3ETTfNcHfxK99PMerOhcWFptgS3jdMXWxKgPNZDH269YjaRgBWPfxn3tg==","signatures":[{"sig":"MEYCIQCNfwadllcAwt+3gBXdxa6dDHmGpGMdI7XjfpmzYQUUewIhALy7Aep+VBtOz3aKRnRJ4lc0IjN4RiuWRw2QOLcHWBjN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":208298},"main":"index.js","gitHead":"4394f939acc9e5f1ae6f663f65513923d67db0f0","scripts":{"test":"mocha"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.1.0_1771515232085_0.5637015837597652","host":"s3://npm-registry-packages-npm-production"}},"6.1.1":{"name":"keycloak-express-middleware","version":"6.1.1","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.1.1","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"b3d64a051e8afda081de3d55a1de9d9b4d83bcf2","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.1.1.tgz","fileCount":38,"integrity":"sha512-ZbLR8k+Ubunp1HNOsPCnRHo7HaTx3ttLZ6LW/DKjvRUdPh0W3F9+Xt4xyV8HNVwrX/oL9MF3+XyGk+eOlI/hhA==","signatures":[{"sig":"MEYCIQDGS/KKFieY3CthwRL/SDc90M2vouuYazba8+zdere0jwIhAJsu2z+AJ1Xk8wt9YQFU7qefc8P7PebjEFotjN8VNFok","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":325602},"main":"index.js","exports":{".":{"import":"./index.js","default":"./index.js","require":"./index.js"}},"gitHead":"c7222a556c64400993387ebc187ad2d76e583019","scripts":{"test":"NODE_ENV=test node test/helpers/keycloak-setup.js && npm --prefix test install && npm --prefix test test","setup-keycloak":"eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && NODE_ENV=test node test/docker-keycloak/setup-keycloak.js"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.1.1_1771941626239_0.09231094932708106","host":"s3://npm-registry-packages-npm-production"}},"6.1.2":{"name":"keycloak-express-middleware","version":"6.1.2","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.1.2","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"584818d1e1be9b9a6e0aa86333a5077643d6e9e4","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.1.2.tgz","fileCount":46,"integrity":"sha512-eNaiTBRCXs9ZZ5C0ytmYX7+2Pc7Rt3H4afmCrGcAxGHRgyJxr/XBV4Oj0UDjHFJ0Se+4uHVvhpFme2gbImcbKw==","signatures":[{"sig":"MEYCIQDxPZmUV6Z/9AF0QQhd33zFmJFo3d2vawq87NY1uyIDkwIhAJKI/giP6i/YORuYzDoyvLZ/BAZWrTiR05W9G/ehqyJh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":343335},"main":"index.js","exports":{".":{"import":"./index.js","default":"./index.js","require":"./index.js"}},"gitHead":"09f5d6120d1cfc50d8351d57383ca48c7f6a69a9","scripts":{"test":"NODE_ENV=test node test/helpers/keycloak-setup.js && npm --prefix test install && npm --prefix test test","setup-keycloak":"eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && NODE_ENV=test node test/docker-keycloak/setup-keycloak.js"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"async":"^3.2.6","debug":"^4.4.1","moment":"^2.30.1","morgan":"^1.10.0","express":"^5.1.0","jwt-simple":"^0.5.6","underscore":"^1.13.7","body-parser":"^2.2.0","cookie-parser":"^1.4.7","serve-favicon":"^2.5.0","express-session":"^1.18.1","keycloak-connect":"^26.1.1","responseinterceptor":"^2.0.2","@keycloak/keycloak-admin-client":"^26.3.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.1.2_1773754695300_0.567685611356993","host":"s3://npm-registry-packages-npm-production"}},"6.1.3":{"name":"keycloak-express-middleware","version":"6.1.3","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.1.3","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"c6fb83674a4e8f56ca9103ceec84b4415f53c7d1","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.1.3.tgz","fileCount":44,"integrity":"sha512-+nymhkfAKW5JG7auMmgNqEOYnlHYz+rhp6Ih+sfKDh/jt322yYzVEJD82yHMCT1pDmoejtNbp7aEykh8XRXJAg==","signatures":[{"sig":"MEUCICERq12Q7nNmUuOF7RJdOeBC9KZrboooC6hIKDl8VvanAiEApMxP5DZ3s0oKwUBeensndAwzzdBqqnq4v2KLP0BLYnk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":354386},"main":"index.js","exports":{".":{"import":"./index.js","default":"./index.js","require":"./index.js"}},"gitHead":"59d6b544e78b16b4a552105b0270febfb0fc867d","scripts":{"test":"npm --prefix test install && npm --prefix test run setup-keycloak && NODE_PATH=./test/node_modules npm --prefix test test","setup-keycloak":"eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && NODE_ENV=test node test/docker-keycloak/setup-keycloak.js"},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"express-session":"^1.19.0","keycloak-connect":"^26.1.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.1.3_1773758361549_0.8432145446838093","host":"s3://npm-registry-packages-npm-production"}},"6.2.0":{"name":"keycloak-express-middleware","version":"6.2.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.2.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"b5aa04f776f76e950266f2562f7d3c78643fb9e0","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.2.0.tgz","fileCount":47,"integrity":"sha512-k64fFiiVy2QyTSlZv+h2fNeUaYgHDV/dBc8MR65lgxbq3Bkre9ESoT3ANod836LwJU+youzit6Kdd2xcUi1dhA==","signatures":[{"sig":"MEUCIH5k74c+MdtN46/Z+iNUSJXzaGxAHw2eED7WbNvyyTAPAiEAy4iB8srjCUtM1YCHt0IQ/gAjCbNh6sFXqWi30yTZEnA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":390110},"main":"index.js","exports":{".":{"import":"./index.js","default":"./index.js","require":"./index.js"}},"gitHead":"f759560cafc423953c6bcb91ff94271519b52368","scripts":{"test":"npm --prefix test install && npm --prefix test run setup-keycloak && NODE_PATH=./test/node_modules npm --prefix test test","setup-keycloak":"eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && NODE_ENV=test node test/docker-keycloak/setup-keycloak.js"},"typings":"index.d.ts","_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"express-session":"^1.19.0","keycloak-connect":"^26.1.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.2.0_1773820472711_0.004685372317794423","host":"s3://npm-registry-packages-npm-production"}},"6.3.0":{"name":"keycloak-express-middleware","version":"6.3.0","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.3.0","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"f2be9aef3eca658d5f484ffa49f468103a0e8d9d","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.3.0.tgz","fileCount":47,"integrity":"sha512-t1L+vwWeV1I4c8GNqNK4IL8/BZ8CjLNdTT3+SLmOYqrnWPi/QubaPobld7w3SFAR6xSkQzzLiwAvSlXBzv5yOQ==","signatures":[{"sig":"MEUCIQDbUFUh1aomig/k+IcBO+cVIYEMfVG/5+jfjT2yzAqjzwIge5zRFJKdTO0YrGss8PquWCbXLb0tNJR6nsr4s2Y3uzI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":453789},"main":"index.js","exports":{".":{"import":"./index.js","default":"./index.js","require":"./index.js"}},"gitHead":"80febc33aac455b46f1373260498b9d95503305a","scripts":{"test":"npm --prefix test install && npm --prefix test run setup-keycloak && NODE_PATH=./test/node_modules npm --prefix test test","setup-keycloak":"eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && NODE_ENV=test node test/docker-keycloak/setup-keycloak.js"},"typings":"index.d.ts","_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"express-session":"^1.19.0","keycloak-connect":"^26.1.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.3.0_1773830015623_0.8871037292088606","host":"s3://npm-registry-packages-npm-production"}},"6.3.1":{"name":"keycloak-express-middleware","version":"6.3.1","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.3.1","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"fc403083b2471b5671d2f20a7655f40332b52255","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.3.1.tgz","fileCount":47,"integrity":"sha512-0cs0cLlFOOSbv3VVBoQZiKKoQvDaDRXdXpmwQGb9uS4GGnIuOKMFE6ggrNkXMV7wsA8DuicUU9R63abstXHFcw==","signatures":[{"sig":"MEQCID7z1uUJK65qR6xX1fX5bUy51LFAOaEVDJsB+eVjbhwpAiAU9wj3BpbvdsbyXRfLSn1Es2mgJ8VVTEOPGGZl5/YW9A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":443359},"main":"index.js","exports":{".":{"import":"./index.js","default":"./index.js","require":"./index.js"}},"gitHead":"a13732c4d616a515658c4a8b2f48d0652a817800","scripts":{"test":"npm --prefix test install && npm --prefix test run setup-keycloak && NODE_PATH=./test/node_modules npm --prefix test test","setup-keycloak":"eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && NODE_ENV=test node test/docker-keycloak/setup-keycloak.js"},"typings":"index.d.ts","_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"express-session":"^1.19.0","keycloak-connect":"^26.1.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.3.1_1773831898978_0.47191123536574575","host":"s3://npm-registry-packages-npm-production"}},"6.3.2":{"name":"keycloak-express-middleware","version":"6.3.2","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.3.2","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"476cc6d1dbd341f6c8c4625a6b3f971454fc7952","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.3.2.tgz","fileCount":46,"integrity":"sha512-54WJ5ur7f+vF3Qdg/0hLFekcRWrF8ME1lUxKiz6c8UesMw4527R6JO7fFHt/UlXPob5JEVD7i8sBWom9nrE3Rw==","signatures":[{"sig":"MEYCIQDzYxJQgaXImpP6FOeSoGVderJBlyY4S9M0Jfg8oG3UCwIhAIhBPQmOrQ8XlQYo8MZ/cHpzpdtvFj4I5EYv6DlLeL10","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":447079},"main":"index.js","exports":{".":{"import":"./index.js","default":"./index.js","require":"./index.js"}},"gitHead":"838abbc6318ab5d96707c020eff185d80fcbf8ee","scripts":{"test":"node test/helpers/ensure-test-config.js && npm --prefix test install && npm --prefix test run setup-keycloak && NODE_PATH=./test/node_modules npm --prefix test test","setup-keycloak":"node test/helpers/ensure-test-config.js && eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && NODE_ENV=test node test/docker-keycloak/setup-keycloak.js"},"typings":"index.d.ts","_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"express-session":"^1.19.0","keycloak-connect":"^26.1.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.3.2_1773832342299_0.10109514281376497","host":"s3://npm-registry-packages-npm-production"}},"6.3.3":{"name":"keycloak-express-middleware","version":"6.3.3","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"url":"Crs4","name":"aromanino"},"license":"MIT","_id":"keycloak-express-middleware@6.3.3","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"dist":{"shasum":"186080b5ae2c68b2d3b15d3209d3fb3f78159e16","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.3.3.tgz","fileCount":46,"integrity":"sha512-IuqbMa7QcAh+4t8ptjJgz43T7RF6PTS1VnbdpnBoWG9DnDoWWb4YP6tDbeO80kQDgUhz/yZy3+tLAM+L7qVtcA==","signatures":[{"sig":"MEYCIQDv6suOmBhPcQ8lisLHDiNll1D1PY8m0VtN4JsJuPw8NQIhAOphrBxXVZtuNdGl0QVkCXq5kqiidPYtFU8D+bJmLNen","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":463677},"main":"index.js","exports":{".":{"import":"./index.js","default":"./index.js","require":"./index.js"}},"gitHead":"5428ac43164f8aff4b92f09bcd3165571bb190d6","scripts":{"test":"node test/helpers/ensure-test-config.js && npm --prefix test install && npm --prefix test run setup-keycloak && NODE_PATH=./test/node_modules npm --prefix test test","setup-keycloak":"node test/helpers/ensure-test-config.js && eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && NODE_ENV=test node test/docker-keycloak/setup-keycloak.js"},"typings":"index.d.ts","_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"repository":{"url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git","type":"git"},"_npmVersion":"11.6.2","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"express-session":"^1.19.0","keycloak-connect":"^26.1.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/keycloak-express-middleware_6.3.3_1773841652307_0.7830290787322178","host":"s3://npm-registry-packages-npm-production"}},"6.3.4":{"name":"keycloak-express-middleware","version":"6.3.4","description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","main":"index.js","typings":"index.d.ts","exports":{".":{"require":"./index.js","import":"./index.js","default":"./index.js"}},"scripts":{"test":"node test/helpers/ensure-test-config.js && npm --prefix test install && npm --prefix test run setup-keycloak && NODE_PATH=./test/node_modules npm --prefix test test","setup-keycloak":"node test/helpers/ensure-test-config.js && eval \"$(ssh-agent -s)\" && ssh-add ~/.ssh/id_ed25519 && NODE_ENV=test node test/docker-keycloak/setup-keycloak.js"},"dependencies":{"express-session":"^1.19.0","keycloak-connect":"^26.1.1"},"keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"author":{"name":"aromanino","url":"Crs4"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git"},"bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","gitHead":"4fba3f898ca21200c3b17c7286054ec91753d6e4","_id":"keycloak-express-middleware@6.3.4","_nodeVersion":"22.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-F5+oyFaU/t0107PlKfKY6UDzR0X5hVcDS/PDBDMwjdgnWegfVuy93ctRoV0fc6+ApsDbTX7R3ap7Uxy3SZSUfQ==","shasum":"a0a7928ea513db6317e55fadb7a05461688fe2f7","tarball":"https://registry.npmjs.org/keycloak-express-middleware/-/keycloak-express-middleware-6.3.4.tgz","fileCount":46,"unpackedSize":463910,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDsnVsT7zWjzLiqjOfYL6E/a+rbe5PWhCHjBX2m/EYJ5wIhALLgvfIPpVJ7uL6kaBZC5dVxwimjTlDRRCjr1USVlw4A"}]},"_npmUser":{"name":"aromanino","email":"a.romanino@gmail.com"},"directories":{},"maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/keycloak-express-middleware_6.3.4_1773843416338_0.07634066583760402"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-06T10:38:44.434Z","modified":"2026-03-18T14:16:56.702Z","2.0.1":"2025-10-06T10:38:44.645Z","2.0.2":"2025-10-06T10:40:10.987Z","2.0.3":"2025-10-06T10:46:03.229Z","2.0.4":"2025-10-06T11:00:04.411Z","3.0.0":"2025-10-06T14:43:04.812Z","3.0.5":"2025-10-08T13:41:52.353Z","3.0.6":"2025-10-08T14:03:01.428Z","3.0.7":"2025-10-14T09:31:11.706Z","3.0.8":"2025-10-14T09:32:17.966Z","3.0.9":"2025-10-15T16:55:18.840Z","4.0.0":"2025-10-29T11:05:10.998Z","4.1.0":"2025-10-29T11:24:31.260Z","4.1.1":"2025-10-29T11:29:21.522Z","4.2.0":"2025-11-04T11:18:08.718Z","4.2.1":"2025-11-04T11:50:45.768Z","4.3.0":"2025-11-06T17:37:42.299Z","4.4.0":"2025-11-06T17:42:52.666Z","4.4.1":"2025-11-06T18:26:25.782Z","4.4.2":"2025-11-06T18:39:02.292Z","4.5.0":"2025-11-06T20:04:07.210Z","4.5.1":"2025-11-10T07:41:56.113Z","6.0.0":"2025-11-12T11:22:39.013Z","6.0.1":"2025-11-12T13:52:01.615Z","6.0.2":"2025-11-14T10:27:48.663Z","6.0.3":"2026-02-10T09:12:31.346Z","6.0.4":"2026-02-10T10:19:48.371Z","6.0.5":"2026-02-10T13:51:25.309Z","6.1.0":"2026-02-19T15:33:52.273Z","6.1.1":"2026-02-24T14:00:26.382Z","6.1.2":"2026-03-17T13:38:15.460Z","6.1.3":"2026-03-17T14:39:21.717Z","6.2.0":"2026-03-18T07:54:32.872Z","6.3.0":"2026-03-18T10:33:35.794Z","6.3.1":"2026-03-18T11:04:59.132Z","6.3.2":"2026-03-18T11:12:22.470Z","6.3.3":"2026-03-18T13:47:32.465Z","6.3.4":"2026-03-18T14:16:56.588Z"},"bugs":{"url":"https://github.com/smartenv-crs4/keycloak-express-middleware/issues"},"author":{"name":"aromanino","url":"Crs4"},"license":"MIT","homepage":"https://github.com/smartenv-crs4/keycloak-express-middleware#readme","keywords":["keycloak","token","user","login","signin","session","ldap","federation","authentication","oauth","oauth2.0","sso","api","client","adapter","middleware","express"],"repository":{"type":"git","url":"git+https://github.com/smartenv-crs4/keycloak-express-middleware.git"},"description":"Adapter API to integrate Node.js (Express) applications with Keycloak. Provides middleware for authentication, authorization, token validation, and route protection via OpenID Connect.","maintainers":[{"name":"aromanino","email":"a.romanino@gmail.com"}],"readme":"# Keycloak Express Middleware for Node.js (Express)\nAn adapter API to integrate **Node.js Express** applications with **Keycloak** for authentication and authorization using **OpenID Connect (OIDC)**.\nThis middleware provides route protection, token validation, and user role management. It is ideal for securing RESTful services, microservices, Express-based backends, and JavaScript frontends.\nIt is based on **'keycloak-connect'** and **'express-session'**.\n\n## Menu\n\n- [Features](#features)\n- [Architecture Evolution Starting from v4.0.0](#architecture-evolution-starting-from-v400)\n- [Migration Guide: From Old to New Version](#migration-guide-from-old-to-new-version)\n- [Installation](#installation)\n- [Get Keycloak Configuration](#get-keycloak-configuration)\n- [Full Usage Example](#full-usage-example)\n- [Authorization Models (Introduction)](#authorization-models-introduction)\n    - [protect vs enforcer](#protect-vs-enforcer-when-to-use-each)\n- [API Documentation](#api-documentation)\n    - [Core Functions](#core-functions)\n        - [API - Constructor](#api---constructor)\n        - [API - underKeycloakProtection (deprecated)](#api---underkeycloakprotection-deprecated)\n    - [Middleware APIs](#middleware-apis)\n        - [API - protectMiddleware](#api---protectmiddlewareconditions)\n        - [API - customProtectMiddleware](#api---customprotectmiddlewarecustomfunction)\n        - [API - enforcerMiddleware](#api---enforcermiddlewareconditions-options)\n        - [API - customEnforcerMiddleware](#api---customenforcermiddlewarecustomfunction-options)\n        - [API - encodeTokenRole](#api---encodetokenrole)\n        - [API - encodeTokenPermission](#api---encodetokenpermission)\n        - [API - loginMiddleware](#api---loginmiddlewareredirectto)\n        - [API - logoutMiddleware](#api---logoutmiddlewareredirectto)\n    - [Imperative and OIDC Functions](#imperative-and-oidc-functions)\n        - [login vs loginPKCE vs loginWithCredentials](#login-vs-loginpkce-vs-loginwithcredentials-when-to-use-each)\n        - [loginMiddleware vs login](#loginmiddleware-vs-login-same-goal-different-style)\n        - [API - login](#api---loginreq-res-redirectto)\n        - [API - logout](#api---logoutreq-res-redirectto)\n        - [API - generateAuthorizationUrl](#api---generateauthorizationurloptions)\n        - [API - loginWithCredentials](#api---loginwithcredentialscredentials)\n        - [API - loginPKCE](#api---loginpkcecredentials)\n        - [API - redirectToUserAccountConsole](#api---redirecttouseraccountconsoleres)\n        - [API - hasScope](#api---hasscopescopeinput-requiredscope)\n        - [API - hasScopes](#api---hasscopesscopeinput-requiredscopes-mode)\n        - [API - getTokenClaims](#api---gettokenclaimsreq)\n        - [API - isAuthenticated](#api---isauthenticatedreq)\n        - [API - getScopes](#api---getscopesscopeinputorreq)\n        - [API - hasScopeFromRequest](#api---hasscopefromrequestreq-requiredscope)\n        - [API - hasScopesFromRequest](#api---hasscopesfromrequestreq-requiredscopes-mode)\n        - [API - requireScopes](#api---requirescopesrequiredscopes-mode)\n        - [API - getServiceToken](#api---getservicetokenoptions)\n        - [API - callProtectedApi](#api---callprotectedapioptions)\n- [Recipes and Patterns](docs/recipes.md)\n- [Handling Unauthorized Access (401/403) Gracefully](#handling-unauthorized-access-401403-gracefully)\n- [Testing Documentation](#testing-documentation)\n- [License](#license)\n- [Contributions](#contributions)\n- [Maintainer](#maintainer)\n\n\n---\n## Features\n- OIDC-based authentication with Keycloak\n- Access token validation (JWT)\n- Route protection via role-based access control\n- Automatic token refresh (optional)\n- Configurable Keycloak client and realm settings\n- User info extraction from token\n- CORS support and integration with frontend apps (SPA or mobile)\n---\n## Architecture Evolution Starting from v4.0.0\nVersion 4 introduced a substantial architecture evolution.\nIt now embraces an object-oriented paradigm, which means each instance of the middleware is self-contained and independent. \nConcretely, you can instantiate the library multiple times within the same application—each time pointing to a different client in Keycloak \nand the instances will not share internal connections or state across modules. \nThis is a major shift from the previous version (up to 3.0.9), where the library maintained a single shared \nconnection and did not support using distinct Keycloak clients simultaneously within the same \napplication scope.  By moving to this new ***one instance = one client*** model, you gain the flexibility to support scenarios such as:\n - a single Express application acting as multiple Keycloak clients, each with different realms, client IDs, or roles,\n - isolating middleware logic per client without risking cross-contamination of sessions or grants,\n - simplifying multi-tenancy or microservice architectures where different parts of an app authenticate against different Keycloak clients.\n \n**To summarize:** the new version (4.0.0+) enables multi-client usage within the same app by turning the middleware into configurable,\nindependent object instances, something that the earlier version did not support.\n\n### Migration Guide: From Old to New Version\n\nOld Version (pre-object-oriented)\n```js\n// OLD VERSION UP TO 3.0.9\nconst express = require('express');\nconst keycloakAdapter = require('keycloak-express-middleware');\n\nconst app = express();\nawait keycloakAdapter.configure(app,{\n        \"realm\": \"Realm-Project\",\n        \"auth-server-url\": \"https://YourKeycloakUrl:30040/\",\n        \"ssl-required\": \"external\",\n    \"resource\": \"keycloakClientName\",\n        \"credentials\": {\n            \"secret\": \"aaaaaaaaaa\"\n        },\n        \"confidential-port\": 0\n    },\n    {\n        session:{\n            secret: 'mySecretForSession',\n        }\n    });\n\n// Example of protection with keycloakAdapter.protectMiddleware middleware\n// with a static client role validation string\n// Access is allowed only for authenticated admin users\napp.get('/privateStaticClientRole', keycloakAdapter.protectMiddleware(\"admin\"), (req, res) => {\n    // \"Your Custom Code\"\n    res.send(\"You are an admin.\");\n});\n```\n\nNew Version (Object-Oriented Design) - Version 4.0.0+\n\n```js\n// NEW VERSION STARTING FROM 4.0.0\nconst express = require('express');\nconst keycloakAdapter = require('keycloak-express-middleware');\n\nconst app = express();\n\n// Create independent Keycloak clients\nconst keycloakA = new keycloakAdapter(app,{\n        \"realm\": \"Realm-Project\",\n        \"auth-server-url\": \"https://YourKeycloakUrl:30040/\",\n        \"ssl-required\": \"external\",\n    \"resource\": \"keycloakClientName_A\",\n        \"credentials\": {\n            \"secret\": \"aaaaaaaaaa\"\n        },\n        \"confidential-port\": 0\n    },\n    {\n        session:{\n            secret: 'mySecretForSession',\n        }\n    });\n\nconst keycloakB = new keycloakAdapter(app,{\n        \"realm\": \"Realm-Project\",\n        \"auth-server-url\": \"https://YourKeycloakUrl:30040/\",\n        \"ssl-required\": \"external\",\n    \"resource\": \"keycloakClientName_B\",\n        \"credentials\": {\n            \"secret\": \"aaaaaaaaaa\"\n        },\n        \"confidential-port\": 0\n    },\n    {\n        session:{\n            secret: 'mySecretForSession',\n        }\n    });\n\n\n\n// Example protected routes\napp.get('/clientA/secure', keycloakA.protectMiddleware(), (req, res) => {\n    res.send('Protected route for Client A');\n});\n\napp.get('/clientB/secure', keycloakB.protectMiddleware(), (req, res) => {\n    res.send('Protected route for Client B');\n});\n\napp.listen(3000, () => console.log('Server running on port 3000'));\n```\n\n---\n## Installation\n```bash\nnpm install keycloak-express-middleware\n```\nOr, if using Yarn:\n```bash\nyarn add keycloak-express-middleware\n```\n\n---\n## Get Keycloak Configuration\nCopy or download your client configuration `keycloak.json` from the Keycloak admin page:\nthe Keycloak Admin Console → clients (left sidebar) → choose your client → Installation → Format Option → Keycloak OIDC JSON → Download\n```json\n{\n  \"realm\": \"your-realm\",\n  \"auth-server-url\": \"https://your-keycloak-domain/auth\",\n  \"ssl-required\": \"external\",\n  \"resource\": \"your-client-id\",\n  \"credentials\": {\n    \"secret\": \"your-client-secret\"\n  },\n  \"confidential-port\": 0\n}\n```\n\n---\n## Full Usage Example\n```js\nconst express = require('express');\n// CommonJS - Default import\nconst keycloakAdapter = require('keycloak-express-middleware');\n\n// ES6 - Named import (recommended for clarity)\n// import { keycloackAdapter as keycloakAdapter } from 'keycloak-express-middleware';\n\n// ES6 - Default import\n// import keycloakAdapter from 'keycloak-express-middleware';\n\nconst app = express();\n\n\n// Configure and Initialize Keycloak adapter\nconst keycloakInstance = new keycloakAdapter(app,{\n        \"realm\": \"Realm-Project\",\n        \"auth-server-url\": \"https://YourKeycloakUrl:30040/\",\n        \"ssl-required\": \"external\",\n    \"resource\": \"keycloakClientName\",\n        \"credentials\": {\n            \"secret\": \"aaaaaaaaaa\"\n        },\n        \"confidential-port\": 0\n    },\n    {\n        session:{\n            secret: 'mySecretForSession',\n        }\n    });\n\n// -------------- Public route  -----------------------\napp.get('/', (req, res) => {\n  res.send('Public route: no authentication required');\n});\n\n\n/* ############## Protected routes (any authenticated user) ###########  */\n\n// Example of login with keycloakInstance.login function\n// After login redirect to \"/home\" \napp.get('/signIn', (req, res) => {\n    console.log(\"Your Custom Code\");\n    keycloakInstance.login(req,res,\"/home\")\n\n});\n\n// Example of login with keycloakInstance.loginMiddleware middleware\n// After login redirect to \"/home\" \napp.get('/loginMiddleware', keycloakInstance.loginMiddleware(\"/home\") ,(req, res) => {\n    // Response handled by middleware, this section will never be reached.\n});\n\n// Example of logout with keycloakInstance.logout function\n// After login redirect to \"http://localhost:3001/home\" \napp.get('/logout', (req, res) => {\n    console.log(\"Your Custom Code\");\n    keycloakInstance.logout(req,res,\"http://localhost:3001/home\");\n});\n\n// Example of logout with keycloakInstance.logoutMiddleware middleware\n// After login redirect to \"http://localhost:3001/home\"\napp.get('/logoutMiddle', keycloakInstance.logoutMiddleware(\"http://redirectUrl\"), (req, res) => {\n    // Response handled by middleware, this section will never be reached.\n});\n\n\n// Example of protection with keycloakInstance.protectMiddleware middleware\n// Access is allowed only for authenticated users\napp.get('/private', keycloakInstance.protectMiddleware(), (req, res) => {\n    console.log(\"Your Custom Code\");\n    console.log( req.session);\n    res.redirect('/auth');\n});\n\n// Example of protection with keycloakInstance.protectMiddleware middleware\n// with a static client role validation string\n// Access is allowed only for authenticated admin users\napp.get('/privateStaticClientRole', keycloakInstance.protectMiddleware(\"admin\"), (req, res) => {\n    // \"Your Custom Code\"\n    res.send(\"You are an admin.\");\n});\n\n// Example of protection with keycloakInstance.protectMiddleware middleware\n// with a static realm role validation string\n// Access is allowed only for authenticated realm admin users\napp.get('/privateStaticRealmRole', keycloakInstance.protectMiddleware(\"realm:admin\"), (req, res) => {\n    // \"Your Custom Code\"\n    res.send(\"You are a realm admin.\");\n});\n\n// Example of protection with keycloakInstance.protectMiddleware middleware\n// with a static other client role validation string\n// Access is allowed only for authenticated otherClient admin users\napp.get('/privateStaticOtherClientRole', keycloakInstance.protectMiddleware(\"otherClient:admin\"), (req, res) => {\n    // \"Your Custom Code\"\n    res.send(\"You are an admin of otherClient.\");\n});\n\n// Example of protection with keycloakInstance.protectMiddleware middleware\n// with a control function tmpFunction\n// Access is allowed only for authenticated admin users\nlet tmpFunction=function (token, req) {\n    return token.hasRole('admin');\n}\napp.get('/isAdmin', keycloakInstance.protectMiddleware(tmpFunction), (req, res) => {\n    // \"Your Custom Code\"\n    res.send(\"You are an admin (verified by tmpFunction).\");\n});\n\n\n// Example of protection with keycloakInstance.customProtectMiddleware middleware\n// with a control function tmpFunctionString\n// Access is allowed only for authenticated users with role defined by tmpFunctionString\nlet tmpFunctionString=function (req,res) {\n    let id=req.params.id\n    // Control String by url param Id \n    return (`${id}`);\n}\napp.get('/:id/isAdmin', keycloakInstance.customProtectMiddleware(tmpFunctionString), (req, res) => {\n    // \"Your Custom Code\"\n    res.send(\"You are an admin (verified by tmpFunctionString).\");\n});\n\n\n// Example of protection with keycloakInstance.encodeTokenRole middleware\n// Encode the token and add it to req.encodedTokenRole\n// Use req.encodedTokenRole.hasRole(\"role\") to check whether the token has that role or not\napp.get('/encodeToken', keycloakInstance.encodeTokenRole(), (req, res) => {\n    if(req.encodedTokenRole.hasRole('realm:admin'))\n        res.send(\"You are a realm admin\");\n    else\n        res.send(\"You are not a realm admin\");\n\n});\n\n\n// #####################################################################################\n// #   This section provides examples of how to protect resources based on permissions #\n// #   rather than roles.                                                              #                                \n// #####################################################################################\n\n\n// Example of protection with keycloakInstance.enforcerMiddleware middleware\n// with a static control string\n// Access is allowed only for users with 'ui-admin-resource' permission defined \n// in keycloak\napp.get('/adminResource', keycloakInstance.enforcerMiddleware('ui-admin-resource'), (req, res) => {\n    // If this section is reached, the user has the required privileges; \n    // otherwise, the middleware responds with a 403 Access Denied.\n    res.send('You are an authorized ui-admin-resource User');\n});\n\n// Example of protection with keycloakInstance.enforcerMiddleware middleware\n// with a control function tmpFunctionEnforceValidation\n// Access is allowed only for users with 'ui-admin-resource' or\n// ui-viewer-resource permission defined in keycloak\nlet tmpFunctionEnforceValidation=function (token,req,callback) {\n    // Check permission using token.hasPermission, which performs the verification\n    // and responds with a callback that returns true if the permission is valid, \n    // and false otherwise.\n    if(token.hasPermission('ui-admin-resource',function(permission){\n        if(permission) callback(true);\n        else if(token.hasPermission('ui-viewer-resource',function(permission){\n            if(permission) callback(true);\n            else callback(false);\n        }));\n    }));\n}\napp.get('/adminOrViewerResource', keycloakInstance.enforcerMiddleware(tmpFunctionEnforceValidation), (req, res) => {\n    // If this section is reached, the user has the required privileges \n    // driven by tmpFunctionEnforceValidation; otherwise, the middleware responds\n    // with a 403 Access Denied.\n    res.send('You are an authorized User');\n});\n\n\n// Example of protection with keycloakInstance.customEnforcerMiddleware middleware\n// with a control function tmpFunctionEnforce that define the control string\n// Access is allowed only for users with a url params ':permission' permission defined \n// in keycloak\nlet tmpFunctionEnforce=function (req,res) {\n    // Permission that depends on a URL parameter.\n    return(req.params.permission);\n}\napp.get('/urlParameterPermission/:permission', keycloakInstance.customEnforcerMiddleware(tmpFunctionEnforce), (req, res) => {\n    res.send(`You are an authorized User with ${req.params.permission} permission`);\n});\n\n// Example of protection with keycloakInstance.encodeTokenPermission middleware\n// Encode the token permission and add it to req.encodedTokenPermission\n// Use req.encodedTokenPermission.hasPermission(\"permission\") to check whether\n// the token has that permission or not\napp.get('/encodeTokenPermission', keycloakInstance.encodeTokenPermission(), (req, res) => {\n    // Check permission using token.hasPermission, which performs the verification\n    // and responds with a callback that returns true if the permission is valid, \n    // and false otherwise.\n    req.encodedTokenPermission.hasPermission('ui-admin-resource', function(permission){\n        if(permission)\n            res.send('You are an authorized User by ui-admin-resource permission');\n        else res.status(403).send(\"access Denied\");\n    });\n});\n\n\n// Example of direct token endpoint usage with keycloakInstance.loginWithCredentials\n// Useful for server-to-server operations (client credentials flow)\napp.get('/service-token', async (req, res) => {\n    try {\n        const tokenResponse = await keycloakInstance.loginWithCredentials({\n            grant_type: 'client_credentials',\n            scope: 'openid profile email'\n        });\n\n        res.json({\n            access_token: tokenResponse.access_token,\n            expires_in: tokenResponse.expires_in,\n            token_type: tokenResponse.token_type,\n            scope: tokenResponse.scope\n        });\n    } catch (err) {\n        res.status(401).json({\n            error: 'Token request failed',\n            details: err.message\n        });\n    }\n});\n\n\n\n// Start the server\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n  console.log(`Server running at http://localhost:${PORT}`);\n});\n```\n---\n\n## Authorization Models (Introduction)\n\nThis package exposes two different authorization families and multiple login/token flows.\nUnderstanding this distinction before reading the single-method API reference helps you select the correct integration strategy.\n\n### protect vs enforcer (when to use each)\n\nBoth protect routes, but they represent different security models.\n\n| Aspect | `protectMiddleware` | `enforcerMiddleware` |\n|---|---|---|\n| Core model | Role-based access control (RBAC) | Permission/policy-based access control (Authorization Services, UMA) |\n| Input | Roles (`admin`, `realm:admin`, `client:role`) | Resource/scope permissions (`invoice:read`, `report-resource:view`) |\n| Decision source | Token roles | Keycloak Authorization Services policies |\n| Setup complexity | Low | Medium/High |\n| Typical usage | Standard protected areas, role-gated endpoints | Fine-grained resource protection, ownership/scoped access |\n\nUse `protectMiddleware` when:\n\n- Your access rules are role-centric.\n- You need quick, explicit route-level authorization with minimal Keycloak policy setup.\n\nUse `enforcerMiddleware` when:\n\n- Access depends on resource and scope permissions.\n- You want policies managed in Keycloak and evaluated centrally.\n\nPractical examples:\n\n- `protectMiddleware('admin')`: endpoint reserved to users with admin role.\n- `enforcerMiddleware('invoice:approve')`: endpoint reserved to users with explicit permission to approve invoices.\n\n---\n## API Documentation\n\nThis section provides a complete reference for all public APIs exposed by the middleware class.\n\nReference conventions used below:\n\n- `Required`: whether the field must be provided by the caller.\n- `Middleware return`: function consumable by Express route registration.\n- Error sections include only explicit runtime errors thrown by the method itself.\n\n### Core Functions\n\n#### API - Constructor\n\n**Signature**\n\n```js\nnew keycloakAdapter(app, keycloakConfig, keycloakOptions = {})\n```\n\nCreates one isolated adapter instance bound to one Keycloak client.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `app` | `Object` | Yes | Express app or router instance. |\n| `keycloakConfig` | `Object` | Yes | Keycloak client configuration (`realm`, `auth-server-url`, `resource`, `credentials`, etc.). |\n| `keycloakOptions` | `Object` | No | Advanced adapter options (session and Keycloak behavior options). |\n\n**Supported `keycloakOptions` fields**\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `session` | `Object` | No | Enables internal session initialization with `express-session` + MemoryStore. |\n| `session.secret` | `string` | No | Session secret. |\n| `session.resave` | `boolean` | No | Express session `resave` option. |\n| `session.saveUninitialized` | `boolean` | No | Express session `saveUninitialized` option. |\n| `realmName` | `string` | No | Optional realm override. |\n| `clientId` | `string` | No | Optional client ID override. |\n| `clientSecret` | `string` | No | Optional client secret override. |\n| `scope`, `idpHint`, `cookies`, `realmUrl` | `string/object` | No | Forwarded to Keycloak adapter behavior. |\n\n**Returns**\n\n- Configured middleware instance.\n\n**Practical example - Basic configuration**\n\n```js\nconst keycloakInstance = new keycloakAdapter(app, keycloakConfig, {\n    session: {\n        secret: process.env.SESSION_SECRET,\n        resave: false,\n        saveUninitialized: false\n    }\n});\n```\n\n**Example - Multi-tenant setup (multiple Keycloak clients)**\n\n```js\n// Tenant A: separate Keycloak client\nconst keycloakTenantA = new keycloakAdapter(app, {\n    realm: 'tenant-a',\n    resource: 'tenant-a-client',\n    'auth-server-url': 'https://keycloak.example.com/',\n    credentials: { secret: process.env.TENANT_A_SECRET }\n}, { session: { secret: process.env.SESSION_SECRET } });\n\n// Tenant B: separate Keycloak client\nconst keycloakTenantB = new keycloakAdapter(app, {\n    realm: 'tenant-b',\n    resource: 'tenant-b-client',\n    'auth-server-url': 'https://keycloak.example.com/',\n    credentials: { secret: process.env.TENANT_B_SECRET }\n}, { session: { secret: process.env.SESSION_SECRET } });\n\n// Route for Tenant A\napp.get('/a/profile', keycloakTenantA.protectMiddleware(), (req, res) => {\n    res.json({ tenant: 'A', user: req.kauth.grant.access_token.content.preferred_username });\n});\n\n// Route for Tenant B\napp.get('/b/profile', keycloakTenantB.protectMiddleware(), (req, res) => {\n    res.json({ tenant: 'B', user: req.kauth.grant.access_token.content.preferred_username });\n});\n```\n\n#### API - underKeycloakProtection (deprecated)\n\n**Signature**\n\n```js\nunderKeycloakProtection(callback)\n```\n\nLegacy helper retained for backward compatibility. Executes `callback` when the middleware is ready.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `callback` | `Function` | Yes | Function that declares protected routes. |\n\n**Returns**\n\n- `void`.\n\n**Example**\n\n```js\nkeycloakInstance.underKeycloakProtection(() => {\n    app.get('/private', keycloakInstance.protectMiddleware(), handler);\n});\n```\n\n### Middleware APIs\n\n#### API - protectMiddleware(conditions)\n\n**Signature**\n\n```js\nprotectMiddleware(conditions)\n```\n\nProtects routes through authentication and optional role-based authorization.\n\n**What this API is for**\n\n- Use this middleware when access rules are based on roles and you want authorization directly on route declaration.\n- It is the default choice for RBAC scenarios such as admin/user/editor segmentation.\n\n**When to prefer it**\n\n- You already model permissions as roles in Keycloak.\n- You do not need policy-based, resource-level authorization.\n- You want a simple, readable route contract (role required is visible in code).\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `conditions` | `undefined \\| null \\| string \\| string[] \\| Function` | No | Access condition: authentication only, role expression(s), or custom predicate `(token, req) => boolean`. |\n\n**Role expression formats**\n\n- `'admin'`: role in configured client.\n- `'realm:admin'`: realm role.\n- `'clientid:role'`: role in another client.\n\n**Returns**\n\n- Middleware return.\n\n**Detailed behavior**\n\n- With no `conditions`, access is granted to any authenticated user.\n- With `string` or `string[]`, access is granted if the token has at least one matching role.\n- With a predicate function, your function decides access synchronously using token/request context.\n- On deny, Keycloak returns unauthorized/forbidden response according to adapter configuration.\n\n**Using `conditions` as a function**\n\nWhen `conditions` is a function, the middleware calls it with:\n\n- `token`: decoded Keycloak token helper object.\n- `req`: current Express request.\n\nThe function must return `true` (allow) or `false` (deny) synchronously.\nThis mode is useful when role checks must be combined with request-specific data (headers, params, query values, etc.).\n\n**Internal flow in practice**\n\n1. Middleware checks whether a valid Keycloak authentication context exists.\n2. If no role constraint is provided, authentication is sufficient.\n3. If role constraints are present, token roles are evaluated.\n4. If conditions fail, request is terminated with auth error handling.\n5. If conditions pass, control goes to next handler.\n\n**Notes**\n\n- Token claims are available at `req.kauth.grant.access_token.content` in downstream handlers.\n- This API is role-oriented, not permission-oriented.\n\n**Example**\n\n```js\napp.get('/admin', keycloakInstance.protectMiddleware('admin'), (req, res) => {\n    const token = req.kauth.grant.access_token.content;\n    res.json({ user: token.preferred_username, scope: token.scope });\n});\n```\n\n**Example with `conditions` as function**\n\n```js\napp.get('/editor-area', keycloakInstance.protectMiddleware((token, req) => {\n    const hasEditorRole = token.hasRealmRole('editor');\n    const trustedChannel = req.headers['x-access-channel'] === 'internal-ui';\n    return hasEditorRole && trustedChannel;\n}), (req, res) => {\n    res.send('Access granted by custom function condition');\n});\n```\n\n**Example - Role array (any role matches)**\n\n```js\n// Access granted if user has ANY of these roles\napp.get('/dashboard', keycloakInstance.protectMiddleware(['admin', 'manager', 'supervisor']), (req, res) => {\n    const token = req.kauth.grant.access_token.content;\n    res.json({ role: token.resource_access[keycloakConfig.resource]?.roles[0] });\n});\n```\n\n**Example - Realm role**\n\n```js\n// Access granted only to realm admins (global role, not client-specific)\napp.get('/realm-admin-only', keycloakInstance.protectMiddleware('realm:admin'), (req, res) => {\n    res.send('You have realm administration privileges');\n});\n```\n\n**Example - Time-based conditional access**\n\n```js\n// Route accessible only during business hours for non-admin users\napp.get('/restricted-time-area', keycloakInstance.protectMiddleware((token, req) => {\n    const isAdmin = token.hasRealmRole('admin');\n    if (isAdmin) return true; // Admins always allowed\n    \n    const hour = new Date().getHours();\n    return hour >= 9 && hour < 17; // Business hours only\n}), (req, res) => {\n    res.send('Access granted during business hours');\n});\n```\n\n#### API - customProtectMiddleware(customFunction)\n\n**Signature**\n\n```js\ncustomProtectMiddleware(customFunction)\n```\n\nBuilds role expressions dynamically from request context.\n\n**What this API is for**\n\n- Use this middleware when the required role is request-dependent (for example URL params, tenant id, or feature partition).\n- It avoids hardcoding one static role for every route variant.\n\n**When to prefer it**\n\n- One route family maps to many role names.\n- The role expression can be derived synchronously from request data.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `customFunction` | `Function` | Yes | `(req, res) => string`, returns role expression passed to Keycloak protect. |\n\n**Returns**\n\n- Middleware return.\n\n**Example - URL parameter based role**\n\n```js\napp.get('/tenant/:role', keycloakInstance.customProtectMiddleware((req) => {\n    return req.params.role;\n}), (req, res) => {\n    res.send(`Accessing tenant with role: ${req.params.role}`);\n});\n```\n\n**Example - Query parameter based role**\n\n```js\napp.get('/resource-access', keycloakInstance.customProtectMiddleware((req) => {\n    // Extract role from query: /resource-access?requiredRole=viewer\n    const role = req.query.requiredRole || 'user';\n    return role;\n}), (req, res) => {\n    res.json({ message: `Accessed with role requirement: ${req.query.requiredRole}` });\n});\n```\n\n**Example - Header-based role routing**\n\n```js\napp.get('/api/data', keycloakInstance.customProtectMiddleware((req) => {\n    // Role determined by custom header (useful for microservices)\n    const roleFromService = req.headers['x-required-role'] || 'user';\n    return roleFromService;\n}), (req, res) => {\n    res.json({ data: 'sensitive data' });\n});\n```\n\n#### API - enforcerMiddleware(conditions, options)\n\n**Signature**\n\n```js\nenforcerMiddleware(conditions, options)\n```\n\nPerforms permission checks via Keycloak Authorization Services (UMA 2.0).\n\n**What this API is for**\n\n- Use this middleware for fine-grained authorization where roles are not enough.\n- It is designed for resource/scope decisions evaluated by Keycloak policies.\n\n**When to prefer it**\n\n- Access depends on resource ownership, scopes, or dynamic claims.\n- You want authorization logic centralized in Keycloak Authorization Services.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `conditions` | `string \\| string[] \\| Function` | Yes | Static permission expression(s) or custom async evaluator `(token, req, callback)` where callback receives boolean. |\n| `options` | `Object` | No | Forwarded enforcer options. |\n\n**Supported `options` fields**\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `response_mode` | `'permissions' \\| 'token'` | No | Determines permission payload mode. |\n| `claims` | `Object` | No | Additional claims for policy evaluation. |\n| `resource_server_id` | `string` | No | Resource server client ID. |\n\n**Returns**\n\n- Middleware return.\n\n**Detailed behavior**\n\n- Evaluates permissions through Keycloak Authorization Services policies.\n- With `response_mode: 'permissions'`, granted permissions are exposed in `req.permissions`.\n- With `response_mode: 'token'`, Keycloak issues token with authorization details in token claims.\n- With function conditions, callback decides allow/deny after async permission checks.\n\n**Using `conditions` as a function**\n\nWhen `conditions` is a function, it is invoked with:\n\n- `token`: helper object exposing permission checks (for example `token.hasPermission(...)`).\n- `req`: current Express request.\n- `callback`: function that must be called with `true` (allow) or `false` (deny).\n\nThis mode is useful when authorization depends on multiple permissions or request-specific context (params, headers, tenant scope).\nUnlike `protectMiddleware` function mode, this flow is asynchronous and callback-driven.\n\n**Internal flow in practice**\n\n1. Middleware resolves static permission expression(s) or executes custom async evaluator.\n2. Keycloak evaluates policies against token + resource context.\n3. Result is surfaced as allowed/denied (and optionally permissions payload/token mode).\n4. Request continues only if policy evaluation grants access.\n\n**Keycloak prerequisites**\n\n- Client must have Authorization enabled.\n- Policy Enforcement Mode must be configured.\n- Resources, policies, and permissions must be defined in Keycloak.\n\n**Example - Simple resource permission**\n\n```js\napp.get('/report', keycloakInstance.enforcerMiddleware('report-resource:view'), (req, res) => {\n    res.render('report', { data: getReportData() });\n});\n```\n\n**Example - Multiple resource permissions (any)**\n\n```js\n// User needs at least ONE of these permissions\napp.get('/documents', keycloakInstance.enforcerMiddleware(\n    ['document:read', 'document:admin']\n), (req, res) => {\n    res.json({ documents: getDocuments() });\n});\n```\n\n**Example with `conditions` as function - resource-specific permission**\n\n```js\napp.get('/reports/:id', keycloakInstance.enforcerMiddleware((token, req, callback) => {\n    token.hasPermission(`report:${req.params.id}:read`, (canRead) => {\n        if (canRead) return callback(true);\n\n        // Fallback permission: user can still access summary-level view\n        token.hasPermission('report:summary:read', (canReadSummary) => {\n            callback(!!canReadSummary);\n        });\n    });\n}), (req, res) => {\n    res.send('Access granted to report');\n});\n```\n\n**Example - Ownership-based permission check**\n\n```js\n// User can only edit document they own\napp.put('/document/:docId', keycloakInstance.enforcerMiddleware((token, req, callback) => {\n    const docId = req.params.docId;\n    const userId = token.sub; // Subject claim from token\n    \n    // Check if user owns this document (could also call database)\n    token.hasPermission(`document:${docId}:edit`, (hasPermission) => {\n        // Additional ownership check from token claims if available\n        const isOwner = token.doc_owner_ids?.includes(docId);\n        callback(hasPermission && isOwner);\n    });\n}), (req, res) => {\n    res.json({ message: 'Document updated' });\n});\n```\n\n#### API - customEnforcerMiddleware(customFunction, options)\n\n**Signature**\n\n```js\ncustomEnforcerMiddleware(customFunction, options)\n```\n\nDynamic permission-check middleware that derives permission expressions from request context.\n\n**What this API is for**\n\n- Use this middleware when permission string must be generated per request (for example `resource:${id}:read`).\n- It combines dynamic request context with Keycloak Authorization Services evaluation.\n\n**When to prefer it**\n\n- Permission names are not static.\n- Resource identity comes from path/query/header data.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `customFunction` | `Function` | Yes | `(req, res) => string`, returns permission expression for enforcer. |\n| `options` | `Object` | No | Same options accepted by `enforcerMiddleware`. |\n\n**Returns**\n\n- Middleware return.\n\n**Example**\n\n```js\napp.get('/resource/:permission', keycloakInstance.customEnforcerMiddleware((req) => {\n    return req.params.permission;\n}), handler);\n```\n\n#### API - encodeTokenRole\n\n**Signature**\n\n```js\nencodeTokenRole()\n```\n\nExposes decoded token-role helpers on the request object.\n\n**What this API is for**\n\n- Use this middleware when you want to read role information inside business logic without enforcing a role gate at middleware declaration time.\n- Useful for adaptive responses (for example enhanced payload for admins).\n\n**Returns**\n\n- Middleware return.\n\n**Request augmentation**\n\n- Adds `req.encodedTokenRole`.\n- Common methods:\n- `hasRole('admin')`\n- `hasRole('realm:admin')`\n- `hasRole('clientid:editor')`\n- `hasResourceRole('editor', 'clientid')`\n\n**Example**\n\n```js\napp.get('/profile', keycloakInstance.encodeTokenRole(), (req, res) => {\n    const isRealmAdmin = req.encodedTokenRole.hasRole('realm:admin');\n    res.json({ isRealmAdmin });\n});\n```\n\n**Example - Conditional response enrichment**\n\n```js\n// Respond differently for admins vs regular users\napp.get('/user-data', keycloakInstance.encodeTokenRole(), (req, res) => {\n    const userData = { name: 'John', email: 'john@example.com' };\n    \n    if (req.encodedTokenRole.hasRole('admin')) {\n        userData.adminNotes = 'User account created 2024-01-15';\n        userData.accessLevel = 'full';\n    } else if (req.encodedTokenRole.hasRole('viewer')) {\n        userData.accessLevel = 'read-only';\n    } else {\n        // Remove sensitive fields for standard users\n        delete userData.email;\n    }\n    \n    res.json(userData);\n});\n```\n\n**Example - Role-based feature flags**\n\n```js\napp.get('/features', keycloakInstance.encodeTokenRole(), (req, res) => {\n    const features = {\n        basicSearch: true,\n        advancedAnalytics: req.encodedTokenRole.hasRole('premium'),\n        apiAccess: req.encodedTokenRole.hasRole('developer'),\n        adminPanel: req.encodedTokenRole.hasRole('realm:admin')\n    };\n    res.json(features);\n});\n```\n\n#### API - encodeTokenPermission\n\n**Signature**\n\n```js\nencodeTokenPermission()\n```\n\nAdds permission-check helper utilities to the request object.\n\n**What this API is for**\n\n- Use this middleware when you need conditional permission checks inside handler code rather than strict upfront route blocking.\n- Useful when a single endpoint supports multiple authorization branches.\n\n**Returns**\n\n- Middleware return.\n\n**Request augmentation**\n\n- Adds `req.encodedTokenPermission.hasPermission(permission, callback)`.\n\n**Helper parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `permission` | `string` | Yes | Permission expression to evaluate. |\n| `callback` | `Function` | Yes | Callback receiving `true` when allowed, `false` otherwise. |\n\n**Example**\n\n```js\napp.get('/can-read', keycloakInstance.encodeTokenPermission(), (req, res) => {\n    req.encodedTokenPermission.hasPermission('doc:read', (ok) => {\n        if (ok) return res.send('Allowed');\n        res.status(403).send('Denied');\n    });\n});\n```\n\n**Example - Multi-step permission checks**\n\n```js\napp.get('/document/:docId', keycloakInstance.encodeTokenPermission(), (req, res) => {\n    const docId = req.params.docId;\n    \n    req.encodedTokenPermission.hasPermission(`doc:${docId}:read`, (canRead) => {\n        if (!canRead) return res.status(403).json({ error: 'Cannot read document' });\n        \n        // User can read, check if they can edit\n        req.encodedTokenPermission.hasPermission(`doc:${docId}:edit`, (canEdit) => {\n            res.json({\n                document: getDocument(docId),\n                canEdit: canEdit,\n                canDelete: false // May check another permission\n            });\n        });\n    });\n});\n```\n\n**Example - Permission-based UI customization**\n\n```js\napp.get('/dashboard', keycloakInstance.encodeTokenPermission(), (req, res) => {\n    const permissions = { canCreate: false, canExport: false, canShare: false };\n    \n    // Cascade permission checks\n    req.encodedTokenPermission.hasPermission('resource:create', (can) => {\n        permissions.canCreate = !!can;\n    });\n    \n    req.encodedTokenPermission.hasPermission('resource:export', (can) => {\n        permissions.canExport = !!can;\n    });\n    \n    req.encodedTokenPermission.hasPermission('resource:share', (can) => {\n        permissions.canShare = !!can;\n        res.render('dashboard', permissions);\n    });\n});\n```\n\n#### API - loginMiddleware(redirectTo)\n\n**Signature**\n\n```js\nloginMiddleware(redirectTo)\n```\n\nForces authentication and redirects authenticated users to destination.\n\n**What this API is for**\n\n- Use this middleware for routes that should behave as login entry points.\n- Typical example: `/signin` route that always triggers authentication then navigates user to app page.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `redirectTo` | `string` | Yes | Post-login redirect URL. |\n\n**Returns**\n\n- Middleware chain (`protect` + redirect handler).\n\n**Operational note**\n\n- Route callback after this middleware is typically not reached.\n\n**Example**\n\n```js\napp.get('/signIn', keycloakInstance.loginMiddleware('/home'));\n```\n\n**Example - Login with post-login redirect to dashboard**\n\n```js\napp.get('/login', keycloakInstance.loginMiddleware('/dashboard'));\napp.get('/signin', keycloakInstance.loginMiddleware('/dashboard')); // Alternative URL\n```\n\n**Example - Login with locale parameter**\n\n```js\napp.get('/login/:lang', keycloakInstance.loginMiddleware((req) => {\n    // Redirect to different pages based on language preference\n    const locale = req.params.lang;\n    return `/${locale}/home`;\n}));\n```\n\n#### API - logoutMiddleware(redirectTo)\n\n**Signature**\n\n```js\nlogoutMiddleware(redirectTo)\n```\n\nDestroys local session and redirects through Keycloak logout endpoint when token is present.\n\n**What this API is for**\n\n- Use this middleware for clean logout endpoints that invalidate local session and, when possible, terminate Keycloak session.\n- Keeps logout behavior consistent and centralized in one middleware.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `redirectTo` | `string` | Yes | Post-logout redirect URL. |\n\n**Returns**\n\n- Middleware return.\n\n**Behavior**\n\n- If `id_token` exists, builds Keycloak logout URL and destroys session before redirect.\n- If token is missing, redirects directly to `redirectTo`.\n\n**Example**\n\n```js\napp.get('/signOut', keycloakInstance.logoutMiddleware('http://localhost:3000/'));\n```\n\n**Example - Logout with landing page**\n\n```js\n// Logout and redirect to goodbye page\napp.get('/logout', keycloakInstance.logoutMiddleware('/goodbye'));\napp.get('/goodbye', (req, res) => {\n    res.render('goodbye', { message: 'You have been logged out successfully' });\n});\n```\n\n**Example - Logout with external URL**\n\n```js\n// Logout and redirect to external domain\napp.get('/logout-and-redirect', keycloakInstance.logoutMiddleware('https://www.example.com'));\n```\n\n### Imperative and OIDC Functions\n\n#### login vs loginPKCE vs loginWithCredentials (when to use each)\n\nThese APIs belong to different layers of the authentication/token lifecycle.\n\nIn short:\n\n- `login(req, res, redirectTo)`: convenience helper for interactive browser login + redirect.\n- `loginPKCE(credentials)`: secure callback exchange for Authorization Code + PKCE flow.\n- `loginWithCredentials(credentials)`: low-level generic token endpoint client for multiple grants.\n\n| Aspect | `login(req, res, redirectTo)` | `loginPKCE(credentials)` | `loginWithCredentials(credentials)` |\n|---|---|---|---|\n| Main purpose | Trigger interactive browser login and redirect user | Exchange authorization code + PKCE verifier for tokens | Generic OAuth2 token endpoint call |\n| Typical phase | Login entry route in Express app | Callback route after authorization redirect | Programmatic token operations |\n| Input style | Express `req`/`res` + redirect target | `code`, `redirect_uri`, `code_verifier` (+ aliases) | `grant_type` + fields required by selected grant |\n| Output | Redirect side effect | Token payload | Token payload |\n| Best fit | Session/server-rendered flow | PKCE-based web/mobile/SPA/BFF flows | Low-level grant handling (refresh, client credentials, etc.) |\n\nHow to read this table:\n\n- `login(...)` is navigation-oriented (browser/session behavior).\n- `loginPKCE(...)` and `loginWithCredentials(...)` are token-oriented (you receive token objects to manage in code).\n\nUse `login(...)` when:\n\n- You want middleware-managed interactive login with redirect.\n- You are coding route-level navigation flow in Express.\n\n#### loginMiddleware() vs login() (same goal, different style)\n\nBoth APIs are designed to trigger interactive authentication and then redirect, but they are used in different coding styles.\n\n| Aspect | `loginMiddleware(redirectTo)` | `login(req, res, redirectTo)` |\n|---|---|---|\n| Type | Route middleware | Imperative helper function |\n| Where used | Directly in route declaration | Inside route handler body |\n| Handler execution | Usually not reached after middleware redirect flow | You can run custom logic before calling `login()` |\n| Best for | Standard login endpoint with minimal code | Conditional login or pre-login business logic |\n\nUse `loginMiddleware(...)` when:\n\n- You want a clean declarative route such as `app.get('/signin', keycloak.loginMiddleware('/home'))`.\n- You do not need custom pre-checks before triggering login.\n\nUse `login(...)` when:\n\n- You need to execute custom code before forcing authentication.\n- Login should happen only under specific runtime conditions.\n\nEquivalent intent examples:\n\n```js\n// Middleware style\napp.get('/signIn', keycloakInstance.loginMiddleware('/home'));\n\n// Imperative style\napp.get('/signIn', (req, res) => {\n    // Custom logic can run here first\n    keycloakInstance.login(req, res, '/home');\n});\n```\n\n> **Note:** `login(...)` was added as a convenience helper.\n> You can reach the same authentication result using `protectMiddleware()` and then redirect manually.\n\nEquivalent behavior with `protectMiddleware()`:\n\n```js\napp.get('/signIn', keycloakInstance.protectMiddleware(), (req, res) => {\n    res.redirect('/home');\n});\n```\n\nUse `loginPKCE(...)` when:\n\n- You already initiated PKCE with `generateAuthorizationUrl(...)`.\n- You are handling callback exchange securely using stored `codeVerifier`.\n\nWhat `loginPKCE(...)` actually does:\n\n- Validates required PKCE callback inputs (`code`, `redirect_uri`, `code_verifier`).\n- Calls the token endpoint with grant type `authorization_code` and PKCE verifier.\n- Returns token payload for your own persistence/session strategy.\n\nClient configuration note for PKCE:\n\n- `loginPKCE(...)` uses Authorization Code + PKCE and does **not** require `Direct Access Grants`.\n\nUse `loginWithCredentials(...)` when:\n\n- You need direct token endpoint operations (e.g., refresh token, client credentials, custom grant handling).\n- You need a reusable low-level method for different OAuth2 grant payloads.\n\nWhat `loginWithCredentials(...)` actually does:\n\n- Builds and sends a generic `application/x-www-form-urlencoded` token request.\n- Supports multiple grant models by payload (`password`, `client_credentials`, `authorization_code`, `refresh_token`).\n- Returns raw token endpoint response or throws error on failure.\n\nClient configuration note for non-browser password login:\n\n- When `loginWithCredentials(...)` is used with `grant_type=password`, the client must have `Direct Access Grants` enabled in Keycloak.\n- This means the client handles username/password directly and exchanges them with Keycloak token endpoint.\n- In OAuth2 terms, this enables `Resource Owner Password Credentials Grant` support for that client.\n\nRecommended PKCE sequence:\n\n1. Start flow with `generateAuthorizationUrl(...)` and persist `state` + `codeVerifier` server-side.\n2. Redirect user to generated authorization URL.\n3. Receive authorization `code` in callback.\n4. Exchange using `loginPKCE(...)`.\n5. Use/persist tokens according to your session/token strategy.\n\n#### API - login(req, res, redirectTo)\n\n**Signature**\n\n```js\nlogin(req, res, redirectTo)\n```\n\nImperative login helper intended for use inside route handlers.\n\n**What this API is for**\n\n- Use this function when login should happen conditionally inside handler logic.\n- Typical example: login only after validating custom preconditions.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `req` | `Object` | Yes | Express request. |\n| `res` | `Object` | Yes | Express response. |\n| `redirectTo` | `string` | Yes | Redirect destination after successful authentication. |\n\n**Returns**\n\n- `void`.\n\n**Detailed behavior**\n\n- Calls Keycloak protect flow immediately.\n- If authenticated, performs `res.redirect(redirectTo)`.\n- If not authenticated, user is redirected to Keycloak login.\n- Designed for imperative use inside a route where you may execute custom logic before triggering login.\n\n**Example**\n\n```js\napp.get('/login-if-needed', (req, res) => {\n    const needsInteractiveLogin = !req.session?.alreadyValidated;\n    if (!needsInteractiveLogin) return res.redirect('/home');\n    keycloakInstance.login(req, res, '/home');\n});\n```\n\n**Example - Login with audit logging**\n\n```js\napp.get('/signin', (req, res) => {\n    console.log(`Login attempt from IP: ${req.ip}`);\n    req.session.loginAttemptTime = new Date();\n    keycloakInstance.login(req, res, '/dashboard');\n});\n```\n\n**Example - Conditional login based on session state**\n\n```js\napp.get('/secure-area', (req, res) => {\n    if (req.session?.user) {\n        // Already logged in, show content\n        return res.render('secure-area');\n    }\n    // Not logged in, trigger authentication\n    keycloakInstance.login(req, res, '/secure-area');\n});\n```\n\n#### API - logout(req, res, redirectTo)\n\n**Signature**\n\n```js\nlogout(req, res, redirectTo)\n```\n\nImperative logout helper intended for use inside route handlers.\n\n**What this API is for**\n\n- Use this function when logout should be triggered after custom handler logic (audit logging, cleanup, conditional branching).\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `req` | `Object` | Yes | Express request. |\n| `res` | `Object` | Yes | Express response. |\n| `redirectTo` | `string` | Yes | Redirect destination after logout. |\n\n**Returns**\n\n- `void`.\n\n**Example**\n\n```js\napp.get('/logout-now', (req, res) => {\n    keycloakInstance.logout(req, res, 'http://localhost:3000/');\n});\n```\n\n**Example - Logout with user feedback**\n\n```js\napp.get('/logout', (req, res) => {\n    const username = req.kauth?.grant?.access_token?.content?.preferred_username || 'User';\n    console.log(`${username} logged out at ${new Date().toISOString()}`);\n    \n    // Audit log could go here\n    req.session.logoutTime = new Date();\n    \n    keycloakInstance.logout(req, res, 'http://localhost:3000/logged-out');\n});\n```\n\n**Example - Conditional logout with cleanup**\n\n```js\napp.get('/exit', async (req, res) => {\n    // Perform cleanup before logout\n    if (req.session?.userId) {\n        await cleanupUserResources(req.session.userId);\n    }\n    keycloakInstance.logout(req, res, '/goodbye');\n});\n```\n\n#### API - generateAuthorizationUrl(options)\n\n**Signature**\n\n```js\ngenerateAuthorizationUrl(options = {})\n```\n\nBuilds PKCE initialization values and authorization URL.\n\n**What this API is for**\n\n- Use this method to start a modern OAuth2 Authorization Code + PKCE flow.\n- It creates all artifacts needed to securely initiate login redirect.\n\n**Security relevance**\n\n- `state` protects against CSRF and response-mixup style attacks.\n- `codeVerifier` is the secret proof used in callback token exchange.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `options.redirect_uri` | `string` | Yes | Callback URI used by Keycloak after login. |\n| `options.redirectUri` | `string` | No | CamelCase alias of `redirect_uri`. |\n| `options.scope` | `string` | No | Requested scopes. Default: `openid profile email`. |\n| `options.state` | `string` | No | Custom state value; auto-generated when omitted. |\n\n**Returns**\n\n| Field | Type | Description |\n|---|---|---|\n| `authUrl` | `string` | Fully formed authorization URL. |\n| `state` | `string` | CSRF state value to store server-side. |\n| `codeVerifier` | `string` | PKCE verifier to store server-side. |\n\n**Errors**\n\n- Throws `Error` when middleware initialization data is missing.\n- Throws `Error` when `redirect_uri`/`redirectUri` is missing.\n\n**Example - Basic PKCE initialization**\n\n```js\nconst pkce = keycloakInstance.generateAuthorizationUrl({\n    redirect_uri: 'https://app.example.com/auth/callback'\n});\nreq.session.pkce_state = pkce.state;\nreq.session.pkce_verifier = pkce.codeVerifier;\nres.redirect(pkce.authUrl);\n```\n\n**Example - PKCE with custom scope**\n\n```js\nconst pkce = keycloakInstance.generateAuthorizationUrl({\n    redirect_uri: 'https://app.example.com/callback',\n    scope: 'openid profile email offline_access'\n});\n\n// Store in session or state management\nreq.session.pkce_state = pkce.state;\nreq.session.pkce_verifier = pkce.codeVerifier;\nreq.session.auth_initiated_at = Date.now();\n\nres.json({\n    authorization_url: pkce.authUrl,\n    // Frontend should store state/verifier safely\n});\n```\n\n**Example - PKCE with custom state**\n\n```js\nconst customState = `state_${Date.now()}_${Math.random()}`;\nconst pkce = keycloakInstance.generateAuthorizationUrl({\n    redirect_uri: 'https://api.example.com/oauth/callback',\n    scope: 'openid profile',\n    state: customState\n});\n\n// Verify state in callback to prevent CSRF attacks\nreq.session.oauth_state = customState;\nres.redirect(pkce.authUrl);\n```\n\n#### API - loginWithCredentials(credentials)\n\n**Signature**\n\n```js\nasync loginWithCredentials(credentials = {})\n```\n\nGeneric OAuth2 token endpoint helper supporting multiple grant types.\n\n**What this API is for**\n\n- Use this method when your application needs direct programmatic token endpoint access.\n- It is the low-level token exchange utility used by higher-level flows as well.\n\n**Typical grants handled**\n\n- `password`\n- `client_credentials`\n- `authorization_code`\n- `refresh_token`\n\n**Client configuration requirement (`password` grant only)**\n\n- If you call `loginWithCredentials(...)` with `grant_type=password`, the Keycloak client must have `Direct Access Grants` enabled.\n- This corresponds to OAuth2 `Resource Owner Password Credentials Grant` for that client.\n- This requirement does not apply to `client_credentials`, `refresh_token`, or `authorization_code` payloads.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `credentials.grant_type` | `string` | Yes | OAuth2 grant type. |\n| `credentials.username` | `string` | No | Username for password grant. |\n| `credentials.password` | `string` | No | Password for password grant. |\n| `credentials.client_id` | `string` | No | Client ID override. |\n| `credentials.client_secret` | `string` | No | Client secret override. |\n| `credentials.refresh_token` | `string` | No | Refresh token for refresh grant. |\n| `credentials.code` | `string` | No | Authorization code for authorization-code grant. |\n| `credentials.redirect_uri` | `string` | No | Redirect URI for authorization-code grant. |\n| `credentials.scope` | `string` | No | Requested scopes. |\n\n**Returns**\n\n- `Promise<Object>`: token payload from Keycloak token endpoint.\n\n**Errors**\n\n- Throws `Error` when middleware initialization data is missing.\n- Throws `Error` when token endpoint responds with non-success status.\n\n**Example - Refresh token grant**\n\n```js\nconst refreshed = await keycloakInstance.loginWithCredentials({\n    grant_type: 'refresh_token',\n    refresh_token: storedRefreshToken\n});\n```\n\n**Example - Password grant (Direct Access Grants required)**\n\n```js\n// Requires \"Direct Access Grants\" enabled on Keycloak client\nconst tokens = await keycloakInstance.loginWithCredentials({\n    grant_type: 'password',\n    username: 'user@example.com',\n    password: 'userPassword123',\n    scope: 'openid profile email'\n});\n\nreq.session.access_token = tokens.access_token;\nres.json({ success: true, token_type: tokens.token_type });\n```\n\n**Example - Client credentials grant (service-to-service)**\n\n```js\n// Get token as a service/application (not user-specific)\nconst serviceToken = await keycloakInstance.loginWithCredentials({\n    grant_type: 'client_credentials',\n    client_id: process.env.KEYCLOAK_CLIENT_ID,\n    client_secret: process.env.KEYCLOAK_CLIENT_SECRET,\n    scope: 'openid'\n});\n\n// Use token to call protected APIs\nconst apiResponse = await fetch('https://api.example.com/data', {\n    headers: { 'Authorization': `Bearer ${serviceToken.access_token}` }\n});\n```\n\n#### API - loginPKCE(credentials)\n\n**Signature**\n\n```js\nasync loginPKCE(credentials = {})\n```\n\nPerforms authorization-code + PKCE verifier exchange.\n\n**What this API is for**\n\n- Use this method in callback endpoints after Keycloak redirects user back with authorization code.\n- It specializes token exchange for PKCE and validates required PKCE inputs.\n\n**Why it matters**\n\n- PKCE mitigates intercepted authorization code reuse by binding code to `code_verifier`.\n- This method encapsulates the correct grant payload shape for PKCE callback stage.\n- PKCE callback exchange does not require `Direct Access Grants`.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `credentials.code` | `string` | Yes | Authorization code returned by Keycloak. |\n| `credentials.redirect_uri` or `credentials.redirectUri` | `string` | Yes | Callback URI used in authorization step. |\n| `credentials.code_verifier` or `credentials.codeVerifier` | `string` | Yes | PKCE verifier from server session. |\n| `credentials.client_id` or `credentials.clientId` | `string` | No | Client ID override. |\n| `credentials.client_secret` or `credentials.clientSecret` | `string` | No | Client secret override. |\n| Additional token fields | `string` | No | Forwarded to token request body. |\n\n**Returns**\n\n- `Promise<Object>`: token payload.\n\n**Errors**\n\n- Throws `Error` when `code` is missing.\n- Throws `Error` when `redirect_uri`/`redirectUri` is missing.\n- Throws `Error` when `code_verifier`/`codeVerifier` is missing.\n- Propagates token endpoint errors from `loginWithCredentials`.\n\n**Example**\n\n```js\nconst tokens = await keycloakInstance.loginPKCE({\n    code: req.query.code,\n    redirect_uri: 'https://app.example.com/auth/callback',\n    code_verifier: req.session.pkce_verifier\n});\n```\n\n**Example - Full PKCE callback flow**\n\n```js\napp.get('/auth/callback', async (req, res) => {\n    try {\n        // Verify state to prevent CSRF\n        if (req.query.state !== req.session.pkce_state) {\n            throw new Error('State mismatch - possible CSRF attack');\n        }\n\n        // Exchange code and verifier for tokens\n        const tokens = await keycloakInstance.loginPKCE({\n            code: req.query.code,\n            redirect_uri: process.env.OAUTH_CALLBACK_URL,\n            code_verifier: req.session.pkce_verifier\n        });\n\n        // Store tokens securely\n        req.session.access_token = tokens.access_token;\n        req.session.refresh_token = tokens.refresh_token;\n        req.session.user_authenticated = true;\n\n        res.redirect('/dashboard');\n    } catch (err) {\n        console.error('PKCE exchange failed:', err);\n        res.status(401).json({ error: 'Authentication failed' });\n    }\n});\n```\n\n**Example - PKCE with automatic token refresh**\n\n```js\napp.get('/auth/callback', async (req, res) => {\n    try {\n        const tokens = await keycloakInstance.loginPKCE({\n            code: req.query.code,\n            redirect_uri: 'https://app.example.com/callback',\n            code_verifier: req.session.pkce_verifier\n        });\n\n        // Store tokens and setup auto-refresh\n        req.session.access_token = tokens.access_token;\n        req.session.refresh_token = tokens.refresh_token;\n        req.session.token_expires_at = Date.now() + (tokens.expires_in * 1000);\n\n        // Schedule token refresh\n        setTimeout(() => refreshAccessToken(req), (tokens.expires_in - 30) * 1000);\n\n        res.redirect('/home');\n    } catch (err) {\n        res.status(401).send('Authentication failed');\n    }\n});\n```\n\n#### API - redirectToUserAccountConsole(res)\n\n**Signature**\n\n```js\nredirectToUserAccountConsole(res)\n```\n\nRedirects user to the Keycloak account console endpoint for the configured realm.\n\n**What this API is for**\n\n- Use this helper to provide a direct “Manage Account” navigation endpoint from your app.\n- It delegates profile/security management to Keycloak account console UI.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `res` | `Object` | Yes | Express response. |\n\n**Returns**\n\n- `void`.\n\n**Example**\n\n```js\napp.get('/my-account', (req, res) => {\n    keycloakInstance.redirectToUserAccountConsole(res);\n});\n```\n\n**Example - Account management link in profile page**\n\n```js\napp.get('/profile', keycloakInstance.protectMiddleware(), (req, res) => {\n    const user = req.kauth.grant.access_token.content;\n    res.render('profile', {\n        user: user.preferred_username,\n        manageAccountUrl: '/manage-account' // This endpoint redirects via redirectToUserAccountConsole\n    });\n});\n\napp.get('/manage-account', keycloakInstance.protectMiddleware(), (req, res) => {\n    keycloakInstance.redirectToUserAccountConsole(res);\n});\n```\n\n**Example - Security settings redirect**\n\n```js\n// Direct users to change password, 2FA settings, etc.\napp.get('/security-settings', keycloakInstance.protectMiddleware(), (req, res) => {\n    keycloakInstance.redirectToUserAccountConsole(res);\n});\n```\n\n#### API - hasScope(scopeInput, requiredScope)\n\n**Signature**\n\n```js\nhasScope(scopeInput, requiredScope)\n```\n\nChecks whether one scope is present in a scope string or array.\n\n**What this API is for**\n\n- Use this helper to check scopes without rewriting parsing logic in every route.\n- Works with both middleware token claims and token endpoint responses.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `scopeInput` | `string \\| string[]` | Yes | Scope source (`\"openid profile email\"` or `['openid', 'profile']`). |\n| `requiredScope` | `string` | Yes | Scope to verify. |\n\n**Returns**\n\n- `boolean`: `true` if scope exists, otherwise `false`.\n\n**Example - Email scope check**\n\n```js\nconst tokenScope = req?.kauth?.grant?.access_token?.content?.scope;\nconst canReadEmail = keycloakInstance.hasScope(tokenScope, 'email');\n```\n\n**Example - Checking multiple scopes one by one**\n\n```js\nconst scope = 'openid profile email'; // From token\n\nconst hasOpenId = keycloakInstance.hasScope(scope, 'openid'); // true\nconst hasOfflineAccess = keycloakInstance.hasScope(scope, 'offline_access'); // false\nconst hasEmail = keycloakInstance.hasScope(scope, 'email'); // true\n\nres.json({ hasOpenId, hasOfflineAccess, hasEmail });\n```\n\n**Example - Response based on scope availability**\n\n```js\nconst scope = req?.kauth?.grant?.access_token?.content?.scope || '';\n\nconst response = {\n    profile: true,\n    email: keycloakInstance.hasScope(scope, 'email'),\n    phone: keycloakInstance.hasScope(scope, 'phone'),\n    address: keycloakInstance.hasScope(scope, 'address')\n};\n\nres.json(response);\n```\n\n#### API - hasScopes(scopeInput, requiredScopes, mode)\n\n**Signature**\n\n```js\nhasScopes(scopeInput, requiredScopes, mode = 'all')\n```\n\nChecks multiple scopes with `all` (default) or `any` matching mode.\n\n**Parameters**\n\n| Name | Type | Required | Description |\n|---|---|---|---|\n| `scopeInput` | `string \\| string[]` | Yes | Scope source (`\"openid profile email\"` or array). |\n| `requiredScopes` | `string \\| string[]` | Yes | One or more scopes to evaluate. |\n| `mode` | `'all' \\| 'any'` | No | `all` requires all scopes, `any` requires at least one. |\n\n**Returns**\n\n- `boolean`: scope validation result.\n\n**Example - Check all required scopes**\n\n```js\nconst scopeString = tokenResponse.scope;\n\nconst hasAll = keycloakInstance.hasScopes(\n    scopeString,\n    ['openid', 'profile'],\n    'all'\n);\n\nconst hasAny = keycloakInstance.hasScopes(\n    scopeString,\n    ['email', 'offline_access'],\n    'any'\n);\n```\n\n**Example - Scope validation before API call**\n\n```js\napp.get('/user-data', keycloakInstance.protectMiddleware(), (req, res) => {\n    const scope = req?.kauth?.grant?.access_token?.content?.scope || '';\n    \n    // Check required scopes\n    const canAccessProfile = keycloakInstance.hasScope(scope, 'profile');\n    const canAccessEmail = keycloakInstance.hasScope(scope, 'email');\n    \n    if (!canAccessProfile) {\n        return res.status(403).json({ error: 'Missing profile scope' });\n    }\n    \n    const userData = {\n        profile: getUserProfile(req),\n        email: canAccessEmail ? getUserEmail(req) : null\n    };\n    \n    res.json(userData);\n});\n```\n\n**Example - Delegated vs direct access scopes**\n\n```js\nconst scope = tokenResponse.scope;\n\n// check for offline access (allows refresh tokens)\nconst canRefresh = keycloakInstance.hasScope(scope, 'offline_access');\n\n// Check for direct API access vs SSO-only\nconst canUseDirectAPI = keycloakInstance.hasScopes(\n    scope,\n    ['api-access', 'direct-auth'],\n    'any'\n);\n\nres.json({\n    sessionRefresh: canRefresh,\n    apiAccess: canUseDirectAPI\n});\n```\n\n#### API - getTokenClaims(req)\n\n**Signature**\n\n```js\ngetTokenClaims(req)\n```\n\nSafely returns decoded access token claims from request.\n\n**Returns**\n\n- `Object`: token claims object, or `{}` if token is unavailable.\n\n**Example**\n\n```js\nconst claims = keycloakInstance.getTokenClaims(req);\nconst username = claims.preferred_username;\n```\n\n**Example - Extract multiple claims**\n\n```js\napp.get('/token-info', keycloakInstance.protectMiddleware(), (req, res) => {\n    const claims = keycloakInstance.getTokenClaims(req);\n    \n    res.json({\n        username: claims.preferred_username,\n        email: claims.email,\n        givenName: claims.given_name,\n        familyName: claims.family_name,\n        expiresAt: new Date(claims.exp * 1000).toISOString()\n    });\n});\n```\n\n**Example - Token inspection/debugging**\n\n```js\napp.get('/debug/token', keycloakInstance.protectMiddleware(), (req, res) => {\n    const claims = keycloakInstance.getTokenClaims(req);\n    \n    if (process.env.NODE_ENV === 'development') {\n        res.json({\n            allClaims: claims,\n            tokenValid: claims.exp > Date.now() / 1000,\n            issuedAt: new Date(claims.iat * 1000),\n            expiresAt: new Date(claims.exp * 1000)\n        });\n    } else {\n        res.status(403).send('Not available in production');\n    }\n});\n```\n\n#### API - isAuthenticated(req)\n\n**Signature**\n\n```js\nisAuthenticated(req)\n```\n\nChecks whether request contains a Keycloak access token.\n\n**Returns**\n\n- `boolean`.\n\n**Example**\n\n```js\nif (!keycloakInstance.isAuthenticated(req)) {\n    return res.status(401).send('Not authenticated');\n}\n```\n\n**Example - Conditional rendering**\n\n```js\napp.get('/content', (req, res) => {\n    if (!keycloakInstance.isAuthenticated(req)) {\n        return res.render('login-prompt');\n    }\n    res.render('protected-content');\n});\n```\n\n**Example - Middleware-less authentication check**\n\n```js\napp.get('/optional-features', (req, res) => {\n    const isAuth = keycloakInstance.isAuthenticated(req);\n    \n    const features = {\n        basicRead: true,\n        advancedSearch: isAuth,\n        exportData: isAuth,\n        collaboration: isAuth && req.kauth?.grant?.access_token?.content?.realm_access?.roles?.includes('premium')\n    };\n    \n    res.json(features);\n});\n```\n\n#### API - getScopes(scopeInputOrReq)\n\n**Signature**\n\n```js\ngetScopes(scopeInputOrReq)\n```\n\nNormalizes scopes to an array from one o","readmeFilename":"README.md"}