Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

keycloak-mock

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

keycloak-mock - npm Package Compare versions

Comparing version 0.0.7 to 0.0.8

dist/jest.config.d.ts

20

lib/index.ts

@@ -1,3 +0,10 @@

export { Mock, MockOptions, activateMock, deactivateMock, getMock, getMockInstance } from "./mock";
export {
Mock,
MockOptions,
activateMock,
deactivateMock,
getMock,
getMockInstance,
} from "./mock";
export {
MockInstance,

@@ -8,3 +15,10 @@ MockInstanceParams,

} 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";
import { JWK } from "node-jose";
import createBearerToken from "./createBearerToken";
import MockDatabase, { MockUserProfile, CreateMockUserProfileOptions } from "./database";
import MockDatabase, {
MockUserProfile,
CreateMockUserProfileOptions,
} from "./database";

@@ -36,2 +39,6 @@ export interface CreateMockInstanceOptions {

createURL(path: string): string {
return `${this.params.authServerURL}${path}`;
}
createBearerToken(sub: string, expiresIn: number = 3600): string {

@@ -54,3 +61,5 @@ const user = this.database.findUserByID(sub);

const createMockInstance = async (options: CreateMockInstanceOptions): Promise<MockInstance> => {
const createMockInstance = async (
options: CreateMockInstanceOptions
): Promise<MockInstance> => {
const store = JWK.createKeyStore();

@@ -57,0 +66,0 @@ const defaultKey = await store.generate("RSA", 2048, { use: "sig" });

17

lib/mock.ts
import nock, { Scope } from "nock";
import { ViewFn } from "./types";
import { MockInstance } from "./instance";
import { decodeTokenAndAttachUser } from "./middlewares";
import { listCertificates, getUser, getUserInfo } from "./views";
import { ViewFn, listCertificates, getUser, getUserInfo } from "./views";
let __activeMocks__: Map<string, Mock> = new Map<string, Mock>();

@@ -31,3 +32,5 @@

.get(`/realms/${realm}/protocol/openid-connect/certs`)
.reply(function() {
.reply(async function() {
await decodeTokenAndAttachUser(instance, this.req);
if (options && options.listCertificatesView) {

@@ -40,3 +43,5 @@ return options.listCertificatesView(instance, this.req);

.get(new RegExp(`/admin/realms/${realm}/users/(.+)`))
.reply(function() {
.reply(async function() {
await decodeTokenAndAttachUser(instance, this.req);
if (options && options.getUserView) {

@@ -49,3 +54,5 @@ return options.getUserView(instance, this.req);

.get(`/realms/${realm}/protocol/openid-connect/userinfo`)
.reply(function() {
.reply(async function() {
await decodeTokenAndAttachUser(instance, this.req);
if (options && options.getUserInfoView) {

@@ -52,0 +59,0 @@ return options.getUserInfoView(instance, this.req);

@@ -1,48 +0,9 @@

import jwt from "jsonwebtoken";
import { JWK } from "node-jose";
import head from "lodash/head";
import last from "lodash/last";
import { ViewFn } from "../types";
import { MockInstance } from "../instance";
import { ViewFn } from "./types";
const getUser: ViewFn = (instance, request) => {
const { user } = request;
const getUser: ViewFn = async (instance, request) => {
const token = (head(request.headers.authorization) || "").split(" ")[1];
if (!token) {
return [401, "Authorization required"];
}
// @ts-ignore
let decodedToken = null;
try {
decodedToken = jwt.decode(token, { complete: true });
} catch (error) {
return [403, "Access denied - cannot decode"];
}
// @ts-ignore
const rawKey = instance.store.get(decodedToken.header.kid);
if (!rawKey) {
return [403, "Access denied - non-existent key"];
}
const key = await JWK.asKey(rawKey);
try {
jwt.verify(token, key.toPEM(false), { algorithms: ["RS256"] });
} catch (error) {
return [403, "Access denied - invalid signature"];
}
const requestSub = last(request.path.split("/"));
// @ts-ignore
if (requestSub !== decodedToken.payload.sub) {
return [403, "Access denied - not you"];
}
// @ts-ignore
const user = instance.database.findUserByID(decodedToken.payload.sub);
if (!user) {
return [403, "Access denied - non-existent user"];
return [403, "Access denied"];
}

@@ -49,0 +10,0 @@

@@ -1,41 +0,9 @@

import jwt from "jsonwebtoken";
import { JWK } from "node-jose";
import head from "lodash/head";
import { ViewFn } from "../types";
import { MockInstance } from "../instance";
import { ViewFn } from "./types";
const getUserInfo: ViewFn = (instance, request) => {
const { user } = request;
const getUserInfo: ViewFn = async (instance, request) => {
const token = (head(request.headers.authorization) || "").split(" ")[1];
if (!token) {
return [401, "Authorization required"];
}
// @ts-ignore
let decodedToken = null;
try {
decodedToken = jwt.decode(token, { complete: true });
} catch (error) {
return [403, "Access denied - cannot decode"];
}
// @ts-ignore
const rawKey = instance.store.get(decodedToken.header.kid);
if (!rawKey) {
return [403, "Access denied - non-existent key"];
}
const key = await JWK.asKey(rawKey);
try {
jwt.verify(token, key.toPEM(false), { algorithms: ["RS256"] });
} catch (error) {
return [403, "Access denied - invalid signature"];
}
// @ts-ignore
const user = instance.database.findUserByID(decodedToken.payload.sub);
if (!user) {
return [403, "Access denied - non-existent user"];
return [403, "Access denied"];
}

@@ -42,0 +10,0 @@

export { default as listCertificates } from "./listCertificates";
export { default as getUser } from "./getUser";
export { default as getUserInfo } from "./getUserInfo";
export { ViewFn } from "./types";

@@ -1,9 +0,8 @@

import { ViewFn } from "./types";
import { ViewFn } from "../types";
import { MockInstance } from "../instance";
const listCertificates: ViewFn = (instance, request) => {
return Promise.resolve([200, instance.store.toJSON(false)]);
return [200, instance.store.toJSON(false)];
};
export default listCertificates;
{
"name": "keycloak-mock",
"version": "0.0.7",
"version": "0.0.8",
"description": "Keycloak server mock for Node.js",

@@ -9,4 +9,8 @@ "main": "dist/index.js",

"license": "MIT",
"engines": {
"node": ">=8.0.0"
},
"scripts": {
"build": "tsc",
"test": "jest -i tests/",
"format": "prettier --write '**/*.ts'",

@@ -17,6 +21,10 @@ "format:verify": "prettier --check '**/*.ts'",

"devDependencies": {
"@types/jest": "^25.1.3",
"@types/jsonwebtoken": "^8.3.7",
"@types/node-jose": "^1.1.2",
"@types/uuid": "^7.0.0",
"axios": "^0.19.2",
"jest": "^24.0.0",
"prettier": "^1.19.1",
"ts-jest": "^24.3.0",
"typescript": "^3.8.2"

@@ -30,4 +38,4 @@ },

"node-jose": "^1.1.3",
"uuid": "^7.0.1"
"uuid": "^7.0.2"
}
}

@@ -12,5 +12,8 @@ # Keycloak Mock

Tested with Node.js 8.x, 10.x, 12.x, 13.x
### What works
* `/auth/[realm]/protocol/openid-connect/certs`
* `/auth/[realm]/protocol/openid-connect/userinfo`
* `/[realm]/protocol/openid-connect/certs`
* `/[realm]/protocol/openid-connect/userinfo`
* `/admin/realms/[realm]/users/[userid]`

@@ -59,7 +62,12 @@ ## Usage

listCertificatesView: (instance, request) => {
return Promise.resolve([500, ""]);
return [500, ""];
},
getUser: (instance, request) => {
// might be null if not authorized
console.log(request.user);
return [500, ""];
},
getUserInfoView: (instance, request) => {
return Promise.resolve([500, ""]);
return [500, ""];
},
})

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc