added jsonwebtoken as inbuilt library

This commit is contained in:
anusree-bruno 2025-04-18 17:09:11 +05:30
parent 9a21eec1b9
commit 740fc5a11c
6 changed files with 129 additions and 2 deletions

1
package-lock.json generated
View File

@ -27692,6 +27692,7 @@
"cheerio": "^1.0.0",
"crypto-js": "^4.1.1",
"json-query": "^2.2.2",
"jsonwebtoken": "^9.0.2",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"nanoid": "3.3.8",

View File

@ -28,6 +28,7 @@
"cheerio": "^1.0.0",
"crypto-js": "^4.1.1",
"json-query": "^2.2.2",
"jsonwebtoken": "^9.0.2",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"nanoid": "3.3.8",

View File

@ -30,6 +30,7 @@ const CryptoJS = require('crypto-js');
const NodeVault = require('node-vault');
const xml2js = require('xml2js');
const cheerio = require('cheerio');
const jsonwebtoken = require('jsonwebtoken');
const { executeQuickJsVmAsync } = require('../sandbox/quickjs');
class ScriptRuntime {
@ -150,6 +151,7 @@ class ScriptRuntime {
'node-fetch': fetch,
'crypto-js': CryptoJS,
'xml2js': xml2js,
jsonwebtoken,
cheerio,
...whitelistedModules,
fs: allowScriptFilesystemAccess ? fs : undefined,
@ -284,6 +286,7 @@ class ScriptRuntime {
'node-fetch': fetch,
'crypto-js': CryptoJS,
'xml2js': xml2js,
jsonwebtoken,
cheerio,
...whitelistedModules,
fs: allowScriptFilesystemAccess ? fs : undefined,

View File

@ -32,6 +32,7 @@ const CryptoJS = require('crypto-js');
const NodeVault = require('node-vault');
const xml2js = require('xml2js');
const cheerio = require('cheerio');
const jsonwebtoken = require('jsonwebtoken');
const { executeQuickJsVmAsync } = require('../sandbox/quickjs');
const getResultsSummary = (results) => {
@ -149,7 +150,8 @@ class TestRuntime {
res,
expect: chai.expect,
assert: chai.assert,
__brunoTestResults: __brunoTestResults
__brunoTestResults: __brunoTestResults,
jwt: jsonwebtoken
};
if (onConsoleLog && typeof onConsoleLog === 'function') {
@ -209,9 +211,16 @@ class TestRuntime {
'crypto-js': CryptoJS,
'xml2js': xml2js,
cheerio,
'jsonwebtoken': jsonwebtoken,
...whitelistedModules,
fs: allowScriptFilesystemAccess ? fs : undefined,
'node-vault': NodeVault
},
resolve: (moduleName, dirname) => {
console.log('Attempting to resolve module:', moduleName);
console.log('From directory:', dirname);
console.log('Available modules:', Object.keys(vm.require.mock));
return moduleName;
}
}
});

View File

@ -12,6 +12,7 @@ const bundleLibraries = async () => {
import btoa from "btoa";
import atob from "atob";
import * as CryptoJS from "@usebruno/crypto-js";
import jwt from "jsonwebtoken";
globalThis.expect = expect;
globalThis.assert = assert;
globalThis.moment = moment;
@ -19,6 +20,7 @@ const bundleLibraries = async () => {
globalThis.atob = atob;
globalThis.Buffer = Buffer;
globalThis.CryptoJS = CryptoJS;
globalThis.jwt = jwt;
globalThis.requireObject = {
...(globalThis.requireObject || {}),
'chai': { expect, assert },
@ -26,7 +28,8 @@ const bundleLibraries = async () => {
'buffer': { Buffer },
'btoa': btoa,
'atob': atob,
'crypto-js': CryptoJS
'crypto-js': CryptoJS,
'jsonwebtoken': jwt
};
`;

View File

@ -0,0 +1,110 @@
meta {
name: jwt
type: http
seq: 1
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:pre-request {
const jwt = require('jsonwebtoken');
// Create a payload
const payload = {
userId: "12345",
username: "testuser",
role: "admin",
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + (60 * 60) // expires in 1 hour
};
// Sign the token
const secret = "test-secret-key";
const token = jwt.sign(payload, secret);
// Store the token and payload for later verification
bru.setVar("jwt-token", token);
bru.setVar("jwt-payload", payload);
bru.setVar("jwt-secret", secret);
// Set the token in the Authorization header
req.setHeader("Authorization", `Bearer ${token}`);
}
script:post-response {
const jwt = require('jsonwebtoken');
const token = bru.getVar("jwt-token");
const secret = bru.getVar("jwt-secret");
// Decode the token
const decoded = jwt.decode(token);
bru.setVar("jwt-decoded", decoded);
// Verify the token
try {
const verified = jwt.verify(token, secret);
bru.setVar("jwt-verified", verified);
} catch (error) {
bru.setVar("jwt-verification-error", error.message);
}
}
tests {
const jwt = require('jsonwebtoken');
test("JWT token should be properly generated", function() {
const token = bru.getVar("jwt-token");
expect(token).to.be.a('string');
expect(token.split('.')).to.have.lengthOf(3); // JWT should have 3 parts
});
test("Decoded token should match original payload", function() {
const decoded = bru.getVar("jwt-decoded");
const payload = bru.getVar("jwt-payload");
expect(decoded.userId).to.equal(payload.userId);
expect(decoded.username).to.equal(payload.username);
expect(decoded.role).to.equal(payload.role);
});
test("Token should be successfully verified", function() {
const verified = bru.getVar("jwt-verified");
const payload = bru.getVar("jwt-payload");
expect(verified.userId).to.equal(payload.userId);
expect(verified.username).to.equal(payload.username);
expect(verified.role).to.equal(payload.role);
});
test("Token should have valid expiration", function() {
const decoded = bru.getVar("jwt-decoded");
const now = Math.floor(Date.now() / 1000);
expect(decoded.exp).to.be.a('number');
expect(decoded.exp).to.be.greaterThan(now);
});
test("Token should have valid issued at time", function() {
const decoded = bru.getVar("jwt-decoded");
const now = Math.floor(Date.now() / 1000);
expect(decoded.iat).to.be.a('number');
expect(decoded.iat).to.be.lessThanOrEqual(now);
});
test("Invalid token verification should fail", async function() {
const token = bru.getVar("jwt-token");
const invalidSecret = "wrong-secret-key";
try {
jwt.verify(token, invalidSecret);
expect.fail("Token verification should have failed with wrong secret");
} catch (error) {
expect(error.message).to.include("invalid signature");
}
});
}