keycloak-mock
Advanced tools
Comparing version 0.0.8 to 0.0.9
@@ -1,4 +0,4 @@ | ||
export { Mock, MockOptions, activateMock, deactivateMock, getMock, getMockInstance } from "./mock"; | ||
export { Mock, MockOptions, activateMock, deactivateMock, getMock, getMockInstance, } from "./mock"; | ||
export { MockInstance, MockInstanceParams, CreateMockInstanceOptions, createMockInstance, } from "./instance"; | ||
export { default as MockDatabase, MockUserProfile, CreateMockUserProfileOptions } from "./database"; | ||
export { default as createBearerToken, CreateTokenOptions } from "./createBearerToken"; | ||
export { default as MockDatabase, MockUserProfile, CreateMockUserProfileOptions, } from "./database"; | ||
export { default as createBearerToken, CreateTokenOptions, } from "./createBearerToken"; |
@@ -19,2 +19,3 @@ import { JWK } from "node-jose"; | ||
constructor(store: JWK.KeyStore, defaultKey: JWK.Key, database: MockDatabase, params: MockInstanceParams); | ||
createURL(path: string): string; | ||
createBearerToken(sub: string, expiresIn?: number): string; | ||
@@ -21,0 +22,0 @@ } |
@@ -52,2 +52,5 @@ "use strict"; | ||
} | ||
MockInstance.prototype.createURL = function (path) { | ||
return "" + this.params.authServerURL + path; | ||
}; | ||
MockInstance.prototype.createBearerToken = function (sub, expiresIn) { | ||
@@ -54,0 +57,0 @@ if (expiresIn === void 0) { expiresIn = 3600; } |
import { Scope } from "nock"; | ||
import { ViewFn } from "./types"; | ||
import { MockInstance } from "./instance"; | ||
import { ViewFn } from "./views"; | ||
export interface Mock { | ||
@@ -5,0 +5,0 @@ scope: Scope; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -7,2 +43,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
var nock_1 = __importDefault(require("nock")); | ||
var middlewares_1 = require("./middlewares"); | ||
var views_1 = require("./views"); | ||
@@ -20,20 +57,47 @@ var __activeMocks__ = new Map(); | ||
.reply(function () { | ||
if (options && options.listCertificatesView) { | ||
return options.listCertificatesView(instance, this.req); | ||
} | ||
return views_1.listCertificates(instance, this.req); | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, middlewares_1.decodeTokenAndAttachUser(instance, this.req)]; | ||
case 1: | ||
_a.sent(); | ||
if (options && options.listCertificatesView) { | ||
return [2 /*return*/, options.listCertificatesView(instance, this.req)]; | ||
} | ||
return [2 /*return*/, views_1.listCertificates(instance, this.req)]; | ||
} | ||
}); | ||
}); | ||
}) | ||
.get(new RegExp("/admin/realms/" + realm + "/users/(.+)")) | ||
.reply(function () { | ||
if (options && options.getUserView) { | ||
return options.getUserView(instance, this.req); | ||
} | ||
return views_1.getUser(instance, this.req); | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, middlewares_1.decodeTokenAndAttachUser(instance, this.req)]; | ||
case 1: | ||
_a.sent(); | ||
if (options && options.getUserView) { | ||
return [2 /*return*/, options.getUserView(instance, this.req)]; | ||
} | ||
return [2 /*return*/, views_1.getUser(instance, this.req)]; | ||
} | ||
}); | ||
}); | ||
}) | ||
.get("/realms/" + realm + "/protocol/openid-connect/userinfo") | ||
.reply(function () { | ||
if (options && options.getUserInfoView) { | ||
return options.getUserInfoView(instance, this.req); | ||
} | ||
return views_1.getUserInfo(instance, this.req); | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, middlewares_1.decodeTokenAndAttachUser(instance, this.req)]; | ||
case 1: | ||
_a.sent(); | ||
if (options && options.getUserInfoView) { | ||
return [2 /*return*/, options.getUserInfoView(instance, this.req)]; | ||
} | ||
return [2 /*return*/, views_1.getUserInfo(instance, this.req)]; | ||
} | ||
}); | ||
}); | ||
}); | ||
@@ -40,0 +104,0 @@ var mock = { scope: scope, instance: instance }; |
@@ -1,3 +0,3 @@ | ||
import { ViewFn } from "./types"; | ||
import { ViewFn } from "../types"; | ||
declare const getUser: ViewFn; | ||
export default getUser; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var getUser = function (instance, request) { | ||
var user = request.user; | ||
if (!user) { | ||
return [403, "Access denied"]; | ||
} | ||
return [ | ||
200, | ||
{ | ||
id: user.sub, | ||
firstName: user.given_name, | ||
lastName: user.family_name, | ||
username: user.preferred_username, | ||
email: user.email, | ||
enabled: true, | ||
totp: false, | ||
emailVerified: user.email_verified, | ||
createdTimestamp: user.created_at, | ||
attributes: user.attributes, | ||
disableableCredentialTypes: ["password"], | ||
requiredActions: [], | ||
federatedIdentities: [], | ||
notBefore: 0, | ||
access: { | ||
manageGroupMembership: true, | ||
view: true, | ||
mapRoles: true, | ||
impersonate: false, | ||
manage: true, | ||
}, | ||
}, | ||
]; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var jsonwebtoken_1 = __importDefault(require("jsonwebtoken")); | ||
var node_jose_1 = require("node-jose"); | ||
var head_1 = __importDefault(require("lodash/head")); | ||
var last_1 = __importDefault(require("lodash/last")); | ||
var getUser = function (instance, request) { return __awaiter(void 0, void 0, void 0, function () { | ||
var token, decodedToken, rawKey, key, requestSub, user; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
token = (head_1.default(request.headers.authorization) || "").split(" ")[1]; | ||
if (!token) { | ||
return [2 /*return*/, [401, "Authorization required"]]; | ||
} | ||
decodedToken = null; | ||
try { | ||
decodedToken = jsonwebtoken_1.default.decode(token, { complete: true }); | ||
} | ||
catch (error) { | ||
return [2 /*return*/, [403, "Access denied - cannot decode"]]; | ||
} | ||
rawKey = instance.store.get(decodedToken.header.kid); | ||
if (!rawKey) { | ||
return [2 /*return*/, [403, "Access denied - non-existent key"]]; | ||
} | ||
return [4 /*yield*/, node_jose_1.JWK.asKey(rawKey)]; | ||
case 1: | ||
key = _a.sent(); | ||
try { | ||
jsonwebtoken_1.default.verify(token, key.toPEM(false), { algorithms: ["RS256"] }); | ||
} | ||
catch (error) { | ||
return [2 /*return*/, [403, "Access denied - invalid signature"]]; | ||
} | ||
requestSub = last_1.default(request.path.split("/")); | ||
// @ts-ignore | ||
if (requestSub !== decodedToken.payload.sub) { | ||
return [2 /*return*/, [403, "Access denied - not you"]]; | ||
} | ||
user = instance.database.findUserByID(decodedToken.payload.sub); | ||
if (!user) { | ||
return [2 /*return*/, [403, "Access denied - non-existent user"]]; | ||
} | ||
return [2 /*return*/, [ | ||
200, | ||
{ | ||
id: user.sub, | ||
firstName: user.given_name, | ||
lastName: user.family_name, | ||
username: user.preferred_username, | ||
email: user.email, | ||
enabled: true, | ||
totp: false, | ||
emailVerified: user.email_verified, | ||
createdTimestamp: user.created_at, | ||
attributes: user.attributes, | ||
disableableCredentialTypes: ["password"], | ||
requiredActions: [], | ||
federatedIdentities: [], | ||
notBefore: 0, | ||
access: { | ||
manageGroupMembership: true, | ||
view: true, | ||
mapRoles: true, | ||
impersonate: false, | ||
manage: true, | ||
}, | ||
}, | ||
]]; | ||
} | ||
}); | ||
}); }; | ||
exports.default = getUser; |
@@ -1,3 +0,3 @@ | ||
import { ViewFn } from "./types"; | ||
import { ViewFn } from "../types"; | ||
declare const getUserInfo: ViewFn; | ||
export default getUserInfo; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var getUserInfo = function (instance, request) { | ||
var user = request.user; | ||
if (!user) { | ||
return [403, "Access denied"]; | ||
} | ||
return [200, user]; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var jsonwebtoken_1 = __importDefault(require("jsonwebtoken")); | ||
var node_jose_1 = require("node-jose"); | ||
var head_1 = __importDefault(require("lodash/head")); | ||
var getUserInfo = function (instance, request) { return __awaiter(void 0, void 0, void 0, function () { | ||
var token, decodedToken, rawKey, key, user; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
token = (head_1.default(request.headers.authorization) || "").split(" ")[1]; | ||
if (!token) { | ||
return [2 /*return*/, [401, "Authorization required"]]; | ||
} | ||
decodedToken = null; | ||
try { | ||
decodedToken = jsonwebtoken_1.default.decode(token, { complete: true }); | ||
} | ||
catch (error) { | ||
return [2 /*return*/, [403, "Access denied - cannot decode"]]; | ||
} | ||
rawKey = instance.store.get(decodedToken.header.kid); | ||
if (!rawKey) { | ||
return [2 /*return*/, [403, "Access denied - non-existent key"]]; | ||
} | ||
return [4 /*yield*/, node_jose_1.JWK.asKey(rawKey)]; | ||
case 1: | ||
key = _a.sent(); | ||
try { | ||
jsonwebtoken_1.default.verify(token, key.toPEM(false), { algorithms: ["RS256"] }); | ||
} | ||
catch (error) { | ||
return [2 /*return*/, [403, "Access denied - invalid signature"]]; | ||
} | ||
user = instance.database.findUserByID(decodedToken.payload.sub); | ||
if (!user) { | ||
return [2 /*return*/, [403, "Access denied - non-existent user"]]; | ||
} | ||
return [2 /*return*/, [200, user]]; | ||
} | ||
}); | ||
}); }; | ||
exports.default = getUserInfo; |
export { default as listCertificates } from "./listCertificates"; | ||
export { default as getUser } from "./getUser"; | ||
export { default as getUserInfo } from "./getUserInfo"; | ||
export { ViewFn } from "./types"; |
@@ -1,3 +0,3 @@ | ||
import { ViewFn } from "./types"; | ||
import { ViewFn } from "../types"; | ||
declare const listCertificates: ViewFn; | ||
export default listCertificates; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var listCertificates = function (instance, request) { | ||
return Promise.resolve([200, instance.store.toJSON(false)]); | ||
return [200, instance.store.toJSON(false)]; | ||
}; | ||
exports.default = listCertificates; |
{ | ||
"name": "keycloak-mock", | ||
"version": "0.0.8", | ||
"version": "0.0.9", | ||
"description": "Keycloak server mock for Node.js", | ||
@@ -17,3 +17,3 @@ "main": "dist/index.js", | ||
"format:verify": "prettier --check '**/*.ts'", | ||
"npm-publish": "yarn format && yarn build && npm publish --access public" | ||
"prepack": "yarn format && yarn build" | ||
}, | ||
@@ -20,0 +20,0 @@ "devDependencies": { |
@@ -11,3 +11,3 @@ { | ||
"target": "es5", | ||
"baseUrl": ".", | ||
"baseUrl": "./", | ||
"outDir": "./dist", | ||
@@ -17,3 +17,4 @@ "declaration": true, | ||
}, | ||
"exclude": ["./dist"] | ||
"exclude": ["./dist"], | ||
"include": ["./lib/*"] | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
40799
37
966