Sindbad~EG File Manager
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createWebhooks = void 0;
const Error_js_1 = require("./Error.js");
const CryptoProvider_js_1 = require("./crypto/CryptoProvider.js");
function createWebhooks(platformFunctions) {
const Webhook = {
DEFAULT_TOLERANCE: 300,
// @ts-ignore
signature: null,
constructEvent(payload, header, secret, tolerance, cryptoProvider, receivedAt) {
try {
this.signature.verifyHeader(payload, header, secret, tolerance || Webhook.DEFAULT_TOLERANCE, cryptoProvider, receivedAt);
}
catch (e) {
if (e instanceof CryptoProvider_js_1.CryptoProviderOnlySupportsAsyncError) {
e.message +=
'\nUse `await constructEventAsync(...)` instead of `constructEvent(...)`';
}
throw e;
}
const jsonPayload = payload instanceof Uint8Array
? JSON.parse(new TextDecoder('utf8').decode(payload))
: JSON.parse(payload);
return jsonPayload;
},
async constructEventAsync(payload, header, secret, tolerance, cryptoProvider, receivedAt) {
await this.signature.verifyHeaderAsync(payload, header, secret, tolerance || Webhook.DEFAULT_TOLERANCE, cryptoProvider, receivedAt);
const jsonPayload = payload instanceof Uint8Array
? JSON.parse(new TextDecoder('utf8').decode(payload))
: JSON.parse(payload);
return jsonPayload;
},
/**
* Generates a header to be used for webhook mocking
*
* @typedef {object} opts
* @property {number} timestamp - Timestamp of the header. Defaults to Date.now()
* @property {string} payload - JSON stringified payload object, containing the 'id' and 'object' parameters
* @property {string} secret - Stripe webhook secret 'whsec_...'
* @property {string} scheme - Version of API to hit. Defaults to 'v1'.
* @property {string} signature - Computed webhook signature
* @property {CryptoProvider} cryptoProvider - Crypto provider to use for computing the signature if none was provided. Defaults to NodeCryptoProvider.
*/
generateTestHeaderString: function (opts) {
if (!opts) {
throw new Error_js_1.StripeError({
message: 'Options are required',
});
}
opts.timestamp =
Math.floor(opts.timestamp) || Math.floor(Date.now() / 1000);
opts.scheme = opts.scheme || signature.EXPECTED_SCHEME;
opts.cryptoProvider = opts.cryptoProvider || getCryptoProvider();
opts.signature =
opts.signature ||
opts.cryptoProvider.computeHMACSignature(opts.timestamp + '.' + opts.payload, opts.secret);
const generatedHeader = [
't=' + opts.timestamp,
opts.scheme + '=' + opts.signature,
].join(',');
return generatedHeader;
},
};
const signature = {
EXPECTED_SCHEME: 'v1',
verifyHeader(encodedPayload, encodedHeader, secret, tolerance, cryptoProvider, receivedAt) {
const { decodedHeader: header, decodedPayload: payload, details, suspectPayloadType, } = parseEventDetails(encodedPayload, encodedHeader, this.EXPECTED_SCHEME);
const secretContainsWhitespace = /\s/.test(secret);
cryptoProvider = cryptoProvider || getCryptoProvider();
const expectedSignature = cryptoProvider.computeHMACSignature(makeHMACContent(payload, details), secret);
validateComputedSignature(payload, header, details, expectedSignature, tolerance, suspectPayloadType, secretContainsWhitespace, receivedAt);
return true;
},
async verifyHeaderAsync(encodedPayload, encodedHeader, secret, tolerance, cryptoProvider, receivedAt) {
const { decodedHeader: header, decodedPayload: payload, details, suspectPayloadType, } = parseEventDetails(encodedPayload, encodedHeader, this.EXPECTED_SCHEME);
const secretContainsWhitespace = /\s/.test(secret);
cryptoProvider = cryptoProvider || getCryptoProvider();
const expectedSignature = await cryptoProvider.computeHMACSignatureAsync(makeHMACContent(payload, details), secret);
return validateComputedSignature(payload, header, details, expectedSignature, tolerance, suspectPayloadType, secretContainsWhitespace, receivedAt);
},
};
function makeHMACContent(payload, details) {
return `${details.timestamp}.${payload}`;
}
function parseEventDetails(encodedPayload, encodedHeader, expectedScheme) {
if (!encodedPayload) {
throw new Error_js_1.StripeSignatureVerificationError(encodedHeader, encodedPayload, {
message: 'No webhook payload was provided.',
});
}
const suspectPayloadType = typeof encodedPayload != 'string' &&
!(encodedPayload instanceof Uint8Array);
const textDecoder = new TextDecoder('utf8');
const decodedPayload = encodedPayload instanceof Uint8Array
? textDecoder.decode(encodedPayload)
: encodedPayload;
// Express's type for `Request#headers` is `string | []string`
// which is because the `set-cookie` header is an array,
// but no other headers are an array (docs: https://nodejs.org/api/http.html#http_message_headers)
// (Express's Request class is an extension of http.IncomingMessage, and doesn't appear to be relevantly modified: https://github.com/expressjs/express/blob/master/lib/request.js#L31)
if (Array.isArray(encodedHeader)) {
throw new Error('Unexpected: An array was passed as a header, which should not be possible for the stripe-signature header.');
}
if (encodedHeader == null || encodedHeader == '') {
throw new Error_js_1.StripeSignatureVerificationError(encodedHeader, encodedPayload, {
message: 'No stripe-signature header value was provided.',
});
}
const decodedHeader = encodedHeader instanceof Uint8Array
? textDecoder.decode(encodedHeader)
: encodedHeader;
const details = parseHeader(decodedHeader, expectedScheme);
if (!details || details.timestamp === -1) {
throw new Error_js_1.StripeSignatureVerificationError(decodedHeader, decodedPayload, {
message: 'Unable to extract timestamp and signatures from header',
});
}
if (!details.signatures.length) {
throw new Error_js_1.StripeSignatureVerificationError(decodedHeader, decodedPayload, {
message: 'No signatures found with expected scheme',
});
}
return {
decodedPayload,
decodedHeader,
details,
suspectPayloadType,
};
}
function validateComputedSignature(payload, header, details, expectedSignature, tolerance, suspectPayloadType, secretContainsWhitespace, receivedAt) {
const signatureFound = !!details.signatures.filter(platformFunctions.secureCompare.bind(platformFunctions, expectedSignature)).length;
const docsLocation = '\nLearn more about webhook signing and explore webhook integration examples for various frameworks at ' +
'https://github.com/stripe/stripe-node#webhook-signing';
const whitespaceMessage = secretContainsWhitespace
? '\n\nNote: The provided signing secret contains whitespace. This often indicates an extra newline or space is in the value'
: '';
if (!signatureFound) {
if (suspectPayloadType) {
throw new Error_js_1.StripeSignatureVerificationError(header, payload, {
message: 'Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the _raw_ request body.' +
'Payload was provided as a parsed JavaScript object instead. \n' +
'Signature verification is impossible without access to the original signed material. \n' +
docsLocation +
'\n' +
whitespaceMessage,
});
}
throw new Error_js_1.StripeSignatureVerificationError(header, payload, {
message: 'No signatures found matching the expected signature for payload.' +
' Are you passing the raw request body you received from Stripe? \n' +
docsLocation +
'\n' +
whitespaceMessage,
});
}
const timestampAge = Math.floor((typeof receivedAt === 'number' ? receivedAt : Date.now()) / 1000) - details.timestamp;
if (tolerance > 0 && timestampAge > tolerance) {
// @ts-ignore
throw new Error_js_1.StripeSignatureVerificationError(header, payload, {
message: 'Timestamp outside the tolerance zone',
});
}
return true;
}
function parseHeader(header, scheme) {
if (typeof header !== 'string') {
return null;
}
return header.split(',').reduce((accum, item) => {
const kv = item.split('=');
if (kv[0] === 't') {
accum.timestamp = parseInt(kv[1], 10);
}
if (kv[0] === scheme) {
accum.signatures.push(kv[1]);
}
return accum;
}, {
timestamp: -1,
signatures: [],
});
}
let webhooksCryptoProviderInstance = null;
/**
* Lazily instantiate a CryptoProvider instance. This is a stateless object
* so a singleton can be used here.
*/
function getCryptoProvider() {
if (!webhooksCryptoProviderInstance) {
webhooksCryptoProviderInstance = platformFunctions.createDefaultCryptoProvider();
}
return webhooksCryptoProviderInstance;
}
Webhook.signature = signature;
return Webhook;
}
exports.createWebhooks = createWebhooks;
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists