@orangecheck/me-client 0.5.0 → 0.7.0
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/dist/index.d.mts +36 -66
- package/dist/index.d.ts +36 -66
- package/dist/index.js +363 -140
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +361 -128
- package/dist/index.mjs.map +1 -1
- package/dist/popup.d.mts +22 -0
- package/dist/popup.d.ts +22 -0
- package/dist/popup.js +70 -0
- package/dist/popup.js.map +1 -0
- package/dist/popup.mjs +68 -0
- package/dist/popup.mjs.map +1 -0
- package/dist/server.d.mts +51 -0
- package/dist/server.d.ts +51 -0
- package/dist/server.js +73 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +65 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +29 -4
package/dist/index.mjs
CHANGED
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
export { OcSessionProvider, useOcSession, useOptionalOcSession } from '@orangecheck/auth-client';
|
|
4
|
-
import { ed25519 } from '@noble/curves/ed25519';
|
|
5
|
-
import { sha256 } from '@noble/hashes/sha256';
|
|
6
3
|
|
|
7
|
-
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
8
7
|
|
|
9
8
|
// src/transport.ts
|
|
10
9
|
var origin = "https://me.ochk.io";
|
|
10
|
+
var bearerToken = null;
|
|
11
11
|
function setOrigin(url) {
|
|
12
12
|
origin = url.replace(/\/$/, "");
|
|
13
13
|
}
|
|
14
14
|
function getOrigin() {
|
|
15
15
|
return origin;
|
|
16
16
|
}
|
|
17
|
+
function setBearerToken(token) {
|
|
18
|
+
bearerToken = token && token.length > 0 ? token : null;
|
|
19
|
+
}
|
|
20
|
+
function getBearerToken() {
|
|
21
|
+
return bearerToken;
|
|
22
|
+
}
|
|
23
|
+
function clearBearerToken() {
|
|
24
|
+
bearerToken = null;
|
|
25
|
+
}
|
|
17
26
|
async function api(path, opts = {}) {
|
|
27
|
+
const headers = {
|
|
28
|
+
"content-type": "application/json",
|
|
29
|
+
accept: "application/json"
|
|
30
|
+
};
|
|
31
|
+
if (bearerToken) headers["authorization"] = `Bearer ${bearerToken}`;
|
|
18
32
|
const res = await fetch(`${origin}${path}`, {
|
|
19
33
|
method: opts.method ?? "GET",
|
|
20
34
|
credentials: "include",
|
|
21
|
-
headers
|
|
35
|
+
headers,
|
|
22
36
|
body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0,
|
|
23
37
|
signal: opts.signal
|
|
24
38
|
});
|
|
@@ -75,8 +89,7 @@ async function create(opts) {
|
|
|
75
89
|
body: {
|
|
76
90
|
scope: opts.scope,
|
|
77
91
|
policy,
|
|
78
|
-
return_to: opts.returnTo ?? (typeof window !== "undefined" ? window.location.href : void 0)
|
|
79
|
-
...opts.project_key ? { project_key: opts.project_key } : {}
|
|
92
|
+
return_to: opts.returnTo ?? (typeof window !== "undefined" ? window.location.href : void 0)
|
|
80
93
|
}
|
|
81
94
|
});
|
|
82
95
|
}
|
|
@@ -177,13 +190,29 @@ async function authorize(opts) {
|
|
|
177
190
|
}
|
|
178
191
|
var payment = { authorize };
|
|
179
192
|
|
|
193
|
+
// src/event.ts
|
|
194
|
+
async function fire(options) {
|
|
195
|
+
if (!options.project_key) {
|
|
196
|
+
throw new Error("event.fire requires project_key");
|
|
197
|
+
}
|
|
198
|
+
if (!options.subtype) {
|
|
199
|
+
throw new Error("event.fire requires subtype");
|
|
200
|
+
}
|
|
201
|
+
return api("/api/integrator/event", {
|
|
202
|
+
method: "POST",
|
|
203
|
+
body: options
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
var event = { fire };
|
|
207
|
+
|
|
180
208
|
// src/types.ts
|
|
181
209
|
var PLATFORM_FEE_POLICY = {
|
|
182
210
|
/** Fraction of every gross_fee that OC retains. */
|
|
183
211
|
pct: 0.2,
|
|
184
212
|
/** Absolute minimum platform fee, in sats. */
|
|
185
213
|
min_floor_sats: 1,
|
|
186
|
-
/** Date this policy was last ratified. Changes require
|
|
214
|
+
/** Date this policy was last ratified. Changes require a versioned
|
|
215
|
+
* @orangecheck/me-client release. */
|
|
187
216
|
ratified: "2026-04-30"
|
|
188
217
|
};
|
|
189
218
|
var MIN_INTEGRATOR_PRICE_SATS = 5;
|
|
@@ -246,149 +275,353 @@ function validateIntegratorConfig(cfg) {
|
|
|
246
275
|
}
|
|
247
276
|
|
|
248
277
|
// src/config.ts
|
|
249
|
-
async function get() {
|
|
250
|
-
return api("/api/developer/config", { method: "GET" });
|
|
251
|
-
}
|
|
252
|
-
async function update(cfg) {
|
|
253
|
-
const result = validateIntegratorConfig(cfg);
|
|
254
|
-
if (!result.ok) {
|
|
255
|
-
const summary = result.errors.map((e) => e.subtype ? `${e.subtype}: ${e.message}` : e.message).join("; ");
|
|
256
|
-
throw new Error(`IntegratorPriceConfig invalid \xB7 ${summary}`);
|
|
257
|
-
}
|
|
258
|
-
return api("/api/developer/config", {
|
|
259
|
-
method: "POST",
|
|
260
|
-
body: cfg
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
278
|
function validate(cfg) {
|
|
264
279
|
return validateIntegratorConfig(cfg);
|
|
265
280
|
}
|
|
266
|
-
var config = {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
headers: { Accept: "application/json" }
|
|
277
|
-
});
|
|
278
|
-
if (!res.ok) {
|
|
279
|
-
throw new Error(`failed to fetch JWKS: ${res.status} ${res.statusText}`);
|
|
281
|
+
var config = { validate };
|
|
282
|
+
|
|
283
|
+
// node_modules/jose/dist/webapi/lib/buffer_utils.js
|
|
284
|
+
new TextEncoder();
|
|
285
|
+
var decoder = new TextDecoder();
|
|
286
|
+
|
|
287
|
+
// node_modules/jose/dist/webapi/lib/base64.js
|
|
288
|
+
function decodeBase64(encoded) {
|
|
289
|
+
if (Uint8Array.fromBase64) {
|
|
290
|
+
return Uint8Array.fromBase64(encoded);
|
|
280
291
|
}
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
function base64urlDecode(input) {
|
|
286
|
-
const padded = input.replace(/-/g, "+").replace(/_/g, "/").padEnd(
|
|
287
|
-
Math.ceil(input.length / 4) * 4,
|
|
288
|
-
"="
|
|
289
|
-
);
|
|
290
|
-
const bin = typeof atob === "function" ? atob(padded) : Buffer.from(padded, "base64").toString("binary");
|
|
291
|
-
const out = new Uint8Array(bin.length);
|
|
292
|
-
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
293
|
-
return out;
|
|
294
|
-
}
|
|
295
|
-
function hexDecode(input) {
|
|
296
|
-
const clean = input.toLowerCase().replace(/^0x/, "");
|
|
297
|
-
if (clean.length % 2 !== 0) throw new Error("hex string has odd length");
|
|
298
|
-
const out = new Uint8Array(clean.length / 2);
|
|
299
|
-
for (let i = 0; i < out.length; i++) {
|
|
300
|
-
out[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
292
|
+
const binary = atob(encoded);
|
|
293
|
+
const bytes = new Uint8Array(binary.length);
|
|
294
|
+
for (let i = 0; i < binary.length; i++) {
|
|
295
|
+
bytes[i] = binary.charCodeAt(i);
|
|
301
296
|
}
|
|
302
|
-
return
|
|
297
|
+
return bytes;
|
|
303
298
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
299
|
+
|
|
300
|
+
// node_modules/jose/dist/webapi/util/base64url.js
|
|
301
|
+
function decode(input) {
|
|
302
|
+
if (Uint8Array.fromBase64) {
|
|
303
|
+
return Uint8Array.fromBase64(typeof input === "string" ? input : decoder.decode(input), {
|
|
304
|
+
alphabet: "base64url"
|
|
305
|
+
});
|
|
312
306
|
}
|
|
313
|
-
|
|
314
|
-
|
|
307
|
+
let encoded = input;
|
|
308
|
+
if (encoded instanceof Uint8Array) {
|
|
309
|
+
encoded = decoder.decode(encoded);
|
|
315
310
|
}
|
|
316
|
-
|
|
311
|
+
encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
|
317
312
|
try {
|
|
318
|
-
|
|
319
|
-
} catch
|
|
320
|
-
|
|
321
|
-
ok: false,
|
|
322
|
-
reason: `failed to decode JWK x: ${err.message}`,
|
|
323
|
-
key_id: kid
|
|
324
|
-
};
|
|
313
|
+
return decodeBase64(encoded);
|
|
314
|
+
} catch {
|
|
315
|
+
throw new TypeError("The input to be decoded is not correctly encoded.");
|
|
325
316
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// node_modules/jose/dist/webapi/util/errors.js
|
|
320
|
+
var JOSEError = class extends Error {
|
|
321
|
+
constructor(message, options) {
|
|
322
|
+
super(message, options);
|
|
323
|
+
__publicField(this, "code", "ERR_JOSE_GENERIC");
|
|
324
|
+
this.name = this.constructor.name;
|
|
325
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
332
326
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
reason: `failed to decode signature: ${err.message}`,
|
|
340
|
-
key_id: kid
|
|
341
|
-
};
|
|
327
|
+
};
|
|
328
|
+
__publicField(JOSEError, "code", "ERR_JOSE_GENERIC");
|
|
329
|
+
var JOSENotSupported = class extends JOSEError {
|
|
330
|
+
constructor() {
|
|
331
|
+
super(...arguments);
|
|
332
|
+
__publicField(this, "code", "ERR_JOSE_NOT_SUPPORTED");
|
|
342
333
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
334
|
+
};
|
|
335
|
+
__publicField(JOSENotSupported, "code", "ERR_JOSE_NOT_SUPPORTED");
|
|
336
|
+
var _a, _b;
|
|
337
|
+
var JWKSMultipleMatchingKeys = class extends (_b = JOSEError, _a = Symbol.asyncIterator, _b) {
|
|
338
|
+
constructor(message = "multiple matching keys found in the JSON Web Key Set", options) {
|
|
339
|
+
super(message, options);
|
|
340
|
+
__publicField(this, _a);
|
|
341
|
+
__publicField(this, "code", "ERR_JWKS_MULTIPLE_MATCHING_KEYS");
|
|
349
342
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
343
|
+
};
|
|
344
|
+
__publicField(JWKSMultipleMatchingKeys, "code", "ERR_JWKS_MULTIPLE_MATCHING_KEYS");
|
|
345
|
+
|
|
346
|
+
// node_modules/jose/dist/webapi/lib/type_checks.js
|
|
347
|
+
var isObjectLike = (value) => typeof value === "object" && value !== null;
|
|
348
|
+
function isObject(input) {
|
|
349
|
+
if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
if (Object.getPrototypeOf(input) === null) {
|
|
353
|
+
return true;
|
|
357
354
|
}
|
|
355
|
+
let proto = input;
|
|
356
|
+
while (Object.getPrototypeOf(proto) !== null) {
|
|
357
|
+
proto = Object.getPrototypeOf(proto);
|
|
358
|
+
}
|
|
359
|
+
return Object.getPrototypeOf(input) === proto;
|
|
358
360
|
}
|
|
359
|
-
var webhook = { verify, fetchJwks };
|
|
360
361
|
|
|
361
|
-
//
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
362
|
+
// node_modules/jose/dist/webapi/lib/jwk_to_key.js
|
|
363
|
+
var unsupportedAlg = 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value';
|
|
364
|
+
function subtleMapping(jwk) {
|
|
365
|
+
let algorithm;
|
|
366
|
+
let keyUsages;
|
|
367
|
+
switch (jwk.kty) {
|
|
368
|
+
case "AKP": {
|
|
369
|
+
switch (jwk.alg) {
|
|
370
|
+
case "ML-DSA-44":
|
|
371
|
+
case "ML-DSA-65":
|
|
372
|
+
case "ML-DSA-87":
|
|
373
|
+
algorithm = { name: jwk.alg };
|
|
374
|
+
keyUsages = jwk.priv ? ["sign"] : ["verify"];
|
|
375
|
+
break;
|
|
376
|
+
default:
|
|
377
|
+
throw new JOSENotSupported(unsupportedAlg);
|
|
378
|
+
}
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
case "RSA": {
|
|
382
|
+
switch (jwk.alg) {
|
|
383
|
+
case "PS256":
|
|
384
|
+
case "PS384":
|
|
385
|
+
case "PS512":
|
|
386
|
+
algorithm = { name: "RSA-PSS", hash: `SHA-${jwk.alg.slice(-3)}` };
|
|
387
|
+
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
388
|
+
break;
|
|
389
|
+
case "RS256":
|
|
390
|
+
case "RS384":
|
|
391
|
+
case "RS512":
|
|
392
|
+
algorithm = { name: "RSASSA-PKCS1-v1_5", hash: `SHA-${jwk.alg.slice(-3)}` };
|
|
393
|
+
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
394
|
+
break;
|
|
395
|
+
case "RSA-OAEP":
|
|
396
|
+
case "RSA-OAEP-256":
|
|
397
|
+
case "RSA-OAEP-384":
|
|
398
|
+
case "RSA-OAEP-512":
|
|
399
|
+
algorithm = {
|
|
400
|
+
name: "RSA-OAEP",
|
|
401
|
+
hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`
|
|
402
|
+
};
|
|
403
|
+
keyUsages = jwk.d ? ["decrypt", "unwrapKey"] : ["encrypt", "wrapKey"];
|
|
404
|
+
break;
|
|
405
|
+
default:
|
|
406
|
+
throw new JOSENotSupported(unsupportedAlg);
|
|
407
|
+
}
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
case "EC": {
|
|
411
|
+
switch (jwk.alg) {
|
|
412
|
+
case "ES256":
|
|
413
|
+
case "ES384":
|
|
414
|
+
case "ES512":
|
|
415
|
+
algorithm = {
|
|
416
|
+
name: "ECDSA",
|
|
417
|
+
namedCurve: { ES256: "P-256", ES384: "P-384", ES512: "P-521" }[jwk.alg]
|
|
418
|
+
};
|
|
419
|
+
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
420
|
+
break;
|
|
421
|
+
case "ECDH-ES":
|
|
422
|
+
case "ECDH-ES+A128KW":
|
|
423
|
+
case "ECDH-ES+A192KW":
|
|
424
|
+
case "ECDH-ES+A256KW":
|
|
425
|
+
algorithm = { name: "ECDH", namedCurve: jwk.crv };
|
|
426
|
+
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
427
|
+
break;
|
|
428
|
+
default:
|
|
429
|
+
throw new JOSENotSupported(unsupportedAlg);
|
|
430
|
+
}
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
case "OKP": {
|
|
434
|
+
switch (jwk.alg) {
|
|
435
|
+
case "Ed25519":
|
|
436
|
+
case "EdDSA":
|
|
437
|
+
algorithm = { name: "Ed25519" };
|
|
438
|
+
keyUsages = jwk.d ? ["sign"] : ["verify"];
|
|
439
|
+
break;
|
|
440
|
+
case "ECDH-ES":
|
|
441
|
+
case "ECDH-ES+A128KW":
|
|
442
|
+
case "ECDH-ES+A192KW":
|
|
443
|
+
case "ECDH-ES+A256KW":
|
|
444
|
+
algorithm = { name: jwk.crv };
|
|
445
|
+
keyUsages = jwk.d ? ["deriveBits"] : [];
|
|
446
|
+
break;
|
|
447
|
+
default:
|
|
448
|
+
throw new JOSENotSupported(unsupportedAlg);
|
|
449
|
+
}
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
default:
|
|
453
|
+
throw new JOSENotSupported('Invalid or unsupported JWK "kty" (Key Type) Parameter value');
|
|
454
|
+
}
|
|
455
|
+
return { algorithm, keyUsages };
|
|
370
456
|
}
|
|
371
|
-
async function
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
});
|
|
457
|
+
async function jwkToKey(jwk) {
|
|
458
|
+
if (!jwk.alg) {
|
|
459
|
+
throw new TypeError('"alg" argument is required when "jwk.alg" is not present');
|
|
460
|
+
}
|
|
461
|
+
const { algorithm, keyUsages } = subtleMapping(jwk);
|
|
462
|
+
const keyData = { ...jwk };
|
|
463
|
+
if (keyData.kty !== "AKP") {
|
|
464
|
+
delete keyData.alg;
|
|
465
|
+
}
|
|
466
|
+
delete keyData.use;
|
|
467
|
+
return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
|
|
376
468
|
}
|
|
377
|
-
var delegation = { issue, revoke };
|
|
378
469
|
|
|
379
|
-
//
|
|
380
|
-
async function
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
470
|
+
// node_modules/jose/dist/webapi/key/import.js
|
|
471
|
+
async function importJWK(jwk, alg, options) {
|
|
472
|
+
if (!isObject(jwk)) {
|
|
473
|
+
throw new TypeError("JWK must be an object");
|
|
474
|
+
}
|
|
475
|
+
let ext;
|
|
476
|
+
ext ?? (ext = jwk.ext);
|
|
477
|
+
switch (jwk.kty) {
|
|
478
|
+
case "oct":
|
|
479
|
+
if (typeof jwk.k !== "string" || !jwk.k) {
|
|
480
|
+
throw new TypeError('missing "k" (Key Value) Parameter value');
|
|
481
|
+
}
|
|
482
|
+
return decode(jwk.k);
|
|
483
|
+
case "RSA":
|
|
484
|
+
if ("oth" in jwk && jwk.oth !== void 0) {
|
|
485
|
+
throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
|
|
486
|
+
}
|
|
487
|
+
return jwkToKey({ ...jwk, alg, ext });
|
|
488
|
+
case "AKP": {
|
|
489
|
+
if (typeof jwk.alg !== "string" || !jwk.alg) {
|
|
490
|
+
throw new TypeError('missing "alg" (Algorithm) Parameter value');
|
|
491
|
+
}
|
|
492
|
+
if (alg !== jwk.alg) {
|
|
493
|
+
throw new TypeError("JWK alg and alg option value mismatch");
|
|
494
|
+
}
|
|
495
|
+
return jwkToKey({ ...jwk, ext });
|
|
496
|
+
}
|
|
497
|
+
case "EC":
|
|
498
|
+
case "OKP":
|
|
499
|
+
return jwkToKey({ ...jwk, alg, ext });
|
|
500
|
+
default:
|
|
501
|
+
throw new JOSENotSupported('Unsupported "kty" (Key Type) Parameter value');
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// src/webhook.ts
|
|
506
|
+
var DEFAULT_ISSUER = "https://ochk.io";
|
|
507
|
+
var DEFAULT_TTL_MS = 60 * 60 * 1e3;
|
|
508
|
+
var jwksCache = /* @__PURE__ */ new Map();
|
|
509
|
+
var inflight = /* @__PURE__ */ new Map();
|
|
510
|
+
async function fetchJwks(issuer, ttlMs) {
|
|
511
|
+
const cached = jwksCache.get(issuer);
|
|
512
|
+
if (cached && Date.now() - cached.fetchedAt < ttlMs) return cached;
|
|
513
|
+
const existing = inflight.get(issuer);
|
|
514
|
+
if (existing) return existing;
|
|
515
|
+
const p = (async () => {
|
|
516
|
+
try {
|
|
517
|
+
const url = `${issuer.replace(/\/$/, "")}/.well-known/jwks.json`;
|
|
518
|
+
const res = await fetch(url, { headers: { Accept: "application/json" } });
|
|
519
|
+
if (!res.ok) throw new Error(`JWKS fetch ${url} returned ${res.status}`);
|
|
520
|
+
const json = await res.json();
|
|
521
|
+
if (!json || !Array.isArray(json.keys)) {
|
|
522
|
+
throw new Error(`JWKS at ${url} did not return {keys:[\u2026]}`);
|
|
523
|
+
}
|
|
524
|
+
const keys = {};
|
|
525
|
+
for (const k of json.keys) {
|
|
526
|
+
if (typeof k.kid !== "string") continue;
|
|
527
|
+
try {
|
|
528
|
+
keys[k.kid] = await importJWK(k, "EdDSA");
|
|
529
|
+
} catch {
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
const entry = { keys, fetchedAt: Date.now() };
|
|
533
|
+
jwksCache.set(issuer, entry);
|
|
534
|
+
return entry;
|
|
535
|
+
} catch (err) {
|
|
536
|
+
const stale = jwksCache.get(issuer);
|
|
537
|
+
if (stale) return stale;
|
|
538
|
+
throw err;
|
|
539
|
+
}
|
|
540
|
+
})().finally(() => {
|
|
541
|
+
inflight.delete(issuer);
|
|
384
542
|
});
|
|
385
|
-
|
|
543
|
+
inflight.set(issuer, p);
|
|
544
|
+
return p;
|
|
386
545
|
}
|
|
387
|
-
|
|
546
|
+
function hexToBytes(hex) {
|
|
547
|
+
if (typeof hex !== "string") return null;
|
|
548
|
+
const s = hex.trim();
|
|
549
|
+
if (s.length === 0 || s.length % 2 !== 0) return null;
|
|
550
|
+
const out = new Uint8Array(s.length / 2);
|
|
551
|
+
for (let i = 0; i < out.length; i++) {
|
|
552
|
+
const b = parseInt(s.slice(i * 2, i * 2 + 2), 16);
|
|
553
|
+
if (Number.isNaN(b)) return null;
|
|
554
|
+
out[i] = b;
|
|
555
|
+
}
|
|
556
|
+
return out;
|
|
557
|
+
}
|
|
558
|
+
function toBytes(input) {
|
|
559
|
+
if (typeof input === "string") return new TextEncoder().encode(input);
|
|
560
|
+
return input;
|
|
561
|
+
}
|
|
562
|
+
function toArrayBuffer(view) {
|
|
563
|
+
const buf = new ArrayBuffer(view.byteLength);
|
|
564
|
+
new Uint8Array(buf).set(view);
|
|
565
|
+
return buf;
|
|
566
|
+
}
|
|
567
|
+
async function verifyEd25519(key, sig, msg) {
|
|
568
|
+
const subtle = typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle ? globalThis.crypto.subtle : null;
|
|
569
|
+
if (!subtle) return false;
|
|
570
|
+
try {
|
|
571
|
+
return await subtle.verify(
|
|
572
|
+
"Ed25519",
|
|
573
|
+
key,
|
|
574
|
+
toArrayBuffer(sig),
|
|
575
|
+
toArrayBuffer(msg)
|
|
576
|
+
);
|
|
577
|
+
} catch {
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
async function verify(rawBody, sigHex, kid, options = {}) {
|
|
582
|
+
if (!sigHex) return { ok: false, reason: "missing signature" };
|
|
583
|
+
if (!kid) return { ok: false, reason: "missing kid" };
|
|
584
|
+
const sig = hexToBytes(sigHex);
|
|
585
|
+
if (!sig) return { ok: false, reason: "malformed signature (expected hex)" };
|
|
586
|
+
const msg = toBytes(rawBody);
|
|
587
|
+
let key;
|
|
588
|
+
if (options.jwk) {
|
|
589
|
+
if (options.jwk.kid !== kid) {
|
|
590
|
+
return { ok: false, reason: `kid mismatch (header=${kid}, jwk=${options.jwk.kid})` };
|
|
591
|
+
}
|
|
592
|
+
try {
|
|
593
|
+
key = await importJWK(options.jwk, "EdDSA");
|
|
594
|
+
} catch {
|
|
595
|
+
return { ok: false, reason: "could not import provided jwk" };
|
|
596
|
+
}
|
|
597
|
+
} else {
|
|
598
|
+
const issuer = options.issuer ?? DEFAULT_ISSUER;
|
|
599
|
+
const ttl = options.jwksCacheTtlMs ?? DEFAULT_TTL_MS;
|
|
600
|
+
try {
|
|
601
|
+
let entry = await fetchJwks(issuer, ttl);
|
|
602
|
+
key = entry.keys[kid];
|
|
603
|
+
if (!key) {
|
|
604
|
+
jwksCache.delete(issuer);
|
|
605
|
+
entry = await fetchJwks(issuer, ttl);
|
|
606
|
+
key = entry.keys[kid];
|
|
607
|
+
}
|
|
608
|
+
} catch (err) {
|
|
609
|
+
return { ok: false, reason: `jwks unavailable: ${err.message}` };
|
|
610
|
+
}
|
|
611
|
+
if (!key) return { ok: false, reason: `kid ${kid} not in JWKS` };
|
|
612
|
+
}
|
|
613
|
+
const ok = await verifyEd25519(key, sig, msg);
|
|
614
|
+
return ok ? { ok: true } : { ok: false, reason: "signature does not match" };
|
|
615
|
+
}
|
|
616
|
+
async function fetchJwksForce(issuer = DEFAULT_ISSUER) {
|
|
617
|
+
jwksCache.delete(issuer);
|
|
618
|
+
await fetchJwks(issuer, DEFAULT_TTL_MS);
|
|
619
|
+
}
|
|
620
|
+
var webhook = { verify, fetchJwks: fetchJwksForce };
|
|
388
621
|
|
|
389
622
|
// src/index.ts
|
|
390
|
-
var oc = { session, payment, config, webhook
|
|
623
|
+
var oc = { session, payment, event, config, webhook };
|
|
391
624
|
|
|
392
|
-
export { MIN_INTEGRATOR_PRICE_SATS, MeClientError, OcSignInButton, PLATFORM_FEE_POLICY, computeFees, config,
|
|
625
|
+
export { MIN_INTEGRATOR_PRICE_SATS, MeClientError, OcSignInButton, PLATFORM_FEE_POLICY, clearBearerToken, computeFees, config, event, getBearerToken, getOrigin, oc, onTelemetry, payment, session, setBearerToken, setOrigin, validateIntegratorConfig, webhook };
|
|
393
626
|
//# sourceMappingURL=index.mjs.map
|
|
394
627
|
//# sourceMappingURL=index.mjs.map
|