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