New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

jsontokens

Package Overview
Dependencies
Maintainers
2
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsontokens - npm Package Compare versions

Comparing version 3.0.0-alpha.0 to 3.0.0-alpha.1

lib/cryptoClients/sha256.d.ts

3

CHANGELOG.md

@@ -9,4 +9,3 @@ # Changelog

### Changed
- Web Crypto API used for hashing, if available. Otherwise uses the Node.js `crypto` module.
- Several functions are now async promises.
- Added async functions that use Web Crypto API used for hashing, if available. Otherwise uses the Node.js `crypto` module.

@@ -13,0 +12,0 @@ ## [2.0.3]

/// <reference types="node" />
import { ec as EC, BNInput } from 'elliptic';
import KeyEncoder from 'key-encoder';
export declare class SECP256K1Client {
static ec: EC;
static algorithmName: string;
static keyEncoder: KeyEncoder;
constructor();
private static getHashFunction;
static createHash(signingInput: string | Buffer): Promise<Buffer>;
static loadPrivateKey(rawPrivateKey: string): EC.KeyPair;
static loadPublicKey(rawPublicKey: string | Buffer): EC.KeyPair;
static encodePublicKey(publicKey: string | Buffer, originalFormat: 'raw' | 'pem' | 'der', destinationFormat: 'raw' | 'pem' | 'der'): string;
static derivePublicKey(privateKey: string, compressed?: boolean): string;

@@ -15,0 +10,0 @@ static signHash(signingInputHash: string | Buffer, rawPrivateKey: string, format?: string): string;

"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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const elliptic_1 = require("elliptic");
const key_encoder_1 = require("key-encoder");
const ecdsa_sig_formatter_1 = require("ecdsa-sig-formatter");

@@ -19,36 +9,2 @@ const errors_1 = require("../errors");

}
static getHashFunction() {
try {
const isSubtleCryptoAvailable = typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined';
if (isSubtleCryptoAvailable) {
// Use the W3C Web Crypto API if available (running in a web browser).
return (input) => __awaiter(this, void 0, void 0, function* () {
const buffer = typeof input === 'string' ? Buffer.from(input) : input;
const hash = yield crypto.subtle.digest('SHA-256', buffer);
return Buffer.from(hash);
});
}
else {
// Otherwise try loading the Node.js `crypto` module (running in Node.js, or an older browser with a polyfill).
const nodeCrypto = require('crypto');
if (!nodeCrypto.createHash) {
const error = new Error('`crypto` module does not contain `createHash`');
console.error(error);
throw error;
}
return input => Promise.resolve(nodeCrypto.createHash('sha256').update(input).digest());
}
}
catch (error) {
console.error(error);
const missingCryptoError = new Error('Crypto lib not found. Neither the global `crypto.subtle` Web Crypto API, ' +
'nor the or the Node.js `require("crypto").createHash` module is available.');
console.error(missingCryptoError);
throw missingCryptoError;
}
}
static createHash(signingInput) {
const hashFunction = this.getHashFunction();
return hashFunction(signingInput);
}
static loadPrivateKey(rawPrivateKey) {

@@ -63,5 +19,2 @@ if (rawPrivateKey.length === 66) {

}
static encodePublicKey(publicKey, originalFormat, destinationFormat) {
return SECP256K1Client.keyEncoder.encodePublic(publicKey, originalFormat, destinationFormat);
}
static derivePublicKey(privateKey, compressed = true) {

@@ -125,8 +78,2 @@ if (typeof privateKey !== 'string') {

SECP256K1Client.algorithmName = 'ES256K';
SECP256K1Client.keyEncoder = new key_encoder_1.default({
curveParameters: [1, 3, 132, 0, 10],
privatePEMOptions: { label: 'EC PRIVATE KEY' },
publicPEMOptions: { label: 'PUBLIC KEY' },
curve: SECP256K1Client.ec
});
//# sourceMappingURL=secp256k1.js.map
export interface TokenInterface {
header: {
[key: string]: any;
[key: string]: Json;
alg?: string;

@@ -8,3 +8,3 @@ typ?: string;

payload: {
[key: string]: any;
[key: string]: Json;
iss?: string;

@@ -17,2 +17,5 @@ jti?: string;

}
export declare type Json = string | number | boolean | null | {
[property: string]: Json;
} | Json[];
export declare function decodeToken(token: string | TokenInterface): TokenInterface;

@@ -1,5 +0,5 @@

export { TokenSigner, createUnsecuredToken } from './signer';
export { TokenVerifier } from './verifier';
export { decodeToken } from './decode';
export { MissingParametersError, InvalidTokenError } from './errors';
export { SECP256K1Client, cryptoClients } from './cryptoClients';
export * from './signer';
export * from './verifier';
export * from './decode';
export * from './errors';
export * from './cryptoClients';
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
var signer_1 = require("./signer");
exports.TokenSigner = signer_1.TokenSigner;
exports.createUnsecuredToken = signer_1.createUnsecuredToken;
var verifier_1 = require("./verifier");
exports.TokenVerifier = verifier_1.TokenVerifier;
var decode_1 = require("./decode");
exports.decodeToken = decode_1.decodeToken;
var errors_1 = require("./errors");
exports.MissingParametersError = errors_1.MissingParametersError;
exports.InvalidTokenError = errors_1.InvalidTokenError;
var cryptoClients_1 = require("./cryptoClients");
exports.SECP256K1Client = cryptoClients_1.SECP256K1Client;
exports.cryptoClients = cryptoClients_1.cryptoClients;
__export(require("./signer"));
__export(require("./verifier"));
__export(require("./decode"));
__export(require("./errors"));
__export(require("./cryptoClients"));
//# sourceMappingURL=index.js.map

@@ -0,3 +1,5 @@

/// <reference types="node" />
import { SECP256K1Client } from './cryptoClients';
export declare function createUnsecuredToken(payload: any): string;
import { Json } from './decode';
export declare function createUnsecuredToken(payload: Json): string;
export interface SignedToken {

@@ -17,6 +19,10 @@ header: string[];

};
sign(payload: any): Promise<string>;
sign(payload: any, expanded: undefined): Promise<string>;
sign(payload: any, expanded: false, customHeader?: any): Promise<string>;
sign(payload: any, expanded: true, customHeader?: any): Promise<SignedToken>;
sign(payload: Json, expanded: true, customHeader?: Json): SignedToken;
sign(payload: Json, expanded: false, customHeader?: Json): string;
signAsync(payload: Json, expanded: true, customHeader?: Json): Promise<SignedToken>;
signAsync(payload: Json, expanded: false, customHeader?: Json): Promise<string>;
createWithSignedHash(payload: Json, expanded: boolean, header: {
typ: string;
alg: string;
}, signingInput: string, signingInputHash: Buffer): SignedToken | string;
}

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

const errors_1 = require("./errors");
const sha256_1 = require("./cryptoClients/sha256");
function createSigningInput(payload, header) {

@@ -55,3 +56,11 @@ const tokenParts = [];

}
sign(payload, expanded = false, customHeader = {}) {
sign(payload, expanded, customHeader = {}) {
// generate the token header
const header = this.header(customHeader);
// prepare the message to be signed
const signingInput = createSigningInput(payload, header);
const signingInputHash = sha256_1.hashSha256(signingInput);
return this.createWithSignedHash(payload, expanded, header, signingInput, signingInputHash);
}
signAsync(payload, expanded = false, customHeader = {}) {
return __awaiter(this, void 0, void 0, function* () {

@@ -62,23 +71,27 @@ // generate the token header

const signingInput = createSigningInput(payload, header);
const signingInputHash = yield this.cryptoClient.createHash(signingInput);
// sign the message and add in the signature
const signature = this.cryptoClient.signHash(signingInputHash, this.rawPrivateKey);
if (expanded) {
return {
'header': [
base64url_1.default.encode(JSON.stringify(header))
],
'payload': JSON.stringify(payload),
'signature': [
signature
]
};
}
else {
return [signingInput, signature].join('.');
}
const signingInputHash = yield sha256_1.hashSha256Async(signingInput);
return this.createWithSignedHash(payload, expanded, header, signingInput, signingInputHash);
});
}
createWithSignedHash(payload, expanded, header, signingInput, signingInputHash) {
// sign the message and add in the signature
const signature = this.cryptoClient.signHash(signingInputHash, this.rawPrivateKey);
if (expanded) {
const signedToken = {
'header': [
base64url_1.default.encode(JSON.stringify(header))
],
'payload': JSON.stringify(payload),
'signature': [
signature
]
};
return signedToken;
}
else {
return [signingInput, signature].join('.');
}
}
}
exports.TokenSigner = TokenSigner;
//# sourceMappingURL=signer.js.map

@@ -8,5 +8,8 @@ import { SECP256K1Client } from './cryptoClients';

constructor(signingAlgorithm: string, rawPublicKey: string);
verify(token: string | SignedToken): Promise<boolean>;
verifyCompact(token: string): Promise<boolean>;
verifyExpanded(token: SignedToken): Promise<boolean>;
verify(token: string | SignedToken): boolean;
verifyAsync(token: string | SignedToken): Promise<boolean>;
verifyCompact(token: string, async: false): boolean;
verifyCompact(token: string, async: true): Promise<boolean>;
verifyExpanded(token: SignedToken, async: false): boolean;
verifyExpanded(token: SignedToken, async: true): Promise<boolean>;
}
"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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -15,2 +6,3 @@ const base64url_1 = require("base64url");

const errors_1 = require("./errors");
const sha256_1 = require("./cryptoClients/sha256");
class TokenVerifier {

@@ -34,18 +26,28 @@ constructor(signingAlgorithm, rawPublicKey) {

if (typeof token === 'string') {
return this.verifyCompact(token);
return this.verifyCompact(token, false);
}
else if (typeof token === 'object') {
return this.verifyExpanded(token);
return this.verifyExpanded(token, false);
}
else {
false;
}
}
verifyAsync(token) {
if (typeof token === 'string') {
return this.verifyCompact(token, true);
}
else if (typeof token === 'object') {
return this.verifyExpanded(token, true);
}
else {
return Promise.resolve(false);
}
}
verifyCompact(token) {
return __awaiter(this, void 0, void 0, function* () {
// decompose the token into parts
const tokenParts = token.split('.');
// calculate the signing input hash
const signingInput = tokenParts[0] + '.' + tokenParts[1];
const signingInputHash = yield this.cryptoClient.createHash(signingInput);
verifyCompact(token, async) {
// decompose the token into parts
const tokenParts = token.split('.');
// calculate the signing input hash
const signingInput = tokenParts[0] + '.' + tokenParts[1];
const performVerify = (signingInputHash) => {
// extract the signature as a DER array

@@ -55,12 +57,18 @@ const derSignatureBuffer = this.cryptoClient.loadSignature(tokenParts[2]);

return this.cryptoClient.verifyHash(signingInputHash, derSignatureBuffer, this.rawPublicKey);
});
};
if (async) {
return sha256_1.hashSha256Async(signingInput).then(signingInputHash => performVerify(signingInputHash));
}
else {
const signingInputHash = sha256_1.hashSha256(signingInput);
return performVerify(signingInputHash);
}
}
verifyExpanded(token) {
return __awaiter(this, void 0, void 0, function* () {
const signingInput = [
token['header'].join('.'),
base64url_1.default.encode(token['payload'])
].join('.');
const signingInputHash = yield this.cryptoClient.createHash(signingInput);
let verified = true;
verifyExpanded(token, async) {
const signingInput = [
token['header'].join('.'),
base64url_1.default.encode(token['payload'])
].join('.');
let verified = true;
const performVerify = (signingInputHash) => {
token['signature'].map((signature) => {

@@ -74,3 +82,10 @@ const derSignatureBuffer = this.cryptoClient.loadSignature(signature);

return verified;
});
};
if (async) {
return sha256_1.hashSha256Async(signingInput).then(signingInputHash => performVerify(signingInputHash));
}
else {
const signingInputHash = sha256_1.hashSha256(signingInput);
return performVerify(signingInputHash);
}
}

@@ -77,0 +92,0 @@ }

{
"name": "jsontokens",
"version": "3.0.0-alpha.0",
"version": "3.0.0-alpha.1",
"description": "node.js library for encoding, decoding, and verifying JSON Web Tokens (JWTs)",
"main": "lib/index.js",
"scripts": {
"build": "tsc -p tsconfig.build.json",
"build": "tsc -b tsconfig.build.json",
"lint": "eslint --ext .ts ./src",

@@ -42,14 +42,15 @@ "test": "npm run lint && jest",

"@peculiar/webcrypto": "^1.0.21",
"@types/jest": "^24.0.19",
"@types/node": "^12.7.12",
"@typescript-eslint/eslint-plugin": "^2.4.0",
"@typescript-eslint/parser": "^2.4.0",
"@types/jest": "^24.0.23",
"@types/node": "^12.12.7",
"@types/sha.js": "^2.4.0",
"@typescript-eslint/eslint-plugin": "^2.7.0",
"@typescript-eslint/parser": "^2.7.0",
"codecov": "^3.6.1",
"eslint": "^6.5.1",
"eslint-plugin-jest": "^22.19.0",
"eslint": "^6.6.0",
"eslint-plugin-jest": "^23.0.3",
"jest": "^24.9.0",
"source-map-support": "^0.5.13",
"source-map-support": "^0.5.16",
"ts-jest": "^24.1.0",
"ts-node": "^8.4.1",
"typescript": "^3.6.4"
"ts-node": "^8.5.0",
"typescript": "^3.7.2"
},

@@ -62,3 +63,3 @@ "dependencies": {

"elliptic": "^6.4.1",
"key-encoder": "^2.0.3"
"sha.js": "^2.4.11"
},

@@ -65,0 +66,0 @@ "files": [

import { ec as EC, BNInput } from 'elliptic'
import KeyEncoder from 'key-encoder'
import { derToJose, joseToDer } from 'ecdsa-sig-formatter'

@@ -10,8 +9,2 @@ import { MissingParametersError } from '../errors'

static algorithmName = 'ES256K'
static keyEncoder = new KeyEncoder({
curveParameters: [1, 3, 132, 0, 10],
privatePEMOptions: { label: 'EC PRIVATE KEY' },
publicPEMOptions: { label: 'PUBLIC KEY' },
curve: SECP256K1Client.ec
})

@@ -21,37 +14,2 @@ constructor() {

private static getHashFunction(): (signingInput: string | Buffer) => Promise<Buffer> {
try {
const isSubtleCryptoAvailable = typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined'
if (isSubtleCryptoAvailable) {
// Use the W3C Web Crypto API if available (running in a web browser).
return async input => {
const buffer = typeof input === 'string' ? Buffer.from(input) : input
const hash = await crypto.subtle.digest('SHA-256', buffer)
return Buffer.from(hash)
}
} else {
// Otherwise try loading the Node.js `crypto` module (running in Node.js, or an older browser with a polyfill).
const nodeCrypto = require('crypto') as typeof import('crypto')
if (!nodeCrypto.createHash) {
const error = new Error('`crypto` module does not contain `createHash`')
console.error(error)
throw error
}
return input => Promise.resolve(nodeCrypto.createHash('sha256').update(input).digest())
}
} catch (error) {
console.error(error)
const missingCryptoError = new Error(
'Crypto lib not found. Neither the global `crypto.subtle` Web Crypto API, ' +
'nor the or the Node.js `require("crypto").createHash` module is available.')
console.error(missingCryptoError)
throw missingCryptoError
}
}
static createHash(signingInput: string | Buffer): Promise<Buffer> {
const hashFunction = this.getHashFunction()
return hashFunction(signingInput)
}
static loadPrivateKey(rawPrivateKey: string) {

@@ -68,7 +26,2 @@ if (rawPrivateKey.length === 66) {

static encodePublicKey(publicKey: string | Buffer, originalFormat: 'raw' | 'pem' | 'der', destinationFormat: 'raw' | 'pem' | 'der') {
return SECP256K1Client.keyEncoder.encodePublic(
publicKey, originalFormat, destinationFormat)
}
static derivePublicKey(privateKey: string, compressed = true) {

@@ -75,0 +28,0 @@ if (typeof privateKey !== 'string') {

@@ -5,3 +5,3 @@ import base64url from 'base64url'

header: {
[key: string]: any;
[key: string]: Json;
alg?: string;

@@ -11,3 +11,3 @@ typ?: string;

payload: {
[key: string]: any;
[key: string]: Json;
iss?: string;

@@ -21,2 +21,10 @@ jti?: string;

export type Json =
| string
| number
| boolean
| null
| { [property: string]: Json }
| Json[];
export function decodeToken(token: string | TokenInterface): TokenInterface {

@@ -45,4 +53,4 @@ if (typeof token === 'string') {

const allHeaders: any[] = []
token.header.map((headerValue: string) => {
const allHeaders: any = [];
(token.header as any).map((headerValue: string) => {
const header = JSON.parse(base64url.decode(headerValue))

@@ -49,0 +57,0 @@ allHeaders.push(header)

@@ -1,5 +0,5 @@

export { TokenSigner, createUnsecuredToken } from './signer'
export { TokenVerifier } from './verifier'
export { decodeToken } from './decode'
export { MissingParametersError, InvalidTokenError } from './errors'
export { SECP256K1Client, cryptoClients } from './cryptoClients'
export * from './signer'
export * from './verifier'
export * from './decode'
export * from './errors'
export * from './cryptoClients'
import base64url from 'base64url'
import { cryptoClients, SECP256K1Client } from './cryptoClients'
import { MissingParametersError } from './errors'
import { Json } from './decode'
import { hashSha256, hashSha256Async } from './cryptoClients/sha256'
function createSigningInput(payload: any, header: any) {
function createSigningInput(payload: Json, header: Json) {
const tokenParts = []

@@ -23,3 +25,3 @@

export function createUnsecuredToken(payload: any) {
export function createUnsecuredToken(payload: Json) {
const header = {typ: 'JWT', alg: 'none'}

@@ -62,8 +64,18 @@ return createSigningInput(payload, header) + '.'

}
sign(payload: Json, expanded: true, customHeader?: Json): SignedToken;
sign(payload: Json, expanded: false, customHeader?: Json): string;
sign(payload: Json, expanded: boolean, customHeader: Json = {}): SignedToken | string {
// generate the token header
const header = this.header(customHeader)
sign(payload: any): Promise<string>;
sign(payload: any, expanded: undefined): Promise<string>;
sign(payload: any, expanded: false, customHeader?: any): Promise<string>;
sign(payload: any, expanded: true, customHeader?: any): Promise<SignedToken>;
async sign(payload: any, expanded: boolean = false, customHeader: any = {}): Promise<string | SignedToken> {
// prepare the message to be signed
const signingInput = createSigningInput(payload, header)
const signingInputHash = hashSha256(signingInput)
return this.createWithSignedHash(payload, expanded, header, signingInput, signingInputHash)
}
signAsync(payload: Json, expanded: true, customHeader?: Json): Promise<SignedToken>;
signAsync(payload: Json, expanded: false, customHeader?: Json): Promise<string>;
async signAsync(payload: Json, expanded: boolean = false, customHeader: Json = {}) {
// generate the token header

@@ -74,4 +86,14 @@ const header = this.header(customHeader)

const signingInput = createSigningInput(payload, header)
const signingInputHash = await this.cryptoClient.createHash(signingInput)
const signingInputHash = await hashSha256Async(signingInput)
return this.createWithSignedHash(payload, expanded, header, signingInput, signingInputHash)
}
createWithSignedHash(
payload: Json,
expanded: boolean,
header: { typ: string; alg: string },
signingInput: string,
signingInputHash: Buffer
):
SignedToken | string {
// sign the message and add in the signature

@@ -82,3 +104,3 @@ const signature = this.cryptoClient.signHash(

if (expanded) {
return {
const signedToken: SignedToken = {
'header': [

@@ -92,2 +114,3 @@ base64url.encode(JSON.stringify(header))

}
return signedToken
} else {

@@ -94,0 +117,0 @@ return [signingInput, signature].join('.')

import { SECP256K1Client as secp256k1 } from '../index'
import { hashSha256Async } from '../cryptoClients/sha256'
import * as webcrypto from '@peculiar/webcrypto'
describe('SECP256k1 tests - node.js crypto', () => {
describe('SECP256k1 tests', () => {
runSECP256k1Tests()
})
describe('SECP256k1 tests - web crypto', () => {
beforeAll(() => {
Object.defineProperty(global, 'crypto', { value: new webcrypto.Crypto() })
})
afterAll(() => {
delete (global as any)['crypto']
})
runSECP256k1Tests()
})
function runSECP256k1Tests() {

@@ -55,3 +44,3 @@ const privateKey = '278a5de700e29faae8e40e366ec5012b5ec63d36ec77e8a2417154cc1d25383f'

const hash = await secp256k1.createHash(message)
const hash = await hashSha256Async(message)
const signature = secp256k1.signHash(hash, privateKey, 'der')

@@ -58,0 +47,0 @@

@@ -10,8 +10,38 @@ import base64url from 'base64url'

describe('main tests - node.js crypto', () => {
let origGlobalCrypto: { defined: boolean, value: any }
beforeAll(() => {
origGlobalCrypto = {
defined: 'crypto' in global,
value: (global as any)['crypto']
}
delete (global as any)['crypto'];
(global as any)['crypto'] = new webcrypto.Crypto()
})
afterAll(() => {
if (origGlobalCrypto.defined) {
(global as any)['crypto'] = origGlobalCrypto.value
} else {
delete (global as any)['crypto']
}
})
runMainTests()
})
describe('main tests - sha.js crypto', () => {
let origCreateHash: typeof import('crypto').createHash
beforeAll(() => {
const nodeCrypto = require('crypto') as typeof import('crypto')
origCreateHash = nodeCrypto.createHash
delete nodeCrypto.createHash
})
afterAll(() => {
const nodeCrypto = require('crypto') as typeof import('crypto')
nodeCrypto.createHash = origCreateHash
})
runMainTests()
})
describe('main tests - web crypto', () => {
beforeAll(() => {
Object.defineProperty(global, 'crypto', { value: new webcrypto.Crypto() })
(global as any)['crypto'] = new webcrypto.Crypto()
})

@@ -45,3 +75,5 @@ afterAll(() => {

const token = await tokenSigner.sign(sampleDecodedToken.payload)
const token = await tokenSigner.signAsync(sampleDecodedToken.payload, false)
const token1 = tokenSigner.sign(sampleDecodedToken.payload, false)
expect(token).toStrictEqual(token1)
expect(token).toBeTruthy()

@@ -62,3 +94,5 @@ expect(typeof token).toBe('string')

const token = await tokenSigner.sign(sampleDecodedToken.payload, undefined, { test: 'TestHeader' })
const token = await tokenSigner.signAsync(sampleDecodedToken.payload, false, { test: 'TestHeader' })
const token1 = tokenSigner.sign(sampleDecodedToken.payload, false, { test: 'TestHeader' })
expect(token).toStrictEqual(token1)
expect(token).toBeTruthy()

@@ -92,9 +126,16 @@ expect(typeof token).toBe('string')

const verified = await tokenVerifier.verify(sampleToken)
const verified = await tokenVerifier.verifyAsync(sampleToken)
const verified1 = await tokenVerifier.verify(sampleToken)
expect(verified).toStrictEqual(verified1)
expect(verified).toBe(true)
const tokenSigner = new TokenSigner('ES256K', rawPrivateKey)
const newToken = await tokenSigner.sign(sampleDecodedToken.payload)
const newToken = await tokenSigner.signAsync(sampleDecodedToken.payload, false)
const newToken1 = tokenSigner.sign(sampleDecodedToken.payload, false)
expect(newToken).toStrictEqual(newToken1)
expect(newToken).toBeTruthy()
const newTokenVerified = await tokenVerifier.verify(newToken)
const newTokenVerified = await tokenVerifier.verifyAsync(newToken)
const newTokenVerified1 = tokenVerifier.verify(newToken)
expect(newTokenVerified).toStrictEqual(newTokenVerified1)
expect(newTokenVerified).toBe(true)

@@ -113,12 +154,18 @@ })

const token = await tokenSigner.sign(sampleDecodedToken.payload, true)
const token = await tokenSigner.signAsync(sampleDecodedToken.payload, true)
const token1 = tokenSigner.sign(sampleDecodedToken.payload, true)
expect(token).toStrictEqual(token1)
expect(token).toBeTruthy()
expect(typeof token).toBe('object')
const verified = await tokenVerifier.verify(token)
const verified = await tokenVerifier.verifyAsync(token)
const verified1 = tokenVerifier.verify(token)
expect(verified).toStrictEqual(verified1)
expect(verified).toBe(true)
const signedToken = await tokenSigner.sign(sampleDecodedToken.payload, true)
const signedToken = await tokenSigner.signAsync(sampleDecodedToken.payload, true)
const signedToken1 = tokenSigner.sign(sampleDecodedToken.payload, true)
expect(signedToken).toStrictEqual(signedToken1)
expect(signedToken).toBeTruthy()
})
}

@@ -5,2 +5,3 @@ import base64url from 'base64url'

import { SignedToken } from './signer'
import { hashSha256Async, hashSha256 } from './cryptoClients/sha256'

@@ -30,8 +31,18 @@ export class TokenVerifier {

verify(token: string | SignedToken): Promise<boolean> {
verify(token: string | SignedToken): boolean {
if (typeof token === 'string') {
return this.verifyCompact(token)
return this.verifyCompact(token, false)
} else if (typeof token === 'object') {
return this.verifyExpanded(token)
return this.verifyExpanded(token, false)
} else {
false
}
}
verifyAsync(token: string | SignedToken): Promise<boolean> {
if (typeof token === 'string') {
return this.verifyCompact(token, true)
} else if (typeof token === 'object') {
return this.verifyExpanded(token, true)
} else {
return Promise.resolve(false)

@@ -41,3 +52,5 @@ }

async verifyCompact(token: string): Promise<boolean> {
verifyCompact(token: string, async: false): boolean
verifyCompact(token: string, async: true): Promise<boolean>
verifyCompact(token: string, async: boolean): boolean | Promise<boolean> {
// decompose the token into parts

@@ -48,13 +61,24 @@ const tokenParts = token.split('.')

const signingInput = tokenParts[0] + '.' + tokenParts[1]
const signingInputHash = await this.cryptoClient.createHash(signingInput)
// extract the signature as a DER array
const derSignatureBuffer = this.cryptoClient.loadSignature(tokenParts[2])
const performVerify = (signingInputHash: Buffer) => {
// extract the signature as a DER array
const derSignatureBuffer = this.cryptoClient.loadSignature(tokenParts[2])
// verify the signed hash
return this.cryptoClient.verifyHash(
signingInputHash, derSignatureBuffer, this.rawPublicKey)
// verify the signed hash
return this.cryptoClient.verifyHash(
signingInputHash, derSignatureBuffer, this.rawPublicKey)
}
if (async) {
return hashSha256Async(signingInput).then(signingInputHash =>
performVerify(signingInputHash))
} else {
const signingInputHash = hashSha256(signingInput)
return performVerify(signingInputHash)
}
}
async verifyExpanded(token: SignedToken): Promise<boolean> {
verifyExpanded(token: SignedToken, async: false): boolean;
verifyExpanded(token: SignedToken, async: true): Promise<boolean>;
verifyExpanded(token: SignedToken, async: boolean): boolean | Promise<boolean> {
const signingInput = [

@@ -64,17 +88,24 @@ token['header'].join('.'),

].join('.')
const signingInputHash = await this.cryptoClient.createHash(signingInput)
let verified = true
token['signature'].map((signature: string) => {
const derSignatureBuffer = this.cryptoClient.loadSignature(signature)
const signatureVerified = this.cryptoClient.verifyHash(
signingInputHash, derSignatureBuffer, this.rawPublicKey)
if (!signatureVerified) {
verified = false
}
})
const performVerify = (signingInputHash: Buffer) => {
token['signature'].map((signature: string) => {
const derSignatureBuffer = this.cryptoClient.loadSignature(signature)
const signatureVerified = this.cryptoClient.verifyHash(
signingInputHash, derSignatureBuffer, this.rawPublicKey)
if (!signatureVerified) {
verified = false
}
})
return verified
}
return verified
if (async) {
return hashSha256Async(signingInput).then(signingInputHash =>
performVerify(signingInputHash))
} else {
const signingInputHash = hashSha256(signingInput)
return performVerify(signingInputHash)
}
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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