Skip to content

Commit

Permalink
Merge pull request #1563 from stripe/anniel-migrate-remaining-infrast…
Browse files Browse the repository at this point in the history
…ructure

Migrate other Stripe infrastructure to TS
  • Loading branch information
anniel-stripe committed Sep 28, 2022
2 parents 17c5a21 + 06a6d4e commit 5aae73c
Show file tree
Hide file tree
Showing 20 changed files with 148 additions and 85 deletions.
10 changes: 8 additions & 2 deletions lib/Webhooks.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/apiVersion.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/crypto/SubtleCryptoProvider.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions lib/multipart.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion lib/net/FetchHttpClient.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion lib/net/NodeHttpClient.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 16 additions & 8 deletions lib/utils.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"node-fetch": "^2.6.2",
"nyc": "^15.1.0",
"prettier": "^1.16.4",
"typescript": "^3.7.2"
"typescript": "^4.8.3"
},
"resolutions": {
"ansi-regex": "5.0.1",
Expand Down
2 changes: 0 additions & 2 deletions src/ResourceNamespace.js → src/ResourceNamespace.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

// ResourceNamespace allows you to create nested resources, i.e. `stripe.issuing.cards`.
// It also works recursively, so you could do i.e. `stripe.billing.invoicing.pay`.

Expand Down
16 changes: 10 additions & 6 deletions src/Webhooks.js → src/Webhooks.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
'use strict';

const utils = require('./utils');
const {StripeError, StripeSignatureVerificationError} = require('./Error');
import utils = require('./utils');
import _Error = require('./Error');
const {StripeError, StripeSignatureVerificationError} = _Error;

const Webhook = {
DEFAULT_TOLERANCE: 300, // 5 minutes
signature: null,

constructEvent(payload, header, secret, tolerance, cryptoProvider) {
this.signature.verifyHeader(
Expand Down Expand Up @@ -169,6 +169,7 @@ function parseEventDetails(encodedPayload, encodedHeader, expectedScheme) {
if (!details || details.timestamp === -1) {
throw new StripeSignatureVerificationError({
message: 'Unable to extract timestamp and signatures from header',
// @ts-expect-error Type '{ decodedHeader: any; decodedPayload: any; }' is not assignable to type 'string'.
detail: {
decodedHeader,
decodedPayload,
Expand All @@ -179,6 +180,7 @@ function parseEventDetails(encodedPayload, encodedHeader, expectedScheme) {
if (!details.signatures.length) {
throw new StripeSignatureVerificationError({
message: 'No signatures found with expected scheme',
// @ts-expect-error Type '{ decodedHeader: any; decodedPayload: any; }' is not assignable to type 'string'.
detail: {
decodedHeader,
decodedPayload,
Expand Down Expand Up @@ -210,6 +212,7 @@ function validateComputedSignature(
'No signatures found matching the expected signature for payload.' +
' Are you passing the raw request body you received from Stripe?' +
' https://github.com/stripe/stripe-node#webhook-signing',
// @ts-expect-error Type '{ header: any; payload: any; }' is not assignable to type 'string'.
detail: {
header,
payload,
Expand All @@ -222,6 +225,7 @@ function validateComputedSignature(
if (tolerance > 0 && timestampAge > tolerance) {
throw new StripeSignatureVerificationError({
message: 'Timestamp outside the tolerance zone',
// @ts-expect-error Type '{ header: any; payload: any; }' is not assignable to type 'string'.
detail: {
header,
payload,
Expand All @@ -242,7 +246,7 @@ function parseHeader(header, scheme) {
const kv = item.split('=');

if (kv[0] === 't') {
accum.timestamp = kv[1];
accum.timestamp = parseInt(kv[1], 10);
}

if (kv[0] === scheme) {
Expand Down Expand Up @@ -274,4 +278,4 @@ function getNodeCryptoProvider() {

Webhook.signature = signature;

module.exports = Webhook;
export = Webhook;
8 changes: 3 additions & 5 deletions src/crypto/CryptoProvider.js → src/crypto/CryptoProvider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

/**
* Interface encapsulating the various crypto computations used by the library,
* allowing pluggable underlying crypto implementations.
Expand All @@ -13,7 +11,7 @@ class CryptoProvider {
* - computeHMACSignature('', 'test_secret') => 'f7f9bd47fb987337b5796fdc1fdb9ba221d0d5396814bfcaf9521f43fd8927fd'
* - computeHMACSignature('\ud83d\ude00', 'test_secret') => '837da296d05c4fe31f61d5d7ead035099d9585a5bcde87de952012a78f0b0c43
*/
computeHMACSignature(payload, secret) {
computeHMACSignature(payload: string, secret: string): string {
throw new Error('computeHMACSignature not implemented.');
}

Expand All @@ -28,9 +26,9 @@ class CryptoProvider {
* - computeHMACSignature('', 'test_secret') => 'f7f9bd47fb987337b5796fdc1fdb9ba221d0d5396814bfcaf9521f43fd8927fd'
* - computeHMACSignature('\ud83d\ude00', 'test_secret') => '837da296d05c4fe31f61d5d7ead035099d9585a5bcde87de952012a78f0b0c43
*/
computeHMACSignatureAsync(payload, secret) {
computeHMACSignatureAsync(payload: string, secret: string): Promise<string> {
throw new Error('computeHMACSignatureAsync not implemented.');
}
}

module.exports = CryptoProvider;
export = CryptoProvider;
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
'use strict';
import crypto = require('crypto');

const crypto = require('crypto');

const CryptoProvider = require('./CryptoProvider');
import CryptoProvider = require('./CryptoProvider');

/**
* `CryptoProvider which uses the Node `crypto` package for its computations.
*/
class NodeCryptoProvider extends CryptoProvider {
/** @override */
computeHMACSignature(payload, secret) {
computeHMACSignature(payload: string, secret: string): string {
return crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
}

/** @override */
async computeHMACSignatureAsync(payload, secret) {
async computeHMACSignatureAsync(
payload: string,
secret: string
): Promise<string> {
const signature = await this.computeHMACSignature(payload, secret);
return signature;
}
}

module.exports = NodeCryptoProvider;
export = NodeCryptoProvider;
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
'use strict';

const CryptoProvider = require('./CryptoProvider');
import CryptoProvider = require('./CryptoProvider');

/**
* `CryptoProvider which uses the SubtleCrypto interface of the Web Crypto API.
*
* This only supports asynchronous operations.
*/
class SubtleCryptoProvider extends CryptoProvider {
constructor(subtleCrypto) {
subtleCrypto: SubtleCrypto;

constructor(subtleCrypto: SubtleCrypto) {
super();

// If no subtle crypto is interface, default to the global namespace. This
Expand All @@ -18,15 +18,18 @@ class SubtleCryptoProvider extends CryptoProvider {
}

/** @override */
computeHMACSignature(payload, secret) {
computeHMACSignature(payload: string, secret: string): string {
throw new Error(
'SubtleCryptoProvider cannot be used in a synchronous context.'
);
}

/** @override */
async computeHMACSignatureAsync(payload, secret) {
const encoder = new TextEncoder('utf-8');
async computeHMACSignatureAsync(
payload: string,
secret: string
): Promise<string> {
const encoder = new TextEncoder();

const key = await this.subtleCrypto.importKey(
'raw',
Expand Down Expand Up @@ -66,4 +69,4 @@ for (let i = 0; i < byteHexMapping.length; i++) {
byteHexMapping[i] = i.toString(16).padStart(2, '0');
}

module.exports = SubtleCryptoProvider;
export = SubtleCryptoProvider;
13 changes: 7 additions & 6 deletions src/multipart.js → src/multipart.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

const utils = require('./utils');
const {StripeError} = require('./Error');
import utils = require('./utils');
import _Error = require('./Error');
const {StripeError} = _Error;

class StreamProcessingError extends StripeError {}

Expand Down Expand Up @@ -33,7 +32,7 @@ const multipartDataGenerator = (method, data, headers) => {
for (const k in flattenedData) {
const v = flattenedData[k];
push(`--${segno}`);
if (v.hasOwnProperty('data')) {
if (Object.prototype.hasOwnProperty.call(v, 'data')) {
push(
`Content-Disposition: form-data; name=${q(k)}; filename=${q(
v.name || 'blob'
Expand Down Expand Up @@ -93,4 +92,6 @@ const multipartRequestDataProcessor = (method, data, headers, callback) => {
return callback(null, buffer);
};

module.exports.multipartRequestDataProcessor = multipartRequestDataProcessor;
export = {
multipartRequestDataProcessor: multipartRequestDataProcessor,
};
Loading

0 comments on commit 5aae73c

Please sign in to comment.