mollie-api-typescript 1.4.1 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/dist/commonjs/funcs/mandatesList.js +1 -0
- package/dist/commonjs/funcs/mandatesList.js.map +1 -1
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +1 -0
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/lib/config.d.ts +2 -2
- package/dist/commonjs/lib/config.js +2 -2
- package/dist/commonjs/models/index.d.ts +1 -0
- package/dist/commonjs/models/index.d.ts.map +1 -1
- package/dist/commonjs/models/index.js +1 -0
- package/dist/commonjs/models/index.js.map +1 -1
- package/dist/commonjs/models/listentitymethod.d.ts +1 -0
- package/dist/commonjs/models/listentitymethod.d.ts.map +1 -1
- package/dist/commonjs/models/listentitymethod.js +1 -0
- package/dist/commonjs/models/listentitymethod.js.map +1 -1
- package/dist/commonjs/models/listentitymethodall.d.ts +1 -0
- package/dist/commonjs/models/listentitymethodall.d.ts.map +1 -1
- package/dist/commonjs/models/listentitymethodall.js +1 -0
- package/dist/commonjs/models/listentitymethodall.js.map +1 -1
- package/dist/commonjs/models/listmandateresponse.d.ts +26 -0
- package/dist/commonjs/models/listmandateresponse.d.ts.map +1 -1
- package/dist/commonjs/models/listmandateresponse.js +15 -1
- package/dist/commonjs/models/listmandateresponse.js.map +1 -1
- package/dist/commonjs/models/listpaymentresponse.d.ts +3 -3
- package/dist/commonjs/models/listsettlementpaymentresponse.d.ts +3 -3
- package/dist/commonjs/models/mandateresponse.d.ts +26 -0
- package/dist/commonjs/models/mandateresponse.d.ts.map +1 -1
- package/dist/commonjs/models/mandateresponse.js +14 -1
- package/dist/commonjs/models/mandateresponse.js.map +1 -1
- package/dist/commonjs/models/mandatescopes.d.ts +22 -0
- package/dist/commonjs/models/mandatescopes.d.ts.map +1 -0
- package/dist/commonjs/models/mandatescopes.js +54 -0
- package/dist/commonjs/models/mandatescopes.js.map +1 -0
- package/dist/commonjs/models/methodincludewalletsparameter.d.ts +1 -0
- package/dist/commonjs/models/methodincludewalletsparameter.d.ts.map +1 -1
- package/dist/commonjs/models/methodincludewalletsparameter.js +1 -0
- package/dist/commonjs/models/methodincludewalletsparameter.js.map +1 -1
- package/dist/commonjs/models/operations/listmandates.d.ts +5 -0
- package/dist/commonjs/models/operations/listmandates.d.ts.map +1 -1
- package/dist/commonjs/models/operations/listmandates.js +1 -0
- package/dist/commonjs/models/operations/listmandates.js.map +1 -1
- package/dist/commonjs/models/paymentrequest.d.ts +11 -3
- package/dist/commonjs/models/paymentrequest.d.ts.map +1 -1
- package/dist/commonjs/models/paymentrequest.js +1 -0
- package/dist/commonjs/models/paymentrequest.js.map +1 -1
- package/dist/commonjs/models/paymentresponse.d.ts +3 -3
- package/dist/commonjs/utils/webhooks/index.d.ts +2 -0
- package/dist/commonjs/utils/webhooks/index.d.ts.map +1 -0
- package/dist/commonjs/utils/webhooks/index.js +7 -0
- package/dist/commonjs/utils/webhooks/index.js.map +1 -0
- package/dist/commonjs/utils/webhooks/signature_validator.d.ts +17 -0
- package/dist/commonjs/utils/webhooks/signature_validator.d.ts.map +1 -0
- package/dist/commonjs/utils/webhooks/signature_validator.js +88 -0
- package/dist/commonjs/utils/webhooks/signature_validator.js.map +1 -0
- package/dist/esm/funcs/mandatesList.js +1 -0
- package/dist/esm/funcs/mandatesList.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/config.d.ts +2 -2
- package/dist/esm/lib/config.js +2 -2
- package/dist/esm/models/index.d.ts +1 -0
- package/dist/esm/models/index.d.ts.map +1 -1
- package/dist/esm/models/index.js +1 -0
- package/dist/esm/models/index.js.map +1 -1
- package/dist/esm/models/listentitymethod.d.ts +1 -0
- package/dist/esm/models/listentitymethod.d.ts.map +1 -1
- package/dist/esm/models/listentitymethod.js +1 -0
- package/dist/esm/models/listentitymethod.js.map +1 -1
- package/dist/esm/models/listentitymethodall.d.ts +1 -0
- package/dist/esm/models/listentitymethodall.d.ts.map +1 -1
- package/dist/esm/models/listentitymethodall.js +1 -0
- package/dist/esm/models/listentitymethodall.js.map +1 -1
- package/dist/esm/models/listmandateresponse.d.ts +26 -0
- package/dist/esm/models/listmandateresponse.d.ts.map +1 -1
- package/dist/esm/models/listmandateresponse.js +14 -0
- package/dist/esm/models/listmandateresponse.js.map +1 -1
- package/dist/esm/models/listpaymentresponse.d.ts +3 -3
- package/dist/esm/models/listsettlementpaymentresponse.d.ts +3 -3
- package/dist/esm/models/mandateresponse.d.ts +26 -0
- package/dist/esm/models/mandateresponse.d.ts.map +1 -1
- package/dist/esm/models/mandateresponse.js +13 -0
- package/dist/esm/models/mandateresponse.js.map +1 -1
- package/dist/esm/models/mandatescopes.d.ts +22 -0
- package/dist/esm/models/mandatescopes.d.ts.map +1 -0
- package/dist/esm/models/mandatescopes.js +18 -0
- package/dist/esm/models/mandatescopes.js.map +1 -0
- package/dist/esm/models/methodincludewalletsparameter.d.ts +1 -0
- package/dist/esm/models/methodincludewalletsparameter.d.ts.map +1 -1
- package/dist/esm/models/methodincludewalletsparameter.js +1 -0
- package/dist/esm/models/methodincludewalletsparameter.js.map +1 -1
- package/dist/esm/models/operations/listmandates.d.ts +5 -0
- package/dist/esm/models/operations/listmandates.d.ts.map +1 -1
- package/dist/esm/models/operations/listmandates.js +1 -0
- package/dist/esm/models/operations/listmandates.js.map +1 -1
- package/dist/esm/models/paymentrequest.d.ts +11 -3
- package/dist/esm/models/paymentrequest.d.ts.map +1 -1
- package/dist/esm/models/paymentrequest.js +1 -0
- package/dist/esm/models/paymentrequest.js.map +1 -1
- package/dist/esm/models/paymentresponse.d.ts +3 -3
- package/dist/esm/utils/webhooks/index.d.ts +2 -0
- package/dist/esm/utils/webhooks/index.d.ts.map +1 -0
- package/dist/esm/utils/webhooks/index.js +2 -0
- package/dist/esm/utils/webhooks/index.js.map +1 -0
- package/dist/esm/utils/webhooks/signature_validator.d.ts +17 -0
- package/dist/esm/utils/webhooks/signature_validator.d.ts.map +1 -0
- package/dist/esm/utils/webhooks/signature_validator.js +83 -0
- package/dist/esm/utils/webhooks/signature_validator.js.map +1 -0
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/funcs/mandatesList.ts +1 -0
- package/src/index.ts +1 -0
- package/src/lib/config.ts +2 -2
- package/src/models/index.ts +1 -0
- package/src/models/listentitymethod.ts +1 -0
- package/src/models/listentitymethodall.ts +1 -0
- package/src/models/listmandateresponse.ts +36 -0
- package/src/models/listpaymentresponse.ts +3 -3
- package/src/models/listsettlementpaymentresponse.ts +3 -3
- package/src/models/mandateresponse.ts +33 -0
- package/src/models/mandatescopes.ts +30 -0
- package/src/models/methodincludewalletsparameter.ts +1 -0
- package/src/models/operations/listmandates.ts +6 -0
- package/src/models/paymentrequest.ts +12 -3
- package/src/models/paymentresponse.ts +3 -3
- package/src/utils/webhooks/index.ts +4 -0
- package/src/utils/webhooks/signature_validator.ts +136 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
export class InvalidSignatureException extends Error {
|
|
2
|
+
constructor(message: string) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "InvalidSignatureException";
|
|
5
|
+
|
|
6
|
+
Object.setPrototypeOf(this, InvalidSignatureException.prototype);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class SignatureValidator {
|
|
11
|
+
static readonly SIGNATURE_HEADER = "X-Mollie-Signature";
|
|
12
|
+
private static readonly SIGNATURE_PREFIX = "sha256=";
|
|
13
|
+
|
|
14
|
+
private readonly signingSecrets: string[];
|
|
15
|
+
|
|
16
|
+
constructor(signingSecrets: string | string[]) {
|
|
17
|
+
this.signingSecrets = Array.isArray(signingSecrets)
|
|
18
|
+
? [...signingSecrets]
|
|
19
|
+
: [signingSecrets];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static async validate(
|
|
23
|
+
payload: string,
|
|
24
|
+
signingSecrets: string | string[],
|
|
25
|
+
signatures?: string | string[] | null,
|
|
26
|
+
): Promise<boolean> {
|
|
27
|
+
return new SignatureValidator(signingSecrets).validatePayload(
|
|
28
|
+
payload,
|
|
29
|
+
signatures,
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async validatePayload(
|
|
34
|
+
payload: string,
|
|
35
|
+
signatures?: string | string[] | null,
|
|
36
|
+
): Promise<boolean> {
|
|
37
|
+
const signatureList = this.normalizeSignatures(signatures);
|
|
38
|
+
|
|
39
|
+
if (signatureList.length === 0) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return this.validateSignatures(payload, signatureList);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private normalizeSignatures(
|
|
47
|
+
signatures?: string | string[] | null,
|
|
48
|
+
): string[] {
|
|
49
|
+
if (typeof signatures === "string") {
|
|
50
|
+
return signatures ? [signatures] : [];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!signatures) {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return signatures.filter((signature): signature is string => !!signature);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private async validateSignatures(
|
|
61
|
+
payload: string,
|
|
62
|
+
signatures: string[],
|
|
63
|
+
): Promise<boolean> {
|
|
64
|
+
for (const signature of signatures) {
|
|
65
|
+
const extractedSignature = this.extractSignature(signature);
|
|
66
|
+
|
|
67
|
+
if (await this.isValidSignature(extractedSignature, payload)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
throw new InvalidSignatureException("Invalid webhook signature");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private extractSignature(signatureHeader: string): string {
|
|
76
|
+
if (signatureHeader.startsWith(SignatureValidator.SIGNATURE_PREFIX)) {
|
|
77
|
+
return signatureHeader.slice(SignatureValidator.SIGNATURE_PREFIX.length);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return signatureHeader;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private async isValidSignature(
|
|
84
|
+
providedSignature: string,
|
|
85
|
+
payload: string,
|
|
86
|
+
): Promise<boolean> {
|
|
87
|
+
for (const secret of this.signingSecrets) {
|
|
88
|
+
const expectedSignature = await SignatureValidator.createSignature(
|
|
89
|
+
payload,
|
|
90
|
+
secret,
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
if (constantTimeEquals(expectedSignature, providedSignature)) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static async createSignature(payload: string, secret: string): Promise<string> {
|
|
102
|
+
const subtle = globalThis.crypto?.subtle;
|
|
103
|
+
if (!subtle) {
|
|
104
|
+
throw new Error("Web Crypto API is not available in this runtime");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const encoder = new TextEncoder();
|
|
108
|
+
const key = await subtle.importKey(
|
|
109
|
+
"raw",
|
|
110
|
+
encoder.encode(secret),
|
|
111
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
112
|
+
false,
|
|
113
|
+
["sign"],
|
|
114
|
+
);
|
|
115
|
+
const signature = await subtle.sign("HMAC", key, encoder.encode(payload));
|
|
116
|
+
|
|
117
|
+
return toHex(signature);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function constantTimeEquals(left: string, right: string): boolean {
|
|
122
|
+
const maxLength = Math.max(left.length, right.length);
|
|
123
|
+
let mismatch = left.length ^ right.length;
|
|
124
|
+
|
|
125
|
+
for (let index = 0; index < maxLength; index++) {
|
|
126
|
+
mismatch |= (left.charCodeAt(index) || 0) ^ (right.charCodeAt(index) || 0);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return mismatch === 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function toHex(buffer: ArrayBuffer): string {
|
|
133
|
+
return Array.from(new Uint8Array(buffer))
|
|
134
|
+
.map((value) => value.toString(16).padStart(2, "0"))
|
|
135
|
+
.join("");
|
|
136
|
+
}
|