Socket
Socket
Sign inDemoInstall

oauth2-mock-server

Package Overview
Dependencies
69
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.0.2 to 6.0.0

11

CHANGELOG.md

@@ -7,4 +7,13 @@ # Changelog

## [5.0.2](https://github.com/axa-group/oauth2-mock-server/compare/v5.0.1...v5.0.2) — 2022-02-20
## [6.0.0](https://github.com/axa-group/oauth2-mock-server/compare/v5.0.2...v6.0.0) — 2023-06-19
### Changed
- **Breaking:** No longer support Node.js 14
- Fix authorize endpoint compliance (remove scope requirement, make state optional) (by [jirutka](https://github.com/jirutka))
- Add support for Node.js 20
- Update dependencies
## [5.0.2](https://github.com/axa-group/oauth2-mock-server/compare/v5.0.1...v5.0.2) — 2023-02-20
### Security

@@ -11,0 +20,0 @@

@@ -0,0 +0,0 @@ export { JWKStore } from './lib/jwk-store';

@@ -0,0 +0,0 @@ "use strict";

@@ -6,2 +6,3 @@ /// <reference types="node" />

export declare function assertIsString(input: unknown, errorMessage: string): asserts input is string;
export declare function assertIsStringOrUndefined(input: unknown, errorMessage: string): asserts input is string | undefined;
export declare function assertIsAddressInfo(input: string | null | AddressInfo): asserts input is AddressInfo;

@@ -8,0 +9,0 @@ export declare function assertIsPlainObject(obj: unknown, errMessage: string): asserts obj is Record<string, unknown>;

14

dist/lib/helpers.js

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.readJsonFromFile = exports.shift = exports.assertIsValidTokenRequest = exports.assertIsPlainObject = exports.assertIsAddressInfo = exports.assertIsString = exports.defaultTokenTtl = void 0;
exports.readJsonFromFile = exports.shift = exports.assertIsValidTokenRequest = exports.assertIsPlainObject = exports.assertIsAddressInfo = exports.assertIsStringOrUndefined = exports.assertIsString = exports.defaultTokenTtl = void 0;
const assert_1 = require("assert");

@@ -18,2 +18,8 @@ const fs_1 = require("fs");

exports.assertIsString = assertIsString;
function assertIsStringOrUndefined(input, errorMessage) {
if (typeof input !== 'string' && input !== undefined) {
throw new assert_1.AssertionError({ message: errorMessage });
}
}
exports.assertIsStringOrUndefined = assertIsStringOrUndefined;
function assertIsAddressInfo(input) {

@@ -34,7 +40,7 @@ if (input === null || typeof input === 'string') {

if ('scope' in body) {
assertIsString(body.scope, "Invalid 'scope' type");
assertIsString(body['scope'], "Invalid 'scope' type");
}
assertIsString(body.grant_type, "Invalid 'grant_type' type");
assertIsString(body['grant_type'], "Invalid 'grant_type' type");
if ('code' in body) {
assertIsString(body.code, "Invalid 'code' type");
assertIsString(body['code'], "Invalid 'code' type");
}

@@ -41,0 +47,0 @@ }

@@ -0,0 +0,0 @@ /// <reference types="node" />

@@ -26,3 +26,3 @@ "use strict";

__classPrivateFieldSet(this, _HttpServer_isSecured, false, "f");
if ((options === null || options === void 0 ? void 0 : options.key) && (options === null || options === void 0 ? void 0 : options.cert)) {
if (options?.key && options?.cert) {
__classPrivateFieldSet(this, _HttpServer_server, (0, https_1.createServer)(options, requestListener), "f");

@@ -29,0 +29,0 @@ __classPrivateFieldSet(this, _HttpServer_isSecured, true, "f");

@@ -0,0 +0,0 @@ import { JWK } from './types';

@@ -18,2 +18,3 @@ "use strict";

const jose_1 = require("jose");
const assert_1 = require("assert");
const generateRandomKid = () => {

@@ -57,10 +58,10 @@ return (0, crypto_1.randomBytes)(40).toString('hex');

function normalizeKeyKid(jwk, opts) {
if (jwk.kid !== undefined) {
if (jwk['kid'] !== undefined) {
return;
}
if (opts !== undefined && opts.kid !== undefined) {
jwk.kid = opts.kid;
jwk['kid'] = opts.kid;
}
else {
jwk.kid = generateRandomKid();
jwk['kid'] = generateRandomKid();
}

@@ -135,2 +136,5 @@ }

const cleaner = privateToPublicTransformerMap[key.alg];
if (cleaner === undefined) {
throw new Error(`Unsupported algo '{key.alg}'`);
}
keys.push(cleaner(key));

@@ -151,2 +155,7 @@ }

const [key] = __classPrivateFieldGet(this, _KeyRotator_keys, "f").splice(i, 1);
if (key === undefined) {
throw new assert_1.AssertionError({
message: 'Unexpected error. key is supposed to exist',
});
}
__classPrivateFieldGet(this, _KeyRotator_keys, "f").push(key);

@@ -153,0 +162,0 @@ return key;

@@ -0,0 +0,0 @@ /// <reference types="node" />

@@ -32,4 +32,3 @@ "use strict";

async buildToken(opts) {
var _a;
const key = this.keys.get(opts === null || opts === void 0 ? void 0 : opts.kid);
const key = this.keys.get(opts?.kid);
if (key === undefined) {

@@ -46,12 +45,12 @@ throw new Error('Cannot build token: Unknown key.');

iat: timestamp,
exp: timestamp + ((_a = opts === null || opts === void 0 ? void 0 : opts.expiresIn) !== null && _a !== void 0 ? _a : helpers_1.defaultTokenTtl),
exp: timestamp + (opts?.expiresIn ?? helpers_1.defaultTokenTtl),
nbf: timestamp - 10,
};
if ((opts === null || opts === void 0 ? void 0 : opts.scopesOrTransform) !== undefined) {
if (opts?.scopesOrTransform !== undefined) {
const scopesOrTransform = opts.scopesOrTransform;
if (typeof scopesOrTransform === 'string') {
payload.scope = scopesOrTransform;
payload['scope'] = scopesOrTransform;
}
else if (Array.isArray(scopesOrTransform)) {
payload.scope = scopesOrTransform.join(' ');
payload['scope'] = scopesOrTransform.join(' ');
}

@@ -58,0 +57,0 @@ else if (typeof scopesOrTransform === 'function') {

@@ -0,0 +0,0 @@ /// <reference types="node" />

@@ -15,3 +15,3 @@ "use strict";

const iss = new oauth2_issuer_1.OAuth2Issuer();
const serv = new oauth2_service_1.OAuth2Service(iss, oauth2Options === null || oauth2Options === void 0 ? void 0 : oauth2Options.endpoints);
const serv = new oauth2_service_1.OAuth2Service(iss, oauth2Options?.endpoints);
let options = undefined;

@@ -18,0 +18,0 @@ if (key && cert) {

/// <reference types="node" />
/// <reference types="node" />
import { IncomingMessage } from 'http';
import { Express } from 'express';
import { IncomingMessage, type RequestListener } from 'http';
import { EventEmitter } from 'events';

@@ -13,3 +12,3 @@ import { OAuth2Issuer } from './oauth2-issuer';

buildToken(req: IncomingMessage, expiresIn: number, scopesOrTransform: ScopesOrTransform | undefined): Promise<string>;
get requestHandler(): Express;
get requestHandler(): RequestListener;
private buildRequestHandler;

@@ -16,0 +15,0 @@ private openidConfigurationHandler;

@@ -25,3 +25,2 @@ "use strict";

const uuid_1 = require("uuid");
const body_parser_1 = require("body-parser");
const helpers_1 = require("./helpers");

@@ -50,3 +49,3 @@ const types_1 = require("./types");

app.disable('x-powered-by');
app.use((0, body_parser_1.json)());
app.use(express_1.default.json());
app.use((0, cors_1.default)());

@@ -89,3 +88,3 @@ app.get(__classPrivateFieldGet(this, _OAuth2Service_endpoints, "f").wellKnownDocument, this.openidConfigurationHandler);

this.jwksHandler = (_req, res) => {
res.json({ keys: this.issuer.keys.toJSON() });
return res.json({ keys: this.issuer.keys.toJSON() });
};

@@ -163,4 +162,4 @@ this.tokenHandler = async (req, res, next) => {

};
body.id_token = await this.buildToken(req, tokenTtl, xfn);
body.refresh_token = (0, uuid_1.v4)();
body['id_token'] = await this.buildToken(req, tokenTtl, xfn);
body['refresh_token'] = (0, uuid_1.v4)();
}

@@ -181,22 +180,14 @@ const tokenEndpointResponse = {

this.authorizeHandler = (req, res) => {
const { scope, state } = req.query;
const responseType = req.query.response_type;
const redirectUri = req.query.redirect_uri;
const code = (0, uuid_1.v4)();
let queryNonce;
if ('nonce' in req.query) {
(0, helpers_1.assertIsString)(req.query.nonce, 'Invalid nonce type');
queryNonce = req.query.nonce;
}
const { nonce, scope, redirect_uri: redirectUri, response_type: responseType, state, } = req.query;
(0, helpers_1.assertIsString)(redirectUri, 'Invalid redirectUri type');
(0, helpers_1.assertIsString)(scope, 'Invalid scope type');
(0, helpers_1.assertIsString)(state, 'Invalid state type');
(0, helpers_1.assertIsStringOrUndefined)(nonce, 'Invalid nonce type');
(0, helpers_1.assertIsStringOrUndefined)(scope, 'Invalid scope type');
(0, helpers_1.assertIsStringOrUndefined)(state, 'Invalid state type');
const url = new url_1.URL(redirectUri);
if (responseType === 'code') {
if (queryNonce !== undefined) {
__classPrivateFieldGet(this, _OAuth2Service_nonce, "f")[code] = queryNonce;
if (nonce !== undefined) {
__classPrivateFieldGet(this, _OAuth2Service_nonce, "f")[code] = nonce;
}
url.searchParams.set('code', code);
url.searchParams.set('scope', scope);
url.searchParams.set('state', state);
}

@@ -206,2 +197,4 @@ else {

url.searchParams.set('error_description', 'The authorization server does not support obtaining an access token using this response_type.');
}
if (state) {
url.searchParams.set('state', state);

@@ -211,3 +204,3 @@ }

this.emit(types_1.Events.BeforeAuthorizeRedirect, authorizeRedirectUri, req);
res.redirect(url.href);
return res.redirect(url.href);
};

@@ -222,3 +215,3 @@ this.userInfoHandler = (req, res) => {

this.emit(types_1.Events.BeforeUserinfo, userInfoResponse, req);
res.status(userInfoResponse.statusCode).json(userInfoResponse.body);
return res.status(userInfoResponse.statusCode).json(userInfoResponse.body);
};

@@ -233,8 +226,8 @@ this.revokeHandler = (req, res) => {

this.endSessionHandler = (req, res) => {
(0, helpers_1.assertIsString)(req.query.post_logout_redirect_uri, 'Invalid post_logout_redirect_uri type');
(0, helpers_1.assertIsString)(req.query['post_logout_redirect_uri'], 'Invalid post_logout_redirect_uri type');
const postLogoutRedirectUri = {
url: new url_1.URL(req.query.post_logout_redirect_uri),
url: new url_1.URL(req.query['post_logout_redirect_uri']),
};
this.emit(types_1.Events.BeforePostLogoutRedirect, postLogoutRedirectUri, req);
res.redirect(postLogoutRedirectUri.url.href);
return res.redirect(postLogoutRedirectUri.url.href);
};

@@ -249,3 +242,5 @@ this.introspectHandler = (req, res) => {

this.emit(types_1.Events.BeforeIntrospect, introspectResponse, req);
res.status(introspectResponse.statusCode).json(introspectResponse.body);
return res
.status(introspectResponse.statusCode)
.json(introspectResponse.body);
};

@@ -252,0 +247,0 @@ __classPrivateFieldSet(this, _OAuth2Service_issuer, oauth2Issuer, "f");

@@ -0,0 +0,0 @@ import { JWK as JoseJWK } from 'jose';

@@ -0,0 +0,0 @@ "use strict";

@@ -58,5 +58,5 @@ /// <reference types="node" />

export interface TokenBuildOptions {
kid?: string;
scopesOrTransform?: ScopesOrTransform;
expiresIn?: number;
kid?: string | undefined;
scopesOrTransform?: ScopesOrTransform | undefined;
expiresIn?: number | undefined;
}

@@ -63,0 +63,0 @@ export interface JWK extends JWKWithKid {

@@ -0,0 +0,0 @@ "use strict";

#!/usr/bin/env node
export {};
import { OAuth2Server } from './index';
declare const _default: Promise<OAuth2Server | null>;
export default _default;

@@ -7,8 +7,6 @@ #!/usr/bin/env node

Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = require("fs");
const util_1 = require("util");
const promises_1 = require("fs/promises");
const path_1 = __importDefault(require("path"));
const index_1 = require("./index");
const helpers_1 = require("./lib/helpers");
const writeFileAsync = (0, util_1.promisify)(fs_1.writeFile);
const defaultOptions = {

@@ -19,3 +17,2 @@ port: 8080,

};
module.exports = cli(process.argv.slice(2));
async function cli(args) {

@@ -29,7 +26,7 @@ let options;

process.exitCode = 1;
return Promise.reject(err);
throw err;
}
if (!options) {
process.exitCode = 0;
return Promise.resolve(null);
if (options === null) {
showHelp();
return null;
}

@@ -45,3 +42,2 @@ return await startServer(options);

case '--help':
showHelp();
return null;

@@ -108,3 +104,3 @@ case '-a':

const filename = `${key.kid}.json`;
await writeFileAsync(filename, JSON.stringify(key, null, 2));
await (0, promises_1.writeFile)(filename, JSON.stringify(key, null, 2));
console.log(`JSON web key written to file "${filename}".`);

@@ -132,5 +128,10 @@ }

console.log(`OAuth 2 issuer is ${server.issuer.url}`);
process.once('SIGINT', async () => {
process.once('SIGINT', () => {
console.log('OAuth 2 server is stopping...');
await server.stop();
const handler = async () => {
await server.stop();
};
handler().catch((e) => {
throw e;
});
console.log('OAuth 2 server has been stopped.');

@@ -140,1 +141,2 @@ });

}
exports.default = cli(process.argv.slice(2));
{
"name": "oauth2-mock-server",
"version": "5.0.2",
"version": "6.0.0",
"description": "OAuth 2 mock server",

@@ -22,3 +22,3 @@ "keywords": [

"engines": {
"node": "^14.15 || ^16.13 || ^18",
"node": "^16.13 || ^18.12 || ^20",
"yarn": "^1.15.2"

@@ -43,18 +43,15 @@ },

"scripts": {
"build:clean": "rimraf ./dist",
"prebuild": "yarn build:clean",
"prebuild": "rimraf ./dist ./.cache",
"build": "tsc -p ./tsconfig.build.json",
"cleanup:testresults": "rimraf TestResults",
"prelint": "tsc --noEmit",
"lint": "eslint --cache --cache-location .cache/ --ext=.js,.ts src test --max-warnings 0",
"lint": "eslint --cache --cache-location .cache/ --ext=.ts src test --max-warnings 0",
"prepack": "yarn build --tsBuildInfoFile null --incremental false",
"pretest": "yarn cleanup:testresults && yarn lint",
"test": "yarn jest"
"pretest": "yarn lint",
"test": "yarn vitest --run --coverage"
},
"dependencies": {
"basic-auth": "^2.0.1",
"body-parser": "^1.20.1",
"cors": "^2.8.5",
"express": "^4.18.2",
"jose": "^4.12.0",
"jose": "^4.14.4",
"lodash.isplainobject": "^4.0.6",

@@ -67,27 +64,24 @@ "uuid": "^9.0.0"

"@types/express": "^4.17.17",
"@types/jest": "^29.4.0",
"@types/lodash.isplainobject": "^4.0.7",
"@types/node": "^14.18.36",
"@types/node": "^16.18.28",
"@types/supertest": "^2.0.12",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.52.0",
"eslint": "^8.34.0",
"eslint-config-prettier": "^8.6.0",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.7",
"@vitest/coverage-c8": "^0.31.1",
"eslint": "^8.41.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-jsdoc": "^40.0.0",
"eslint-plugin-jsdoc": "^45.0.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.4.3",
"jest-junit": "^14.0.0",
"prettier": "^2.8.4",
"rimraf": "^4.1.2",
"eslint-plugin-vitest": "^0.2.3",
"prettier": "^2.8.8",
"rimraf": "^5.0.1",
"supertest": "^6.3.3",
"ts-jest": "^29.0.5",
"ts-node": "^10.9.1",
"typescript": "^4.9.5"
"typescript": "^5.0.4",
"vitest": "^0.31.1"
},
"resolutions": {
"@types/node": "^14"
"@types/node": "^16"
}
}

@@ -16,3 +16,3 @@ # `oauth2-mock-server`

- [Node.js 14+](https://nodejs.org/)
- [Node.js 16+](https://nodejs.org/)
- [Yarn 1.15.2+](https://classic.yarnpkg.com/lang/en/)

@@ -19,0 +19,0 @@

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc