-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11 from eBay/dev
Merging 3.0.0 into main
- Loading branch information
Showing
53 changed files
with
4,966 additions
and
5,622 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
export declare const constants: { | ||
readonly BASE64: "base64"; | ||
readonly COLON: ":"; | ||
readonly CONTENT_DIGEST_SHA256: "sha-256=:"; | ||
readonly CONTENT_DIGEST_SHA512: "sha-512=:"; | ||
readonly HEADERS: { | ||
readonly APPLICATION_JSON: "application/json"; | ||
readonly CONTENT_DIGEST: "content-digest"; | ||
readonly SIGNATURE_INPUT: "signature-input"; | ||
readonly SIGNATURE_KEY: "x-ebay-signature-key"; | ||
readonly SIGNATURE: "signature"; | ||
}; | ||
readonly HTTP_STATUS_CODE: { | ||
readonly NO_CONTENT: 204; | ||
readonly OK: 200; | ||
readonly BAD_REQUEST: 400; | ||
readonly INTERNAL_SERVER_ERROR: 500; | ||
}; | ||
readonly KEY_PATTERN_END: RegExp; | ||
readonly KEY_PATTERN_START: RegExp; | ||
readonly KEY_END: "\n-----END PUBLIC KEY-----"; | ||
readonly KEY_START: "-----BEGIN PUBLIC KEY-----\n"; | ||
readonly SHA_256: "sha256"; | ||
readonly SHA_512: "sha512"; | ||
readonly SIGNATURE_PREFIX: "sig1=:"; | ||
readonly UTF8: "utf8"; | ||
readonly X_EBAY_SIGNATURE: "x-ebay-signature"; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* * | ||
* * Copyright 2022 eBay Inc. | ||
* * | ||
* * Licensed under the Apache License, Version 2.0 (the "License"); | ||
* * you may not use this file except in compliance with the License. | ||
* * You may obtain a copy of the License at | ||
* * | ||
* * http://www.apache.org/licenses/LICENSE-2.0 | ||
* * | ||
* * Unless required by applicable law or agreed to in writing, software | ||
* * distributed under the License is distributed on an "AS IS" BASIS, | ||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* * See the License for the specific language governing permissions and | ||
* * limitations under the License. | ||
* * | ||
*/ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.constants = void 0; | ||
exports.constants = { | ||
BASE64: 'base64', | ||
COLON: ':', | ||
CONTENT_DIGEST_SHA256: 'sha-256=:', | ||
CONTENT_DIGEST_SHA512: 'sha-512=:', | ||
HEADERS: { | ||
APPLICATION_JSON: 'application/json', | ||
CONTENT_DIGEST: 'content-digest', | ||
SIGNATURE_INPUT: 'signature-input', | ||
SIGNATURE_KEY: 'x-ebay-signature-key', | ||
SIGNATURE: 'signature' | ||
}, | ||
HTTP_STATUS_CODE: { | ||
NO_CONTENT: 204, | ||
OK: 200, | ||
BAD_REQUEST: 400, | ||
INTERNAL_SERVER_ERROR: 500 | ||
}, | ||
KEY_PATTERN_END: /\n-----END PUBLIC KEY-----/, | ||
KEY_PATTERN_START: /-----BEGIN PUBLIC KEY-----\n/, | ||
KEY_END: '\n-----END PUBLIC KEY-----', | ||
KEY_START: '-----BEGIN PUBLIC KEY-----\n', | ||
SHA_256: 'sha256', | ||
SHA_512: 'sha512', | ||
SIGNATURE_PREFIX: 'sig1=:', | ||
UTF8: 'utf8', | ||
X_EBAY_SIGNATURE: 'x-ebay-signature' | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
declare function needsContentDigestValidation(requestBody: string): boolean; | ||
declare function readKey(value: string): string; | ||
export { needsContentDigestValidation, readKey }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* * | ||
* * Copyright 2022 eBay Inc. | ||
* * | ||
* * Licensed under the Apache License, Version 2.0 (the "License"); | ||
* * you may not use this file except in compliance with the License. | ||
* * You may obtain a copy of the License at | ||
* * | ||
* * http://www.apache.org/licenses/LICENSE-2.0 | ||
* * | ||
* * Unless required by applicable law or agreed to in writing, software | ||
* * distributed under the License is distributed on an "AS IS" BASIS, | ||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* * See the License for the specific language governing permissions and | ||
* * limitations under the License. | ||
* * | ||
*/ | ||
'use strict'; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.readKey = exports.needsContentDigestValidation = void 0; | ||
const fs = __importStar(require("fs")); | ||
const constants_1 = require("../constants"); | ||
function needsContentDigestValidation(requestBody) { | ||
return requestBody !== null && | ||
requestBody !== undefined && | ||
requestBody.length > 0; | ||
} | ||
exports.needsContentDigestValidation = needsContentDigestValidation; | ||
function readKey(value) { | ||
let key = value; | ||
if (fs.existsSync(value)) { | ||
key = fs.readFileSync(value, { | ||
encoding: constants_1.constants.UTF8 | ||
}); | ||
} | ||
return key; | ||
} | ||
exports.readKey = readKey; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/// <reference types="node" /> | ||
/** | ||
* Generates the 'Content-Digest' header value for the input payload. | ||
* | ||
* @param {Buffer} payload The request payload. | ||
* @param {string} cipher The algorithm used to calculate the digest. | ||
* @returns {string} contentDigest The 'Content-Digest' header value. | ||
*/ | ||
declare function generateDigestHeader(payload: Buffer, cipher: string): string; | ||
/** | ||
* Validates the 'Content-Digest' header value. | ||
* | ||
* @param {string} contentDigestHeader The Content-Digest header value. | ||
* @param {Buffer} body The HTTP request body. | ||
* @throws {Error} If the Content-Digest header value is invalid. | ||
*/ | ||
declare function validateDigestHeader(contentDigestHeader: string, body: Buffer): void; | ||
export { generateDigestHeader, validateDigestHeader }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* * | ||
* * Copyright 2022 eBay Inc. | ||
* * | ||
* * Licensed under the Apache License, Version 2.0 (the "License"); | ||
* * you may not use this file except in compliance with the License. | ||
* * You may obtain a copy of the License at | ||
* * | ||
* * http://www.apache.org/licenses/LICENSE-2.0 | ||
* * | ||
* * Unless required by applicable law or agreed to in writing, software | ||
* * distributed under the License is distributed on an "AS IS" BASIS, | ||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* * See the License for the specific language governing permissions and | ||
* * limitations under the License. | ||
* * | ||
*/ | ||
'use strict'; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validateDigestHeader = exports.generateDigestHeader = void 0; | ||
const crypto_1 = __importDefault(require("crypto")); | ||
const constants_1 = require("../constants"); | ||
/** | ||
* Generates the 'Content-Digest' header value for the input payload. | ||
* | ||
* @param {Buffer} payload The request payload. | ||
* @param {string} cipher The algorithm used to calculate the digest. | ||
* @returns {string} contentDigest The 'Content-Digest' header value. | ||
*/ | ||
function generateDigestHeader(payload, cipher) { | ||
let contentDigest = ''; | ||
// Validate the input payload | ||
if (!payload) { | ||
return contentDigest; | ||
} | ||
// Calculate the SHA-256 digest | ||
const hash = crypto_1.default.createHash(cipher) | ||
.update(payload) | ||
.digest(constants_1.constants.BASE64); | ||
const algo = cipher === constants_1.constants.SHA_512 ? constants_1.constants.CONTENT_DIGEST_SHA512 : | ||
constants_1.constants.CONTENT_DIGEST_SHA256; | ||
contentDigest = algo + hash + constants_1.constants.COLON; | ||
return contentDigest; | ||
} | ||
exports.generateDigestHeader = generateDigestHeader; | ||
; | ||
/** | ||
* Validates the 'Content-Digest' header value. | ||
* | ||
* @param {string} contentDigestHeader The Content-Digest header value. | ||
* @param {Buffer} body The HTTP request body. | ||
* @throws {Error} If the Content-Digest header value is invalid. | ||
*/ | ||
function validateDigestHeader(contentDigestHeader, body) { | ||
if (!contentDigestHeader) { | ||
throw new Error("Content-Digest header missing"); | ||
} | ||
// Validate | ||
const contentDigestPattern = new RegExp("(.+)=:(.+):"); | ||
const contentDigestParts = contentDigestPattern.exec(contentDigestHeader); | ||
if (!contentDigestParts || contentDigestParts.length == 0) { | ||
throw new Error("Content-digest header invalid"); | ||
} | ||
const cipher = contentDigestParts[1]; | ||
if (cipher !== "sha-256" && cipher !== "sha-512") { | ||
throw new Error("Invalid cipher " + cipher); | ||
} | ||
const algorithm = cipher === "sha-256" ? constants_1.constants.SHA_256 : constants_1.constants.SHA_512; | ||
const newDigest = generateDigestHeader(body, algorithm); | ||
if (newDigest !== contentDigestHeader) { | ||
throw new Error("Content-Digest value is invalid. Expected body digest is: " | ||
+ newDigest); | ||
} | ||
} | ||
exports.validateDigestHeader = validateDigestHeader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Config } from '..'; | ||
/** | ||
* Decrypts the input JWE string and returns the 'pkey' value from claims set. | ||
* | ||
* @param {string} jweString The JWE string. | ||
* @param {Config} config The input config. | ||
* @returns Promise<string> If the JWE decryption is successful, else returns Promise<undefined>. | ||
*/ | ||
export declare function decryptJWE(jweString: string, config: Config): Promise<string | undefined>; | ||
/** | ||
* Generates JWE string. | ||
* | ||
* @param {Config} config The input config. | ||
* @returns {Promise<string>} jwe The JWE as string. | ||
*/ | ||
export declare function encryptJWE(config: Config): Promise<string>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* * | ||
* * Copyright 2022 eBay Inc. | ||
* * | ||
* * Licensed under the Apache License, Version 2.0 (the "License"); | ||
* * you may not use this file except in compliance with the License. | ||
* * You may obtain a copy of the License at | ||
* * | ||
* * http://www.apache.org/licenses/LICENSE-2.0 | ||
* * | ||
* * Unless required by applicable law or agreed to in writing, software | ||
* * distributed under the License is distributed on an "AS IS" BASIS, | ||
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* * See the License for the specific language governing permissions and | ||
* * limitations under the License. | ||
* * | ||
*/ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.encryptJWE = exports.decryptJWE = void 0; | ||
const jose_1 = require("jose"); | ||
const constants_1 = require("../constants"); | ||
const common_1 = require("./common"); | ||
const signature_base_helper_1 = require("./signature-base-helper"); | ||
/** | ||
* Decrypts the input JWE string and returns the 'pkey' value from claims set. | ||
* | ||
* @param {string} jweString The JWE string. | ||
* @param {Config} config The input config. | ||
* @returns Promise<string> If the JWE decryption is successful, else returns Promise<undefined>. | ||
*/ | ||
async function decryptJWE(jweString, config) { | ||
const masterKey = (0, common_1.readKey)(config.masterKey); | ||
const masterKeyBuffer = Buffer.from(masterKey, constants_1.constants.BASE64); | ||
const jwtDecryptResult = await (0, jose_1.jwtDecrypt)(jweString, masterKeyBuffer); | ||
if (jwtDecryptResult['payload'] && jwtDecryptResult['payload']['pkey']) { | ||
const pKey = jwtDecryptResult['payload']['pkey']; | ||
return constants_1.constants.KEY_START + pKey + constants_1.constants.KEY_END; | ||
} | ||
} | ||
exports.decryptJWE = decryptJWE; | ||
/** | ||
* Generates JWE string. | ||
* | ||
* @param {Config} config The input config. | ||
* @returns {Promise<string>} jwe The JWE as string. | ||
*/ | ||
async function encryptJWE(config) { | ||
const masterKey = (0, common_1.readKey)(config.masterKey); | ||
let publicKey = (0, common_1.readKey)(config.publicKey); | ||
publicKey = formatPublicKey(publicKey); | ||
const unixTimestamp = (0, signature_base_helper_1.getUnixTimestamp)(); | ||
const masterKeyBuffer = Buffer.from(masterKey, constants_1.constants.BASE64); | ||
const jwe = await new jose_1.EncryptJWT(config.jwtPayload) | ||
.setProtectedHeader(config.jweHeaderParams) | ||
.setIssuedAt(unixTimestamp) | ||
.setNotBefore(unixTimestamp) | ||
.setExpirationTime(`${config.jwtExpiration}y`) | ||
.encrypt(masterKeyBuffer); | ||
return jwe; | ||
} | ||
exports.encryptJWE = encryptJWE; | ||
/** | ||
* Removes beginning and end markers from the input public key. | ||
* | ||
* @param {string} key The public key. | ||
* @throws {Error} if the key format is invalid. | ||
*/ | ||
function formatPublicKey(key) { | ||
try { | ||
const updatedKey = key.replace(constants_1.constants.KEY_PATTERN_START, ''); | ||
return updatedKey.replace(constants_1.constants.KEY_PATTERN_END, ''); | ||
} | ||
catch (exception) { | ||
throw new Error(`Invalid public key format`); | ||
} | ||
} |
Oops, something went wrong.