diff --git a/example/index.js b/example/index.js index 61b9835b..86c6c299 100644 --- a/example/index.js +++ b/example/index.js @@ -13,12 +13,14 @@ * License for the specific language governing permissions and limitations under * the License. */ +import express from 'express' +import session from 'express-session' +import hogan from 'hogan-express' +import Keycloak from 'keycloak-connect' +import path from 'node:path' +import url from 'node:url' -const Keycloak = require('keycloak-connect') -const hogan = require('hogan-express') -const express = require('express') -const session = require('express-session') - +const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) const app = express() const server = app.listen(3000, function () { @@ -29,7 +31,7 @@ const server = app.listen(3000, function () { // Register '.mustache' extension with The Mustache Express app.set('view engine', 'html') -app.set('views', require('path').join(__dirname, '/view')) +app.set('views', path.join(__dirname, '/view')) app.engine('html', hogan) // A normal un-protected public URL. diff --git a/example/package.json b/example/package.json index 8dcb60c9..e07cd292 100644 --- a/example/package.json +++ b/example/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "description": "Example page that demonstrates available keycloak functionality", "main": "index.js", + "type": "module", "scripts": { "start": "node index.js" }, diff --git a/guides/guides.mjs b/guides/guides.js similarity index 100% rename from guides/guides.mjs rename to guides/guides.js diff --git a/guides/securing-apps/nodejs-adapter.adoc b/guides/securing-apps/nodejs-adapter.adoc index e0646370..dc3048c5 100644 --- a/guides/securing-apps/nodejs-adapter.adoc +++ b/guides/securing-apps/nodejs-adapter.adoc @@ -63,8 +63,8 @@ In the root directory of your project create a file called `server.js` and add t [source,javascript] ---- - const session = require('express-session'); - const Keycloak = require('keycloak-connect'); + import session from 'express-session'; + import Keycloak from 'keycloak-connect'; const memoryStore = new session.MemoryStore(); const keycloak = new Keycloak({ store: memoryStore }); @@ -135,7 +135,8 @@ server-side state for authentication, you need to initialize the session store that `express-session` is using. [source,javascript] ---- - const session = require('express-session'); + import session from 'express-session'; + const memoryStore = new session.MemoryStore(); // Configure session @@ -169,7 +170,8 @@ then require Express in our project as outlined below: [source,javascript] ---- - const express = require('express'); + import express from 'express'; + const app = express(); ---- diff --git a/keycloak.js b/keycloak.js index 101233f9..7af52026 100644 --- a/keycloak.js +++ b/keycloak.js @@ -14,20 +14,19 @@ * the License. */ -const BearerStore = require('./stores/bearer-store') -const CookieStore = require('./stores/cookie-store') -const SessionStore = require('./stores/session-store') - -const Config = require('./middleware/auth-utils/config') -const GrantManager = require('./middleware/auth-utils/grant-manager') -const Setup = require('./middleware/setup') -const Admin = require('./middleware/admin') -const Logout = require('./middleware/logout') -const PostAuth = require('./middleware/post-auth') -const GrantAttacher = require('./middleware/grant-attacher') -const Protect = require('./middleware/protect') -const Enforcer = require('./middleware/enforcer') -const CheckSso = require('./middleware/check-sso') +import Admin from './middleware/admin.js' +import Config from './middleware/auth-utils/config.js' +import GrantManager from './middleware/auth-utils/grant-manager.js' +import CheckSso from './middleware/check-sso.js' +import Enforcer from './middleware/enforcer.js' +import GrantAttacher from './middleware/grant-attacher.js' +import Logout from './middleware/logout.js' +import PostAuth from './middleware/post-auth.js' +import Protect from './middleware/protect.js' +import Setup from './middleware/setup.js' +import BearerStore from './stores/bearer-store.js' +import CookieStore from './stores/cookie-store.js' +import SessionStore from './stores/session-store.js' /** * Instantiate a Keycloak. @@ -58,7 +57,7 @@ const CheckSso = require('./middleware/check-sso') * @return {Keycloak} A constructed Keycloak object. * */ -function Keycloak (config, keycloakConfig) { +export default function Keycloak (config, keycloakConfig) { // If keycloakConfig is null, Config() will search for `keycloak.json`. this.config = new Config(keycloakConfig) @@ -426,5 +425,3 @@ Keycloak.prototype.redirectToLogin = function (request) { Keycloak.prototype.getConfig = function () { return this.config } - -module.exports = Keycloak diff --git a/middleware/admin.js b/middleware/admin.js index a9c81539..f0a209f8 100644 --- a/middleware/admin.js +++ b/middleware/admin.js @@ -13,10 +13,8 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -const Token = require('./auth-utils/token') -const Signature = require('./auth-utils/signature') +import Token from './auth-utils/token.js' +import Signature from './auth-utils/signature.js' function Admin (keycloak, url) { this._keycloak = keycloak @@ -99,7 +97,7 @@ function adminNotBefore (request, response, keycloak) { }) } -module.exports = function (keycloak, adminUrl) { +export default function adminMiddleware (keycloak, adminUrl) { let url = adminUrl if (url[url.length - 1] !== '/') { url = url + '/' diff --git a/middleware/auth-utils/config.js b/middleware/auth-utils/config.js index 076e9512..7fd7deb8 100644 --- a/middleware/auth-utils/config.js +++ b/middleware/auth-utils/config.js @@ -13,11 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -'use strict' - -const path = require('path') -const fs = require('fs') +import path from 'node:path' +import fs from 'node:fs' /** * Construct a configuration object. @@ -31,7 +28,7 @@ const fs = require('fs') * * @constructor */ -function Config (config) { +export default function Config (config) { if (!config) { config = path.join(process.cwd(), 'keycloak.json') } @@ -168,5 +165,3 @@ Config.prototype.configure = function configure (config) { */ this.verifyTokenAudience = resolveValue(config['verify-token-audience'] || config.verifyTokenAudience || false) } - -module.exports = Config diff --git a/middleware/auth-utils/grant-manager.js b/middleware/auth-utils/grant-manager.js index 676cd131..287a2049 100644 --- a/middleware/auth-utils/grant-manager.js +++ b/middleware/auth-utils/grant-manager.js @@ -13,16 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use strict' - -const URL = require('url') -const http = require('http') -const https = require('https') -const crypto = require('crypto') -const querystring = require('querystring') -const Grant = require('./grant') -const Token = require('./token') -const Rotation = require('./rotation') +import URL from 'node:url' +import http from 'node:http' +import https from 'node:https' +import crypto from 'node:crypto' +import querystring from 'node:querystring' +import Grant from './grant.js' +import Token from './token.js' +import Rotation from './rotation.js' /** * Construct a grant manager. @@ -31,7 +29,7 @@ const Rotation = require('./rotation') * * @constructor */ -function GrantManager (config) { +export default function GrantManager (config) { this.realmUrl = config.realmUrl this.clientId = config.clientId this.secret = config.secret @@ -536,5 +534,3 @@ const fetch = (manager, handler, options, params) => { req.end() }) } - -module.exports = GrantManager diff --git a/middleware/auth-utils/grant.js b/middleware/auth-utils/grant.js index 854ef25d..e9274585 100644 --- a/middleware/auth-utils/grant.js +++ b/middleware/auth-utils/grant.js @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use strict' /** * Construct a new grant. @@ -30,7 +29,7 @@ * * @constructor */ -function Grant (grant) { +export default function Grant (grant) { this.update(grant) } @@ -80,5 +79,3 @@ Grant.prototype.isExpired = function isExpired () { } return this.access_token.isExpired() } - -module.exports = Grant diff --git a/middleware/auth-utils/rotation.js b/middleware/auth-utils/rotation.js index 734020b9..0dc2e3a0 100644 --- a/middleware/auth-utils/rotation.js +++ b/middleware/auth-utils/rotation.js @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use strict' -const URL = require('url') -const http = require('http') -const https = require('https') -const jwkToPem = require('jwk-to-pem') +import URL from 'node:url' +import http from 'node:http' +import https from 'node:https' +import jwkToPem from 'jwk-to-pem' /** * Construct a Rotation instance @@ -26,7 +25,7 @@ const jwkToPem = require('jwk-to-pem') * * @constructor */ -function Rotation (config) { +export default function Rotation (config) { this.realmUrl = config.realmUrl this.minTimeBetweenJwksRequests = config.minTimeBetweenJwksRequests this.jwks = [] @@ -93,5 +92,3 @@ const nodeify = (promise, cb) => { if (typeof cb !== 'function') return promise return promise.then((res) => cb(null, res)).catch((err) => cb(err)) } - -module.exports = Rotation diff --git a/middleware/auth-utils/signature.js b/middleware/auth-utils/signature.js index 4967f740..e137dbdc 100644 --- a/middleware/auth-utils/signature.js +++ b/middleware/auth-utils/signature.js @@ -13,10 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use strict' - -const Rotation = require('./rotation') -const crypto = require('crypto') +import crypto from 'node:crypto' +import Rotation from './rotation.js' /** * Construct a signature. @@ -25,7 +23,7 @@ const crypto = require('crypto') * * @constructor */ -function Signature (config) { +export default function Signature (config) { this.publicKey = config.publicKey this.rotation = new Rotation(config) } @@ -51,5 +49,3 @@ Signature.prototype.verify = function verify (token, callback) { }) }) } - -module.exports = Signature diff --git a/middleware/auth-utils/token.js b/middleware/auth-utils/token.js index 517e77d3..67527a15 100644 --- a/middleware/auth-utils/token.js +++ b/middleware/auth-utils/token.js @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -'use strict' /** * Construct a token. @@ -27,7 +26,7 @@ * @param {String} token The JSON Web Token formatted token string. * @param {String} clientId Optional clientId if this is an `access_token`. */ -function Token (token, clientId) { +export default function Token (token, clientId) { this.token = token this.clientId = clientId @@ -185,5 +184,3 @@ Token.prototype.hasPermission = function hasPermission (resource, scope) { return false } - -module.exports = Token diff --git a/middleware/check-sso.js b/middleware/check-sso.js index 88daa13a..e9458e35 100644 --- a/middleware/check-sso.js +++ b/middleware/check-sso.js @@ -13,10 +13,8 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -const UUID = require('./../uuid') -const URL = require('url') +import URL from 'node:url' +import UUID from './../uuid.js' function forceCheckSSO (keycloak, request, response) { const host = request.hostname @@ -38,7 +36,7 @@ function forceCheckSSO (keycloak, request, response) { response.redirect(checkSsoUrl) } -module.exports = function (keycloak) { +export default function checkSsoMiddleware (keycloak) { return function checkSso (request, response, next) { if (request.kauth && request.kauth.grant) { return next() diff --git a/middleware/enforcer.js b/middleware/enforcer.js index b7c1e963..95c7e197 100644 --- a/middleware/enforcer.js +++ b/middleware/enforcer.js @@ -13,8 +13,6 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - function handlePermissions (permissions, callback) { for (let i = 0; i < permissions.length; i++) { const expected = permissions[i].split(':') @@ -42,7 +40,7 @@ function handlePermissions (permissions, callback) { * * @constructor */ -function Enforcer (keycloak, config) { +export default function Enforcer (keycloak, config) { this.keycloak = keycloak this.config = config || {} @@ -155,5 +153,3 @@ Enforcer.prototype.enforce = function enforce (expectedPermissions) { } } } - -module.exports = Enforcer diff --git a/middleware/grant-attacher.js b/middleware/grant-attacher.js index 88fd06a7..acba3dd0 100644 --- a/middleware/grant-attacher.js +++ b/middleware/grant-attacher.js @@ -13,9 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -module.exports = function (keycloak) { +export default function grantAttacherMiddleware (keycloak) { return function grantAttacher (request, response, next) { keycloak.getGrant(request, response) .then(grant => { diff --git a/middleware/logout.js b/middleware/logout.js index c7855958..b6030cfb 100644 --- a/middleware/logout.js +++ b/middleware/logout.js @@ -13,11 +13,9 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' +import URL from 'node:url' -const URL = require('url') - -module.exports = function (keycloak, logoutUrl) { +export default function logoutMiddleware (keycloak, logoutUrl) { return function logout (request, response, next) { const parsedRequest = URL.parse(request.url, true); // eslint-disable-line if (parsedRequest.pathname !== logoutUrl) { diff --git a/middleware/post-auth.js b/middleware/post-auth.js index 8bd74447..d38fcf1a 100644 --- a/middleware/post-auth.js +++ b/middleware/post-auth.js @@ -13,11 +13,9 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' +import URL from 'node:url' -const URL = require('url') - -module.exports = function (keycloak) { +export default function postAuthMiddleware (keycloak) { return function postAuth (request, response, next) { if (!request.query.auth_callback) { return next() diff --git a/middleware/protect.js b/middleware/protect.js index e42c747d..9a0cb709 100644 --- a/middleware/protect.js +++ b/middleware/protect.js @@ -13,9 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -const UUID = require('./../uuid') +import UUID from './../uuid.js' function forceLogin (keycloak, request, response) { const host = request.hostname @@ -39,7 +37,7 @@ function simpleGuard (role, token) { return token.hasRole(role) } -module.exports = function (keycloak, spec) { +export default function protectMiddleware (keycloak, spec) { let guard if (typeof spec === 'function') { diff --git a/middleware/setup.js b/middleware/setup.js index c0665eed..812f99d6 100644 --- a/middleware/setup.js +++ b/middleware/setup.js @@ -13,9 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -module.exports = function setup (request, response, next) { +export default function setup (request, response, next) { request.kauth = {} next() } diff --git a/package.json b/package.json index dddbd333..964fca57 100644 --- a/package.json +++ b/package.json @@ -3,14 +3,15 @@ "version": "999.0.0-SNAPSHOT", "description": "Keycloak Connect Middleware", "homepage": "http://keycloak.org", + "type": "module", "main": "keycloak.js", "scripts": { "lint": "standard", "test": "./run-tests.sh", "docs": "jsdoc --verbose -d docs -t ./node_modules/ink-docstrap/template -R README.md index.js ./middleware/*.js stores/*.js ./middleware/auth-utils/*.js", "coverage": "nyc cover tape test/unit/*.js tape test/*.js", - "server:start": "./scripts/start-server.mjs -Dkeycloak.profile.feature.account_api=disabled -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.file=test/fixtures/auth-utils/nodejs-test-realm.json -Dkeycloak.migration.strategy=OVERWRITE_EXISTING", - "guides": "node guides/guides.mjs $npm_package_version" + "server:start": "./scripts/start-server.js -Dkeycloak.profile.feature.account_api=disabled -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.file=test/fixtures/auth-utils/nodejs-test-realm.json -Dkeycloak.migration.strategy=OVERWRITE_EXISTING", + "guides": "node guides/guides.js $npm_package_version" }, "keywords": [ "sso", diff --git a/scripts/start-server.mjs b/scripts/start-server.js similarity index 100% rename from scripts/start-server.mjs rename to scripts/start-server.js diff --git a/stores/bearer-store.js b/stores/bearer-store.js index 2fb35712..8a8ccac0 100644 --- a/stores/bearer-store.js +++ b/stores/bearer-store.js @@ -13,8 +13,6 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - const BearerStore = {} BearerStore.get = (request) => { @@ -30,4 +28,4 @@ BearerStore.get = (request) => { } } -module.exports = BearerStore +export default BearerStore diff --git a/stores/cookie-store.js b/stores/cookie-store.js index 6f05f918..92728538 100644 --- a/stores/cookie-store.js +++ b/stores/cookie-store.js @@ -13,8 +13,6 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - const CookieStore = {} CookieStore.TOKEN_KEY = 'keycloak-token' @@ -45,4 +43,4 @@ CookieStore.wrap = (grant) => { grant.unstore = unstore } -module.exports = CookieStore +export default CookieStore diff --git a/stores/session-store.js b/stores/session-store.js index baf54abc..b8ea8af0 100644 --- a/stores/session-store.js +++ b/stores/session-store.js @@ -13,9 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -function SessionStore (store) { +export default function SessionStore (store) { this.store = store } @@ -52,5 +50,3 @@ SessionStore.prototype.wrap = (grant) => { grant.unstore = unstore } } - -module.exports = SessionStore diff --git a/test/fixtures/node-console/index.js b/test/fixtures/node-console/index.js index f74c5a5c..4bc19ef7 100644 --- a/test/fixtures/node-console/index.js +++ b/test/fixtures/node-console/index.js @@ -13,16 +13,18 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -const Keycloak = require('../../../') -const bodyParser = require('body-parser') -const hogan = require('hogan-express') -const express = require('express') -const session = require('express-session') -const cookieParser = require('cookie-parser') -const enableDestroy = require('server-destroy') -const parseClient = require('../../utils/helper').parseClient +import bodyParser from 'body-parser' +import cookieParser from 'cookie-parser' +import express from 'express' +import session from 'express-session' +import hogan from 'hogan-express' +import path from 'node:path' +import url from 'node:url' +import enableDestroy from 'server-destroy' +import Keycloak from '../../../keycloak.js' +import { parseClient } from '../../utils/helper.js' + +const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) Keycloak.prototype.redirectToLogin = function (req) { const apiMatcher = /^\/service\/.*/i @@ -33,7 +35,7 @@ Keycloak.prototype.obtainDirectly = function (user, pass) { return this.grantManager.obtainDirectly(user, pass) } -function NodeApp () { +export function NodeApp () { const app = express() app.use(cookieParser()) const server = app.listen(0) @@ -71,7 +73,7 @@ function NodeApp () { this.build = function (kcConfig, params) { app.set('view engine', 'html') - app.set('views', require('path').join(__dirname, '/views')) + app.set('views', path.join(__dirname, '/views')) app.engine('html', hogan) // Create a session-store to be used by both the express-session @@ -213,7 +215,3 @@ function output (res, output, eventMessage, page) { event: eventMessage }) } - -module.exports = { - NodeApp -} diff --git a/test/grant-manager-spec.js b/test/grant-manager-spec.js index 15e61929..d9355be7 100644 --- a/test/grant-manager-spec.js +++ b/test/grant-manager-spec.js @@ -1,12 +1,11 @@ -'use strict' +import nock from 'nock' +import test from 'tape' +import Config from '../middleware/auth-utils/config.js' +import GrantManager from '../middleware/auth-utils/grant-manager.js' +import { dummyReply } from './utils/helper.js' -const GrantManager = require('../middleware/auth-utils/grant-manager') -const Config = require('../middleware/auth-utils/config') -const test = require('tape') -const nock = require('nock') const delay = (ms) => (value) => new Promise((resolve) => setTimeout(() => resolve(value), ms)) const getManager = (fixture) => new GrantManager(new Config(fixture)) -const helper = require('./utils/helper') test('GrantManager with empty configuration', (t) => { t.plan(1) @@ -666,7 +665,7 @@ test('GrantManager#obtainDirectly should work with https', (t) => { grant_type: 'password', scope: 'openid' }) - .reply(204, helper.dummyReply) + .reply(204, dummyReply) const manager = getManager('./test/fixtures/auth-utils/keycloak-https.json') manager.validateToken = (t) => { return Promise.resolve(t) } manager.ensureFreshness = (t) => { return Promise.resolve(t) } diff --git a/test/grant-manager-token-timeout-spec.js b/test/grant-manager-token-timeout-spec.js index 29904ac6..3a79798d 100644 --- a/test/grant-manager-token-timeout-spec.js +++ b/test/grant-manager-token-timeout-spec.js @@ -1,8 +1,7 @@ -'use strict' +import test from 'tape' +import Config from '../middleware/auth-utils/config.js' +import GrantManager from '../middleware/auth-utils/grant-manager.js' -const GrantManager = require('../middleware/auth-utils/grant-manager') -const Config = require('../middleware/auth-utils/config') -const test = require('tape') const delay = (ms) => (value) => new Promise((resolve) => setTimeout(() => resolve(value), ms)) const getManager = (fixture) => new GrantManager(new Config(fixture)) diff --git a/test/keycloak-connect-rest-enforcer-spec.js b/test/keycloak-connect-rest-enforcer-spec.js index e52bfc31..4939a482 100644 --- a/test/keycloak-connect-rest-enforcer-spec.js +++ b/test/keycloak-connect-rest-enforcer-spec.js @@ -13,22 +13,19 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -const admin = require('./utils/realm') -const NodeApp = require('./fixtures/node-console/index').NodeApp - -const test = require('blue-tape') -const axios = require('axios') -const getToken = require('./utils/token') +import axios from 'axios' +import test from 'blue-tape' +import { NodeApp } from './fixtures/node-console/index.js' +import { createClient, createRealm, deleteRealm } from './utils/realm.js' +import getToken from './utils/token.js' const realmName = 'policy-enforcer-realm' -const realmManager = admin.createRealm(realmName) +const realmManager = createRealm(realmName) const app = new NodeApp() test('setup', t => { return realmManager.then(() => { - return admin.createClient(app.enforcerResourceServer(), realmName) + return createClient(app.enforcerResourceServer(), realmName) .then((installation) => { return app.build(installation) }) @@ -184,6 +181,6 @@ test('Should test access to resources without any permission defined.', t => { test('teardown', t => { return realmManager.then((realm) => { app.destroy() - admin.destroy(realmName) + deleteRealm(realmName) }) }) diff --git a/test/keycloak-connect-rest-mixed-client-spec.js b/test/keycloak-connect-rest-mixed-client-spec.js index 3551119e..88a670e3 100644 --- a/test/keycloak-connect-rest-mixed-client-spec.js +++ b/test/keycloak-connect-rest-mixed-client-spec.js @@ -13,18 +13,15 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -const admin = require('./utils/realm') -const NodeApp = require('./fixtures/node-console/index').NodeApp -const TestVector = require('./utils/helper').TestVector - -const test = require('blue-tape') -const axios = require('axios') -const getToken = require('./utils/token') +import axios from 'axios' +import test from 'blue-tape' +import { NodeApp } from './fixtures/node-console/index.js' +import { TestVector } from './utils/helper.js' +import { createClient, createRealm, deleteRealm } from './utils/realm.js' +import getToken from './utils/token.js' const realmName = 'mixed-mode-realm' -const realmManager = admin.createRealm(realmName) +const realmManager = createRealm(realmName) const app = new NodeApp() const auth = { @@ -40,7 +37,7 @@ const assertAlternativeMessages = (assert, message, ...messages) => { test('setup', t => { return realmManager.then(() => { - return admin.createClient(app.confidential(), realmName) + return createClient(app.confidential(), realmName) .then((installation) => { return app.build(installation) }) @@ -161,7 +158,7 @@ test('Should test admin logout endpoint with incomplete payload', t => { t.plan(2) const app = new NodeApp() - const client = admin.createClient(app.confidential('adminapp'), realmName) + const client = createClient(app.confidential('adminapp'), realmName) return client.then((installation) => { app.build(installation) @@ -190,7 +187,7 @@ test('Should test admin logout endpoint with payload signed by a different key p t.plan(2) const app = new NodeApp() - const client = admin.createClient(app.confidential('adminapp2'), realmName) + const client = createClient(app.confidential('adminapp2'), realmName) return client.then((installation) => { app.build(installation) @@ -214,7 +211,7 @@ test('Should test admin logout endpoint with valid payload', t => { t.plan(1) const app = new NodeApp() - const client = admin.createClient(app.confidential('adminapp3'), realmName) + const client = createClient(app.confidential('adminapp3'), realmName) return client.then((installation) => { app.build(installation) @@ -237,7 +234,7 @@ test('Should test admin push_not_before endpoint with incomplete payload', t => t.plan(2) const app = new NodeApp() - const client = admin.createClient(app.confidential('adminapp5'), realmName) + const client = createClient(app.confidential('adminapp5'), realmName) return client.then((installation) => { app.build(installation) @@ -266,7 +263,7 @@ test('Should test admin push_not_before endpoint with payload signed by a differ t.plan(2) const app = new NodeApp() - const client = admin.createClient(app.confidential('adminapp6'), realmName) + const client = createClient(app.confidential('adminapp6'), realmName) return client.then((installation) => { app.build(installation) @@ -289,7 +286,7 @@ test('Should test admin push_not_before endpoint with payload signed by a differ test('Should verify during authentication if the token contains the client name as audience.', t => { t.plan(3) const someapp = new NodeApp() - const client = admin.createClient(someapp.confidential('audience-app'), realmName) + const client = createClient(someapp.confidential('audience-app'), realmName) return client.then((installation) => { installation.verifyTokenAudience = true @@ -313,7 +310,7 @@ test('Should test admin push_not_before endpoint with valid payload', t => { t.plan(1) const app = new NodeApp() - const client = admin.createClient(app.confidential('adminapp7'), realmName) + const client = createClient(app.confidential('adminapp7'), realmName) return client.then((installation) => { app.build(installation) @@ -349,6 +346,6 @@ test.skip('Should logout with redirect url', t => { test('teardown', t => { return realmManager.then((realm) => { app.destroy() - admin.destroy(realmName) + deleteRealm(realmName) }) }) diff --git a/test/keycloak-connect-rest-spec.js b/test/keycloak-connect-rest-spec.js index 822d119b..5be84063 100644 --- a/test/keycloak-connect-rest-spec.js +++ b/test/keycloak-connect-rest-spec.js @@ -13,23 +13,20 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -const admin = require('./utils/realm') -const TestVector = require('./utils/helper').TestVector -const NodeApp = require('./fixtures/node-console/index').NodeApp - -const test = require('blue-tape') -const axios = require('axios') -const getToken = require('./utils/token') +import axios from 'axios' +import test from 'blue-tape' +import { NodeApp } from './fixtures/node-console/index.js' +import { TestVector } from './utils/helper.js' +import { createClient, createRealm, deleteRealm } from './utils/realm.js' +import getToken from './utils/token.js' const realmName = 'service-node-realm' -const realmManager = admin.createRealm(realmName) +const realmManager = createRealm(realmName) const app = new NodeApp() test('setup', t => { return realmManager.then(() => { - return admin.createClient(app.bearerOnly(), realmName) + return createClient(app.bearerOnly(), realmName) .then((installation) => { return app.build(installation) }) @@ -105,7 +102,7 @@ test('Access should be denied for bearer client with invalid public key.', t => t.plan(1) const someApp = new NodeApp() - const client = admin.createClient(app.bearerOnly('wrongkey-app'), realmName) + const client = createClient(app.bearerOnly('wrongkey-app'), realmName) return client.then((installation) => { installation['realm-public-key'] = TestVector.wrongRealmPublicKey @@ -135,7 +132,7 @@ test('Should test protected route after push revocation.', t => { t.plan(2) const app = new NodeApp() - const client = admin.createClient(app.bearerOnly('revokeapp'), realmName) + const client = createClient(app.bearerOnly('revokeapp'), realmName) return client.then((installation) => { app.build(installation) @@ -180,7 +177,7 @@ test('Should invoke admin logout.', t => { t.plan(2) const app = new NodeApp() - const client = admin.createClient(app.bearerOnly('anotherapp'), realmName) + const client = createClient(app.bearerOnly('anotherapp'), realmName) return client.then((installation) => { app.build(installation) @@ -224,6 +221,6 @@ test('Should invoke admin logout.', t => { test('teardown', t => { return realmManager.then((realm) => { app.destroy() - admin.destroy(realmName) + deleteRealm(realmName) }) }) diff --git a/test/keycloak-connect-web-enforcer-spec.js b/test/keycloak-connect-web-enforcer-spec.js index f826b486..035a4256 100644 --- a/test/keycloak-connect-web-enforcer-spec.js +++ b/test/keycloak-connect-web-enforcer-spec.js @@ -13,20 +13,17 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' +import test from 'blue-tape' +import { NodeApp } from './fixtures/node-console/index.js' +import { createClient, createRealm, deleteRealm } from './utils/realm.js' +import { newPage as page } from './utils/webdriver.js' -const test = require('blue-tape') -const admin = require('./utils/realm') - -const page = require('./utils/webdriver').newPage -const NodeApp = require('./fixtures/node-console/index').NodeApp - -const realmManager = admin.createRealm() +const realmManager = createRealm() const app = new NodeApp() test('setup', t => { return realmManager.then(() => { - return admin.createClient(app.enforcerResourceServer()) + return createClient(app.enforcerResourceServer()) .then((installation) => { return app.build(installation) }) @@ -56,7 +53,7 @@ test('Should be able to access resource protected by the policy enforcer', t => test('teardown', t => { return realmManager.then((realm) => { app.destroy() - admin.destroy('test-realm') + deleteRealm('test-realm') page.quit() }) }) diff --git a/test/keycloak-connect-web-spec.js b/test/keycloak-connect-web-spec.js index 5ed8f219..16d84d4e 100644 --- a/test/keycloak-connect-web-spec.js +++ b/test/keycloak-connect-web-spec.js @@ -13,24 +13,19 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -const test = require('blue-tape') -const admin = require('./utils/realm') -const TestVector = require('./utils/helper').TestVector - -const page = require('./utils/webdriver').newPage -const realmAccountPage = require('./utils/webdriver').realmAccountPage -const driver = require('./utils/webdriver').driver -const NodeApp = require('./fixtures/node-console/index').NodeApp -const session = require('express-session') - -const realmManager = admin.createRealm() +import test from 'blue-tape' +import session from 'express-session' +import { NodeApp } from './fixtures/node-console/index.js' +import { TestVector } from './utils/helper.js' +import { createClient, createRealm, deleteRealm } from './utils/realm.js' +import { driver, newPage as page, realmAccountPage } from './utils/webdriver.js' + +const realmManager = createRealm() const app = new NodeApp() test('setup', t => { return realmManager.then(() => { - return admin.createClient(app.publicClient()) + return createClient(app.publicClient()) .then((installation) => { return app.build(installation) }) @@ -39,7 +34,7 @@ test('setup', t => { // test('setup', t => { // return client = realmManager.then((realm) => { -// return admin.createClient(app.publicClient()); +// return createClient(app.publicClient()); // }); // }); @@ -135,7 +130,7 @@ test.skip('SSO should work for nodejs app and testRealmAccountPage', t => { test.skip('Public client should be redirected to GitHub when idpHint is provided', t => { t.plan(1) const app = new NodeApp() - const client = admin.createClient(app.publicClient('appIdP')) + const client = createClient(app.publicClient('appIdP')) return client.then((installation) => { app.build(installation, { store: new session.MemoryStore(), idpHint: 'github' }) @@ -167,7 +162,7 @@ test.skip('User should be forbidden to access restricted page', t => { test.skip('Public client should be forbidden for invalid public key', t => { t.plan(2) const app = new NodeApp() - const client = admin.createClient(app.publicClient('app2')) + const client = createClient(app.publicClient('app2')) return client.then((installation) => { installation['realm-public-key'] = TestVector.wrongRealmPublicKey @@ -195,7 +190,7 @@ test.skip('Public client should be forbidden for invalid public key', t => { test.skip('Confidential client should be forbidden for invalid public key', t => { t.plan(3) const app = new NodeApp() - const client = admin.createClient(app.confidential('app3')) + const client = createClient(app.confidential('app3')) return client.then((installation) => { installation['realm-public-key'] = TestVector.wrongRealmPublicKey @@ -253,7 +248,7 @@ test.skip('Should test check SSO after logging in and logging out', t => { test.skip('Public client should work with slash in the end of auth-server-url', t => { t.plan(3) const app = new NodeApp() - const client = admin.createClient(app.publicClient('authServerSlashes')) + const client = createClient(app.publicClient('authServerSlashes')) return client.then((installation) => { installation['auth-server-url'] = 'http://localhost:8080/' @@ -289,7 +284,7 @@ test.skip('Public client should work with slash in the end of auth-server-url', test.skip('App should be able to use cookie-store', t => { t.plan(1) const app = new NodeApp() - const client = admin.createClient(app.publicClient('appCookies')) + const client = createClient(app.publicClient('appCookies')) return client.then((installation) => { app.build(installation, { cookies: true }) @@ -313,7 +308,7 @@ test.skip('App should be able to use cookie-store', t => { test('teardown', t => { return realmManager.then((realm) => { app.destroy() - admin.destroy('test-realm') + deleteRealm('test-realm') page.quit() }) }) diff --git a/test/unit/hconfig-test.js b/test/unit/hconfig-test.js index 089d2902..87d54b3c 100644 --- a/test/unit/hconfig-test.js +++ b/test/unit/hconfig-test.js @@ -1,8 +1,6 @@ -'use strict' - -const test = require('tape-catch') -const RSA = require('rsa-compat').RSA -const Config = require('../../middleware/auth-utils/config') +import { RSA } from 'rsa-compat' +import test from 'tape-catch' +import Config from '../../middleware/auth-utils/config.js' test('Config#configure', (t) => { const cfg = new Config({ realm: 'test-realm' }) diff --git a/test/unit/keycloak-object-test.js b/test/unit/keycloak-object-test.js index eb5b3cc2..629259bb 100644 --- a/test/unit/keycloak-object-test.js +++ b/test/unit/keycloak-object-test.js @@ -13,13 +13,10 @@ * License for the specific language governing permissions and limitations under * the License. */ - -'use strict' - -const test = require('tape') -const Keycloak = require('../../') -const UUID = require('../../uuid') -const session = require('express-session') +import session from 'express-session' +import test from 'tape' +import Keycloak from '../../keycloak.js' +import UUID from '../../uuid.js' let kc = null diff --git a/test/utils/config.js b/test/utils/config.js index a4854b9e..61d15a53 100644 --- a/test/utils/config.js +++ b/test/utils/config.js @@ -4,7 +4,6 @@ * @param {object} username - Username to any user with credentials to create realms * @param {object} password - password */ -'use strict' const settings = { baseUrl: 'http://127.0.0.1:8080', @@ -15,4 +14,4 @@ const settings = { clientId: 'admin-cli' } -module.exports = settings +export default settings diff --git a/test/utils/helper.js b/test/utils/helper.js index ebb9993b..90fa16bd 100644 --- a/test/utils/helper.js +++ b/test/utils/helper.js @@ -13,11 +13,10 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' /** * A helper for test cases and fixtures */ -const fs = require('fs') +import fs from 'node:fs' /** * Utility to parse realm templates @@ -28,13 +27,13 @@ const fs = require('fs') * @param {object} hostname - Host name which the client app will listen. */ -function parse (file, realmName) { +export function parse (file, realmName) { const content = fs.readFileSync(file, 'utf8') .replace(/{{realm}}/g, realmName) return JSON.parse(content) } -function parseClient (file, httpPort, name) { +export function parseClient (file, httpPort, name) { const port = httpPort || '3000' const content = fs.readFileSync(file, 'utf8') .replace(/{{name}}/g, name) @@ -47,7 +46,7 @@ function parseClient (file, httpPort, name) { * Utility to provide testing vectors instead of * a bunch of duplicate files with small changes */ -function TestVector () { +export function TestVector () { } TestVector.wrongRealmPublicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAikGBvYGniAJ59ZjpaSDw2o+j40Ila/dWfN8qA1dzXJesH9Z1sZrcevJB+rfxoZDaWMz2l9Q3OxG/qolTpsQl8NBdb5tymic9qDkAIsiyKThzjcfs5lOSxfnkHn6+Z0QbrYnXQs/cGvQ1Ai81M1M1O6BHDWu05n8c977h+BsfLmqGj7MZZj9gw9RM84RIKDGHTbFh9YyXBJVtqbOhRD7hcB0O9olDZb7mQ5A8gsMctcUhsVBy3xKCLMD41XU92rQ9FAlsV9mBglLqaVWr2mxQItN3lgjE02L8UyorI3T0uprIsnv7B2NwUC5ZhwZGfnBznUPVrT6makEJklpg5if3qQIDAQAB' @@ -58,18 +57,13 @@ TestVector.notBeforeValidPayload = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6 TestVector.notBeforeWrongKeyPairPayload = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IkZKODZHY0YzalRiTkxPY280TnZaa1VDSVVtZllDcW9xdE9RZU1mYmhObEUifQ.eyJpYXQiOjE1NTY2MTg2NjIsInJlc291cmNlIjoiYWRtaW5hcHA2IiwiYWN0aW9uIjoiUFVTSF9OT1RfQkVGT1JFIiwibm90QmVmb3JlIjoxNTg3MDQ3NTM3fQ.X0EoW-9N_6jOn9VFkm3HxTwZS2cCm0ChCH3ddYcAnVcugGSrvv1K5vQy9czlalvEnLZ_HpaWNWoBYA7hoqR5S600A-BSMHrb6oPt2B1JW8htgubD8NbJC2COsOGAbxLupO9YEP_oodzpAF5ikMB3Pm2g1e66BFvotSQHAtgg7HepzywvPrkYork44worrX2ByHVK4Y5Or6BWleEx1pa59dqmZNfupaL4pKSG9j7H9NM1YmEuKwjHr9PIyN7bPkx64LamI5aUIk5rjIM8plnxiayEgdCr9B6ag0xVoKggv3GV0m-XsRkbUPl91EbLQXwSCYdL5TQsvK5uJqkba9eiRA' TestVector.notBeforeIncompletePayload = '.eyJyZXNvdXJjZSI6ImFkbWluYXBwNSIsImFjdGlvbiI6IlBVU0hfTk9UX0JFRk9SRSIsIm5vdEJlZm9yZSI6MTU4NzA0NzUzN30.' -module.exports = { - parse, - TestVector, - parseClient, - dummyReply: { - access_token: 'Dummy access token', - expires_in: 2, - refresh_expires_in: 1800, - refresh_token: 'Dummy refresh token', - token_type: 'bearer', - id_token: 'Dummy id token', - 'not-before-policy': 1462208947, - session_state: '22e0b5bd-fb0f-4f99-93aa-a60c4b934c88' - } +export const dummyReply = { + access_token: 'Dummy access token', + expires_in: 2, + refresh_expires_in: 1800, + refresh_token: 'Dummy refresh token', + token_type: 'bearer', + id_token: 'Dummy id token', + 'not-before-policy': 1462208947, + session_state: '22e0b5bd-fb0f-4f99-93aa-a60c4b934c88' } diff --git a/test/utils/realm.js b/test/utils/realm.js index 8eb84cc8..336dda0d 100644 --- a/test/utils/realm.js +++ b/test/utils/realm.js @@ -13,17 +13,16 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' /** * A wrapper to keycloak-admin-client with an initial setup */ /* eslint new-cap: ["error", { "newIsCap": false }] */ -const keycloakAdminClient = require('@keycloak/keycloak-admin-client') -const parse = require('./helper').parse -const settings = require('./config') -const realmTemplate = 'test/fixtures/testrealm.json' +import KeycloakAdminClient from '@keycloak/keycloak-admin-client' +import settings from './config.js' +import { parse } from './helper.js' -const kca = new keycloakAdminClient.default(settings) +const realmTemplate = 'test/fixtures/testrealm.json' +const kca = new KeycloakAdminClient.default(settings) /** * Create realms based on port and name specified @@ -32,7 +31,7 @@ const kca = new keycloakAdminClient.default(settings) * @param {object} name - Realm name * @returns {Promise} A promise that will resolve with the realm object. */ -function createRealm (realmName) { +export function createRealm (realmName) { const name = realmName || 'test-realm' return kca.auth(settings).then(() => { return kca.realms.create(parse(realmTemplate, name)).then(() => { @@ -49,7 +48,7 @@ function createRealm (realmName) { * @param {object} name - client name * @returns {Promise} A promise that will resolve with the realm object. */ -function createClient (clientRep, realmName) { +export function createClient (clientRep, realmName) { const realm = realmName || 'test-realm' kca.setConfig({ realmName: 'master' }) return kca.auth(settings).then(() => { @@ -65,7 +64,7 @@ function createClient (clientRep, realmName) { * Remove the realm based on the name provided * @param {object} realm - Realm name */ -function destroy (realm) { +export function deleteRealm (realm) { kca.setConfig({ realmName: 'master' }) kca.auth(settings).then(() => { return kca.realms.del({ realm }) @@ -73,9 +72,3 @@ function destroy (realm) { console.error('Realm was not found to remove:', err) }) } - -module.exports = { - createRealm, - createClient, - destroy -} diff --git a/test/utils/token.js b/test/utils/token.js index d7077282..62d89f17 100644 --- a/test/utils/token.js +++ b/test/utils/token.js @@ -1,8 +1,6 @@ -'use strict' +import requester from 'keycloak-request-token' -const requester = require('keycloak-request-token') const baseUrl = 'http://127.0.0.1:8080' - const defaultSettings = { username: 'test-admin', password: 'password', @@ -11,7 +9,7 @@ const defaultSettings = { realmName: 'service-node-realm' } -module.exports = (options) => { +export default function getToken (options) { const settings = Object.assign({}, defaultSettings, options) return requester(baseUrl, settings) } diff --git a/test/utils/webdriver.js b/test/utils/webdriver.js index ee8cb6fa..e71ebb4f 100644 --- a/test/utils/webdriver.js +++ b/test/utils/webdriver.js @@ -13,16 +13,19 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' /** * An utility with the specifics for selenium */ -const chrome = require('selenium-webdriver/chrome') -const webdriver = require('selenium-webdriver') -const args = require('minimist')(process.argv.slice(2)) -const By = webdriver.By -const until = webdriver.until -const driver = createDriver() +import chromedriver from 'chromedriver' +import minimist from 'minimist' +import webdriver from 'selenium-webdriver' +import chrome from 'selenium-webdriver/chrome.js' + +const args = minimist(process.argv.slice(2)) +const { By, until } = webdriver + +export { webdriver } +export const driver = createDriver() function createDriver () { chrome.setDefaultService(new chrome.ServiceBuilder(determineChromedriverPath()).build()) @@ -56,7 +59,6 @@ function determineChromedriverPath () { let path = args.chromedriverPath || process.env.CHROMEDRIVER_PATH if (!path) { - const chromedriver = require('chromedriver') path = chromedriver.path } @@ -161,7 +163,7 @@ ConsolePage.prototype.h1 = () => { return driver.findElement(By.tagName('h1')) } -const newPage = new ConsolePage() +export const newPage = new ConsolePage() function RealmAccountPage () {} @@ -180,11 +182,4 @@ RealmAccountPage.prototype.logout = function () { return driver.findElement(By.linkText('Sign out')).then(webElement => webElement.click()) } -const realmAccountPage = new RealmAccountPage() - -module.exports = { - driver, - webdriver, - newPage, - realmAccountPage -} +export const realmAccountPage = new RealmAccountPage() diff --git a/uuid.js b/uuid.js index 3794be1b..2c7022ad 100644 --- a/uuid.js +++ b/uuid.js @@ -13,9 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ -'use strict' - -module.exports = function () { +export default function uuid () { const s = [] const hexDigits = '0123456789abcdef' for (let i = 0; i < 36; i++) {