@lightsparkdev/core 0.3.10 → 0.3.11
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/CHANGELOG.md +6 -0
- package/package.json +2 -2
- package/src/LightsparkException.ts +1 -1
- package/src/ServerEnvironment.ts +1 -1
- package/src/auth/AuthProvider.ts +1 -1
- package/src/crypto/NodeKeyCache.ts +1 -1
- package/src/crypto/crypto.ts +22 -22
- package/src/requester/Requester.ts +13 -13
- package/src/utils/base64.ts +3 -3
- package/src/utils/currency.ts +2 -2
- package/src/utils/types.ts +1 -1
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightsparkdev/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.11",
|
|
4
4
|
"description": "Lightspark JS SDK",
|
|
5
5
|
"author": "Lightspark Inc.",
|
|
6
6
|
"keywords": [
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"eslint": "^8.3.0",
|
|
81
81
|
"eslint-watch": "^8.0.0",
|
|
82
82
|
"jest": "^29.4.1",
|
|
83
|
-
"prettier": "
|
|
83
|
+
"prettier": "3.0.2",
|
|
84
84
|
"prettier-plugin-organize-imports": "^3.2.2",
|
|
85
85
|
"ts-jest": "^29.0.5",
|
|
86
86
|
"tsc-absolute": "^1.0.1",
|
package/src/ServerEnvironment.ts
CHANGED
package/src/auth/AuthProvider.ts
CHANGED
package/src/crypto/crypto.ts
CHANGED
|
@@ -14,21 +14,21 @@ export type CryptoInterface = {
|
|
|
14
14
|
decryptSecretWithNodePassword: (
|
|
15
15
|
cipher: string,
|
|
16
16
|
encryptedSecret: string,
|
|
17
|
-
nodePassword: string
|
|
17
|
+
nodePassword: string,
|
|
18
18
|
) => Promise<ArrayBuffer | null>;
|
|
19
19
|
|
|
20
20
|
generateSigningKeyPair: () => Promise<GeneratedKeyPair>;
|
|
21
21
|
|
|
22
22
|
serializeSigningKey: (
|
|
23
23
|
key: CryptoKey | string,
|
|
24
|
-
format: "pkcs8" | "spki"
|
|
24
|
+
format: "pkcs8" | "spki",
|
|
25
25
|
) => Promise<ArrayBuffer>;
|
|
26
26
|
|
|
27
27
|
getNonce: () => Promise<number>;
|
|
28
28
|
|
|
29
29
|
sign: (
|
|
30
30
|
keyOrAlias: CryptoKey | string,
|
|
31
|
-
data: Uint8Array
|
|
31
|
+
data: Uint8Array,
|
|
32
32
|
) => Promise<ArrayBuffer>;
|
|
33
33
|
|
|
34
34
|
importPrivateSigningKey: (keyData: Uint8Array) => Promise<CryptoKey | string>;
|
|
@@ -80,7 +80,7 @@ const deriveKey = async (
|
|
|
80
80
|
salt: ArrayBuffer,
|
|
81
81
|
iterations: number,
|
|
82
82
|
algorithm: string,
|
|
83
|
-
bit_len: number
|
|
83
|
+
bit_len: number,
|
|
84
84
|
): Promise<[CryptoKey, ArrayBuffer]> => {
|
|
85
85
|
const enc = new TextEncoder();
|
|
86
86
|
const cryptoImpl = await getCrypto();
|
|
@@ -89,7 +89,7 @@ const deriveKey = async (
|
|
|
89
89
|
enc.encode(password),
|
|
90
90
|
"PBKDF2",
|
|
91
91
|
false,
|
|
92
|
-
["deriveBits", "deriveKey"]
|
|
92
|
+
["deriveBits", "deriveKey"],
|
|
93
93
|
);
|
|
94
94
|
|
|
95
95
|
const derived = await cryptoImpl.subtle.deriveBits(
|
|
@@ -100,7 +100,7 @@ const deriveKey = async (
|
|
|
100
100
|
hash: "SHA-256",
|
|
101
101
|
},
|
|
102
102
|
password_key,
|
|
103
|
-
bit_len
|
|
103
|
+
bit_len,
|
|
104
104
|
);
|
|
105
105
|
|
|
106
106
|
// Split the derived bytes into a 32 byte AES key and a 16 byte IV
|
|
@@ -109,7 +109,7 @@ const deriveKey = async (
|
|
|
109
109
|
derived.slice(0, 32),
|
|
110
110
|
{ name: algorithm, length: 256 },
|
|
111
111
|
false,
|
|
112
|
-
["encrypt", "decrypt"]
|
|
112
|
+
["encrypt", "decrypt"],
|
|
113
113
|
);
|
|
114
114
|
|
|
115
115
|
const iv = derived.slice(32);
|
|
@@ -120,7 +120,7 @@ const deriveKey = async (
|
|
|
120
120
|
const decrypt = async (
|
|
121
121
|
header_json: string,
|
|
122
122
|
ciphertext: string,
|
|
123
|
-
password: string
|
|
123
|
+
password: string,
|
|
124
124
|
): Promise<ArrayBuffer> => {
|
|
125
125
|
let decoded = b64decode(ciphertext);
|
|
126
126
|
|
|
@@ -139,7 +139,7 @@ const decrypt = async (
|
|
|
139
139
|
if (header.v < 0 || header.v > 4) {
|
|
140
140
|
throw new LightsparkException(
|
|
141
141
|
"DecryptionError",
|
|
142
|
-
"Unknown version ".concat(header.v)
|
|
142
|
+
"Unknown version ".concat(header.v),
|
|
143
143
|
);
|
|
144
144
|
}
|
|
145
145
|
|
|
@@ -158,12 +158,12 @@ const decrypt = async (
|
|
|
158
158
|
salt,
|
|
159
159
|
header.i,
|
|
160
160
|
algorithm,
|
|
161
|
-
256
|
|
161
|
+
256,
|
|
162
162
|
);
|
|
163
163
|
return await cryptoImpl.subtle.decrypt(
|
|
164
164
|
{ name: algorithm, iv: nonce.buffer },
|
|
165
165
|
key,
|
|
166
|
-
cipherText
|
|
166
|
+
cipherText,
|
|
167
167
|
);
|
|
168
168
|
} else {
|
|
169
169
|
const salt = decoded.slice(0, salt_len);
|
|
@@ -173,12 +173,12 @@ const decrypt = async (
|
|
|
173
173
|
salt,
|
|
174
174
|
header.i,
|
|
175
175
|
algorithm,
|
|
176
|
-
bit_len
|
|
176
|
+
bit_len,
|
|
177
177
|
);
|
|
178
178
|
return await cryptoImpl.subtle.decrypt(
|
|
179
179
|
{ name: algorithm, iv },
|
|
180
180
|
key,
|
|
181
|
-
encrypted
|
|
181
|
+
encrypted,
|
|
182
182
|
);
|
|
183
183
|
}
|
|
184
184
|
};
|
|
@@ -186,7 +186,7 @@ const decrypt = async (
|
|
|
186
186
|
async function decryptSecretWithNodePassword(
|
|
187
187
|
cipher: string,
|
|
188
188
|
encryptedSecret: string,
|
|
189
|
-
nodePassword: string
|
|
189
|
+
nodePassword: string,
|
|
190
190
|
): Promise<ArrayBuffer | null> {
|
|
191
191
|
let decryptedValue: ArrayBuffer | null = null;
|
|
192
192
|
try {
|
|
@@ -209,18 +209,18 @@ const generateSigningKeyPair = async (): Promise<GeneratedKeyPair> => {
|
|
|
209
209
|
hash: "SHA-256",
|
|
210
210
|
},
|
|
211
211
|
/*extractable*/ true,
|
|
212
|
-
/*keyUsages*/ ["sign", "verify"]
|
|
212
|
+
/*keyUsages*/ ["sign", "verify"],
|
|
213
213
|
);
|
|
214
214
|
};
|
|
215
215
|
|
|
216
216
|
const serializeSigningKey = async (
|
|
217
217
|
key: CryptoKey | string,
|
|
218
|
-
format: "pkcs8" | "spki"
|
|
218
|
+
format: "pkcs8" | "spki",
|
|
219
219
|
): Promise<ArrayBuffer> => {
|
|
220
220
|
const cryptoImpl = await getCrypto();
|
|
221
221
|
return await cryptoImpl.subtle.exportKey(
|
|
222
222
|
/*format*/ format,
|
|
223
|
-
/*key*/ key as CryptoKey
|
|
223
|
+
/*key*/ key as CryptoKey,
|
|
224
224
|
);
|
|
225
225
|
};
|
|
226
226
|
|
|
@@ -231,11 +231,11 @@ const getNonce = async () => {
|
|
|
231
231
|
|
|
232
232
|
const sign = async (
|
|
233
233
|
keyOrAlias: CryptoKey | string,
|
|
234
|
-
data: Uint8Array
|
|
234
|
+
data: Uint8Array,
|
|
235
235
|
): Promise<ArrayBuffer> => {
|
|
236
236
|
if (typeof keyOrAlias === "string") {
|
|
237
237
|
throw new LightsparkSigningException(
|
|
238
|
-
"Key alias not supported for default crypto."
|
|
238
|
+
"Key alias not supported for default crypto.",
|
|
239
239
|
);
|
|
240
240
|
}
|
|
241
241
|
const cryptoImpl = await getCrypto();
|
|
@@ -245,12 +245,12 @@ const sign = async (
|
|
|
245
245
|
saltLength: 32,
|
|
246
246
|
},
|
|
247
247
|
keyOrAlias as CryptoKey,
|
|
248
|
-
data
|
|
248
|
+
data,
|
|
249
249
|
);
|
|
250
250
|
};
|
|
251
251
|
|
|
252
252
|
const importPrivateSigningKey = async (
|
|
253
|
-
keyData: Uint8Array
|
|
253
|
+
keyData: Uint8Array,
|
|
254
254
|
): Promise<CryptoKey | string> => {
|
|
255
255
|
const cryptoImpl = await getCrypto();
|
|
256
256
|
return await cryptoImpl.subtle.importKey(
|
|
@@ -261,7 +261,7 @@ const importPrivateSigningKey = async (
|
|
|
261
261
|
hash: "SHA-256",
|
|
262
262
|
},
|
|
263
263
|
/*extractable*/ true,
|
|
264
|
-
/*keyUsages*/ ["sign"]
|
|
264
|
+
/*keyUsages*/ ["sign"],
|
|
265
265
|
);
|
|
266
266
|
};
|
|
267
267
|
|
|
@@ -33,7 +33,7 @@ class Requester {
|
|
|
33
33
|
private readonly sdkUserAgent: string,
|
|
34
34
|
private readonly authProvider: AuthProvider = new StubAuthProvider(),
|
|
35
35
|
private readonly baseUrl: string = DEFAULT_BASE_URL,
|
|
36
|
-
private readonly cryptoImpl: CryptoInterface = DefaultCrypto
|
|
36
|
+
private readonly cryptoImpl: CryptoInterface = DefaultCrypto,
|
|
37
37
|
) {
|
|
38
38
|
let websocketImpl;
|
|
39
39
|
if (typeof WebSocket === "undefined" && typeof window === "undefined") {
|
|
@@ -58,14 +58,14 @@ class Requester {
|
|
|
58
58
|
query.queryPayload,
|
|
59
59
|
query.variables || {},
|
|
60
60
|
query.signingNodeId,
|
|
61
|
-
!!query.skipAuth
|
|
61
|
+
!!query.skipAuth,
|
|
62
62
|
);
|
|
63
63
|
return query.constructObject(data);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
public subscribe<T>(
|
|
67
67
|
queryPayload: string,
|
|
68
|
-
variables: { [key: string]: unknown } = {}
|
|
68
|
+
variables: { [key: string]: unknown } = {},
|
|
69
69
|
) {
|
|
70
70
|
const operationNameRegex = /^\s*(query|mutation|subscription)\s+(\w+)/i;
|
|
71
71
|
const operationMatch = queryPayload.match(operationNameRegex);
|
|
@@ -76,7 +76,7 @@ class Requester {
|
|
|
76
76
|
if (operationType == "mutation") {
|
|
77
77
|
throw new LightsparkException(
|
|
78
78
|
"InvalidQuery",
|
|
79
|
-
"Mutation queries should call makeRawRequest instead"
|
|
79
|
+
"Mutation queries should call makeRawRequest instead",
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
82
|
// Undefined variables need to be null instead.
|
|
@@ -97,7 +97,7 @@ class Requester {
|
|
|
97
97
|
next: (data) => observer.next(data as { data: T }),
|
|
98
98
|
error: (err) => observer.error(err),
|
|
99
99
|
complete: () => observer.complete(),
|
|
100
|
-
})
|
|
100
|
+
}),
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -105,7 +105,7 @@ class Requester {
|
|
|
105
105
|
queryPayload: string,
|
|
106
106
|
variables: { [key: string]: unknown } = {},
|
|
107
107
|
signingNodeId: string | undefined = undefined,
|
|
108
|
-
skipAuth: boolean = false
|
|
108
|
+
skipAuth: boolean = false,
|
|
109
109
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- LIG-3400 */
|
|
110
110
|
): Promise<any | null> {
|
|
111
111
|
const operationNameRegex = /^\s*(query|mutation|subscription)\s+(\w+)/i;
|
|
@@ -117,7 +117,7 @@ class Requester {
|
|
|
117
117
|
if (operationType == "subscription") {
|
|
118
118
|
throw new LightsparkException(
|
|
119
119
|
"InvalidQuery",
|
|
120
|
-
"Subscription queries should call subscribe instead"
|
|
120
|
+
"Subscription queries should call subscribe instead",
|
|
121
121
|
);
|
|
122
122
|
}
|
|
123
123
|
// Undefined variables need to be null instead.
|
|
@@ -147,7 +147,7 @@ class Requester {
|
|
|
147
147
|
bodyData = await this.addSigningDataIfNeeded(
|
|
148
148
|
bodyData,
|
|
149
149
|
headers,
|
|
150
|
-
signingNodeId
|
|
150
|
+
signingNodeId,
|
|
151
151
|
);
|
|
152
152
|
|
|
153
153
|
let urlWithProtocol = this.baseUrl;
|
|
@@ -165,7 +165,7 @@ class Requester {
|
|
|
165
165
|
if (!response.ok) {
|
|
166
166
|
throw new LightsparkException(
|
|
167
167
|
"RequestFailed",
|
|
168
|
-
`Request ${operation} failed. ${response.statusText}
|
|
168
|
+
`Request ${operation} failed. ${response.statusText}`,
|
|
169
169
|
);
|
|
170
170
|
}
|
|
171
171
|
const responseJson = await response.json();
|
|
@@ -173,7 +173,7 @@ class Requester {
|
|
|
173
173
|
if (!data) {
|
|
174
174
|
throw new LightsparkException(
|
|
175
175
|
"RequestFailed",
|
|
176
|
-
`Request ${operation} failed. ${JSON.stringify(responseJson.errors)}
|
|
176
|
+
`Request ${operation} failed. ${JSON.stringify(responseJson.errors)}`,
|
|
177
177
|
);
|
|
178
178
|
}
|
|
179
179
|
return data;
|
|
@@ -192,7 +192,7 @@ class Requester {
|
|
|
192
192
|
private async addSigningDataIfNeeded(
|
|
193
193
|
queryPayload: { query: string; variables: unknown; operationName: string },
|
|
194
194
|
headers: { [key: string]: string },
|
|
195
|
-
signingNodeId: string | undefined
|
|
195
|
+
signingNodeId: string | undefined,
|
|
196
196
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- LIG-3400 */
|
|
197
197
|
): Promise<any> {
|
|
198
198
|
if (!signingNodeId) {
|
|
@@ -217,7 +217,7 @@ class Requester {
|
|
|
217
217
|
const key = await this.nodeKeyCache.getKey(signingNodeId);
|
|
218
218
|
if (!key) {
|
|
219
219
|
throw new LightsparkSigningException(
|
|
220
|
-
"Missing node of encrypted_signing_private_key"
|
|
220
|
+
"Missing node of encrypted_signing_private_key",
|
|
221
221
|
);
|
|
222
222
|
}
|
|
223
223
|
|
|
@@ -226,7 +226,7 @@ class Requester {
|
|
|
226
226
|
TextEncoderImpl = (await import("text-encoding")).TextEncoder;
|
|
227
227
|
}
|
|
228
228
|
const encodedPayload = new TextEncoderImpl().encode(
|
|
229
|
-
JSON.stringify(payload)
|
|
229
|
+
JSON.stringify(payload),
|
|
230
230
|
);
|
|
231
231
|
const signedPayload = await this.cryptoImpl.sign(key, encodedPayload);
|
|
232
232
|
const encodedSignedPayload = b64encode(signedPayload);
|
package/src/utils/base64.ts
CHANGED
|
@@ -16,7 +16,7 @@ const Base64 = {
|
|
|
16
16
|
|
|
17
17
|
if (charCode > 0xff) {
|
|
18
18
|
throw new Error(
|
|
19
|
-
"'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."
|
|
19
|
+
"'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.",
|
|
20
20
|
);
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -32,7 +32,7 @@ const Base64 = {
|
|
|
32
32
|
|
|
33
33
|
if (str.length % 4 == 1) {
|
|
34
34
|
throw new Error(
|
|
35
|
-
"'atob' failed: The string to be decoded is not correctly encoded."
|
|
35
|
+
"'atob' failed: The string to be decoded is not correctly encoded.",
|
|
36
36
|
);
|
|
37
37
|
}
|
|
38
38
|
for (
|
|
@@ -59,6 +59,6 @@ export const urlsafe_b64decode = (encoded: string): Uint8Array => {
|
|
|
59
59
|
|
|
60
60
|
export const b64encode = (data: ArrayBuffer): string => {
|
|
61
61
|
return Base64.btoa(
|
|
62
|
-
String.fromCharCode.apply(null, Array.from(new Uint8Array(data)))
|
|
62
|
+
String.fromCharCode.apply(null, Array.from(new Uint8Array(data))),
|
|
63
63
|
);
|
|
64
64
|
};
|
package/src/utils/currency.ts
CHANGED
|
@@ -101,7 +101,7 @@ const CONVERSION_MAP = {
|
|
|
101
101
|
|
|
102
102
|
export const convertCurrencyAmount = (
|
|
103
103
|
from: CurrencyAmount,
|
|
104
|
-
toUnit: CurrencyUnit
|
|
104
|
+
toUnit: CurrencyUnit,
|
|
105
105
|
): CurrencyAmount => {
|
|
106
106
|
if (
|
|
107
107
|
from.originalUnit === CurrencyUnit.FUTURE_VALUE ||
|
|
@@ -116,7 +116,7 @@ export const convertCurrencyAmount = (
|
|
|
116
116
|
if (!conversionFn) {
|
|
117
117
|
throw new LightsparkException(
|
|
118
118
|
"CurrencyError",
|
|
119
|
-
`Cannot convert from ${from.originalUnit} to ${toUnit}
|
|
119
|
+
`Cannot convert from ${from.originalUnit} to ${toUnit}`,
|
|
120
120
|
);
|
|
121
121
|
}
|
|
122
122
|
return {
|
package/src/utils/types.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type OmitTypename<T> = Omit<T, "__typename">;
|
|
|
17
17
|
export const isType =
|
|
18
18
|
<T extends string>(typename: T) =>
|
|
19
19
|
<N extends { __typename: string }>(
|
|
20
|
-
node: N | undefined | null
|
|
20
|
+
node: N | undefined | null,
|
|
21
21
|
): node is Extract<N, { __typename: T }> => {
|
|
22
22
|
return node?.__typename === typename;
|
|
23
23
|
};
|