@hiofu/apply-sdk 0.1.0 → 0.1.3
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 +39 -36
- package/dist/{chunk-6YSWH4IM.js → chunk-S5RLAIWP.js} +275 -19
- package/dist/{client-BD0-Mbnq.d.cts → client-BTGUPzt9.d.cts} +4 -4
- package/dist/{client-BD0-Mbnq.d.ts → client-BTGUPzt9.d.ts} +4 -4
- package/dist/index.cjs +282 -34
- package/dist/index.d.cts +11 -5
- package/dist/index.d.ts +11 -5
- package/dist/index.global.js +1 -1
- package/dist/index.js +45 -33
- package/dist/react.cjs +424 -18
- package/dist/react.d.cts +307 -3
- package/dist/react.d.ts +307 -3
- package/dist/react.js +170 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -34,6 +34,7 @@ __export(src_exports, {
|
|
|
34
34
|
HiofuApplyError: () => HiofuApplyError,
|
|
35
35
|
HiofuClient: () => HiofuClient,
|
|
36
36
|
HiofuConfigurationError: () => HiofuConfigurationError,
|
|
37
|
+
HiofuPopupError: () => HiofuPopupError,
|
|
37
38
|
autoBind: () => autoBind,
|
|
38
39
|
bootstrapFromScriptTag: () => bootstrapFromScriptTag,
|
|
39
40
|
createApplyClient: () => createApplyClient,
|
|
@@ -205,8 +206,12 @@ function generateVerifier(length = 64) {
|
|
|
205
206
|
if (length < 43 || length > 128) {
|
|
206
207
|
throw new Error("PKCE verifier length must be 43..128");
|
|
207
208
|
}
|
|
209
|
+
const cryptoApi = globalThis.crypto;
|
|
210
|
+
if (!cryptoApi?.getRandomValues) {
|
|
211
|
+
throw new Error("Secure random generation is unavailable in this browser.");
|
|
212
|
+
}
|
|
208
213
|
const buf = new Uint8Array(length);
|
|
209
|
-
|
|
214
|
+
cryptoApi.getRandomValues(buf);
|
|
210
215
|
let out = "";
|
|
211
216
|
for (let i = 0; i < length; i++) {
|
|
212
217
|
out += CHARSET[buf[i] % CHARSET.length];
|
|
@@ -219,9 +224,146 @@ function base64urlEncode(bytes) {
|
|
|
219
224
|
for (const b of u8) str += String.fromCharCode(b);
|
|
220
225
|
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
221
226
|
}
|
|
227
|
+
var SHA256_K = new Uint32Array([
|
|
228
|
+
1116352408,
|
|
229
|
+
1899447441,
|
|
230
|
+
3049323471,
|
|
231
|
+
3921009573,
|
|
232
|
+
961987163,
|
|
233
|
+
1508970993,
|
|
234
|
+
2453635748,
|
|
235
|
+
2870763221,
|
|
236
|
+
3624381080,
|
|
237
|
+
310598401,
|
|
238
|
+
607225278,
|
|
239
|
+
1426881987,
|
|
240
|
+
1925078388,
|
|
241
|
+
2162078206,
|
|
242
|
+
2614888103,
|
|
243
|
+
3248222580,
|
|
244
|
+
3835390401,
|
|
245
|
+
4022224774,
|
|
246
|
+
264347078,
|
|
247
|
+
604807628,
|
|
248
|
+
770255983,
|
|
249
|
+
1249150122,
|
|
250
|
+
1555081692,
|
|
251
|
+
1996064986,
|
|
252
|
+
2554220882,
|
|
253
|
+
2821834349,
|
|
254
|
+
2952996808,
|
|
255
|
+
3210313671,
|
|
256
|
+
3336571891,
|
|
257
|
+
3584528711,
|
|
258
|
+
113926993,
|
|
259
|
+
338241895,
|
|
260
|
+
666307205,
|
|
261
|
+
773529912,
|
|
262
|
+
1294757372,
|
|
263
|
+
1396182291,
|
|
264
|
+
1695183700,
|
|
265
|
+
1986661051,
|
|
266
|
+
2177026350,
|
|
267
|
+
2456956037,
|
|
268
|
+
2730485921,
|
|
269
|
+
2820302411,
|
|
270
|
+
3259730800,
|
|
271
|
+
3345764771,
|
|
272
|
+
3516065817,
|
|
273
|
+
3600352804,
|
|
274
|
+
4094571909,
|
|
275
|
+
275423344,
|
|
276
|
+
430227734,
|
|
277
|
+
506948616,
|
|
278
|
+
659060556,
|
|
279
|
+
883997877,
|
|
280
|
+
958139571,
|
|
281
|
+
1322822218,
|
|
282
|
+
1537002063,
|
|
283
|
+
1747873779,
|
|
284
|
+
1955562222,
|
|
285
|
+
2024104815,
|
|
286
|
+
2227730452,
|
|
287
|
+
2361852424,
|
|
288
|
+
2428436474,
|
|
289
|
+
2756734187,
|
|
290
|
+
3204031479,
|
|
291
|
+
3329325298
|
|
292
|
+
]);
|
|
293
|
+
function rightRotate(value, shift) {
|
|
294
|
+
return value >>> shift | value << 32 - shift;
|
|
295
|
+
}
|
|
296
|
+
function sha256Fallback(data) {
|
|
297
|
+
let paddedLength = data.length + 1 + 8;
|
|
298
|
+
while (paddedLength % 64 !== 0) paddedLength++;
|
|
299
|
+
const padded = new Uint8Array(paddedLength);
|
|
300
|
+
padded.set(data);
|
|
301
|
+
padded[data.length] = 128;
|
|
302
|
+
const view = new DataView(padded.buffer);
|
|
303
|
+
const bitLength = data.length * 8;
|
|
304
|
+
view.setUint32(paddedLength - 8, Math.floor(bitLength / 4294967296));
|
|
305
|
+
view.setUint32(paddedLength - 4, bitLength >>> 0);
|
|
306
|
+
let h0 = 1779033703;
|
|
307
|
+
let h1 = 3144134277;
|
|
308
|
+
let h2 = 1013904242;
|
|
309
|
+
let h3 = 2773480762;
|
|
310
|
+
let h4 = 1359893119;
|
|
311
|
+
let h5 = 2600822924;
|
|
312
|
+
let h6 = 528734635;
|
|
313
|
+
let h7 = 1541459225;
|
|
314
|
+
const w = new Uint32Array(64);
|
|
315
|
+
for (let offset = 0; offset < paddedLength; offset += 64) {
|
|
316
|
+
for (let i = 0; i < 16; i++) {
|
|
317
|
+
w[i] = view.getUint32(offset + i * 4);
|
|
318
|
+
}
|
|
319
|
+
for (let i = 16; i < 64; i++) {
|
|
320
|
+
const s0 = rightRotate(w[i - 15], 7) ^ rightRotate(w[i - 15], 18) ^ w[i - 15] >>> 3;
|
|
321
|
+
const s1 = rightRotate(w[i - 2], 17) ^ rightRotate(w[i - 2], 19) ^ w[i - 2] >>> 10;
|
|
322
|
+
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
323
|
+
}
|
|
324
|
+
let a = h0;
|
|
325
|
+
let b = h1;
|
|
326
|
+
let c = h2;
|
|
327
|
+
let d = h3;
|
|
328
|
+
let e = h4;
|
|
329
|
+
let f = h5;
|
|
330
|
+
let g = h6;
|
|
331
|
+
let h = h7;
|
|
332
|
+
for (let i = 0; i < 64; i++) {
|
|
333
|
+
const s1 = rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25);
|
|
334
|
+
const ch = e & f ^ ~e & g;
|
|
335
|
+
const temp1 = h + s1 + ch + SHA256_K[i] + w[i] >>> 0;
|
|
336
|
+
const s0 = rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22);
|
|
337
|
+
const maj = a & b ^ a & c ^ b & c;
|
|
338
|
+
const temp2 = s0 + maj >>> 0;
|
|
339
|
+
h = g;
|
|
340
|
+
g = f;
|
|
341
|
+
f = e;
|
|
342
|
+
e = d + temp1 >>> 0;
|
|
343
|
+
d = c;
|
|
344
|
+
c = b;
|
|
345
|
+
b = a;
|
|
346
|
+
a = temp1 + temp2 >>> 0;
|
|
347
|
+
}
|
|
348
|
+
h0 = h0 + a >>> 0;
|
|
349
|
+
h1 = h1 + b >>> 0;
|
|
350
|
+
h2 = h2 + c >>> 0;
|
|
351
|
+
h3 = h3 + d >>> 0;
|
|
352
|
+
h4 = h4 + e >>> 0;
|
|
353
|
+
h5 = h5 + f >>> 0;
|
|
354
|
+
h6 = h6 + g >>> 0;
|
|
355
|
+
h7 = h7 + h >>> 0;
|
|
356
|
+
}
|
|
357
|
+
const output = new ArrayBuffer(32);
|
|
358
|
+
const outputView = new DataView(output);
|
|
359
|
+
[h0, h1, h2, h3, h4, h5, h6, h7].forEach((word, index) => {
|
|
360
|
+
outputView.setUint32(index * 4, word);
|
|
361
|
+
});
|
|
362
|
+
return output;
|
|
363
|
+
}
|
|
222
364
|
async function generateChallenge(verifier) {
|
|
223
365
|
const data = new TextEncoder().encode(verifier);
|
|
224
|
-
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
366
|
+
const digest = globalThis.crypto?.subtle?.digest ? await globalThis.crypto.subtle.digest("SHA-256", data) : sha256Fallback(data);
|
|
225
367
|
return base64urlEncode(digest);
|
|
226
368
|
}
|
|
227
369
|
function generateState(length = 43) {
|
|
@@ -231,6 +373,13 @@ function generateState(length = 43) {
|
|
|
231
373
|
// src/popup.ts
|
|
232
374
|
var DEFAULT_HIOFU_ORIGIN = "https://hiofu.com";
|
|
233
375
|
var DEFAULT_AUTHORIZE_TIMEOUT_MS = 5 * 6e4;
|
|
376
|
+
var HiofuPopupError = class extends Error {
|
|
377
|
+
constructor(reason, message) {
|
|
378
|
+
super(message);
|
|
379
|
+
this.name = "HiofuPopupError";
|
|
380
|
+
this.reason = reason;
|
|
381
|
+
}
|
|
382
|
+
};
|
|
234
383
|
function resolveRedirectUri(config, hiofuOrigin) {
|
|
235
384
|
if (config.redirectUri) return config.redirectUri;
|
|
236
385
|
const hiofuBaseOrigin = new URL(hiofuOrigin).origin;
|
|
@@ -254,6 +403,8 @@ async function authorize(config, scopes, context, callbacks) {
|
|
|
254
403
|
url.searchParams.set("state", state);
|
|
255
404
|
url.searchParams.set("code_challenge", challenge);
|
|
256
405
|
url.searchParams.set("code_challenge_method", "S256");
|
|
406
|
+
url.searchParams.set("popup", "1");
|
|
407
|
+
url.searchParams.set("sdk", "apply");
|
|
257
408
|
if (context?.jobId) url.searchParams.set("job_id", context.jobId);
|
|
258
409
|
if (context?.jobTitle) url.searchParams.set("job_title", context.jobTitle);
|
|
259
410
|
if (context?.employerId)
|
|
@@ -281,11 +432,15 @@ async function authorize(config, scopes, context, callbacks) {
|
|
|
281
432
|
let focusTimer = null;
|
|
282
433
|
let overallTimeout = null;
|
|
283
434
|
let channel = null;
|
|
435
|
+
let openerLostAttention = false;
|
|
436
|
+
let openerRegainedAttention = false;
|
|
284
437
|
const cleanup = () => {
|
|
285
438
|
settled = true;
|
|
286
439
|
window.removeEventListener("message", onMessage);
|
|
287
440
|
window.removeEventListener("storage", onStorage);
|
|
441
|
+
window.removeEventListener("blur", onBlur);
|
|
288
442
|
window.removeEventListener("focus", onFocus);
|
|
443
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
289
444
|
window.clearInterval(poll);
|
|
290
445
|
if (focusTimer) clearTimeout(focusTimer);
|
|
291
446
|
if (overallTimeout) clearTimeout(overallTimeout);
|
|
@@ -356,6 +511,14 @@ async function authorize(config, scopes, context, callbacks) {
|
|
|
356
511
|
} catch {
|
|
357
512
|
}
|
|
358
513
|
};
|
|
514
|
+
const onBlur = () => {
|
|
515
|
+
openerLostAttention = true;
|
|
516
|
+
};
|
|
517
|
+
const onVisibilityChange = () => {
|
|
518
|
+
if (document.visibilityState === "hidden") {
|
|
519
|
+
openerLostAttention = true;
|
|
520
|
+
}
|
|
521
|
+
};
|
|
359
522
|
if (typeof BroadcastChannel !== "undefined") {
|
|
360
523
|
try {
|
|
361
524
|
channel = new BroadcastChannel("hiofu_oauth");
|
|
@@ -369,6 +532,9 @@ async function authorize(config, scopes, context, callbacks) {
|
|
|
369
532
|
}
|
|
370
533
|
const onFocus = () => {
|
|
371
534
|
if (settled) return;
|
|
535
|
+
if (openerLostAttention) {
|
|
536
|
+
openerRegainedAttention = true;
|
|
537
|
+
}
|
|
372
538
|
if (focusTimer) clearTimeout(focusTimer);
|
|
373
539
|
focusTimer = setTimeout(() => {
|
|
374
540
|
try {
|
|
@@ -383,12 +549,14 @@ async function authorize(config, scopes, context, callbacks) {
|
|
|
383
549
|
};
|
|
384
550
|
window.addEventListener("message", onMessage);
|
|
385
551
|
window.addEventListener("storage", onStorage);
|
|
552
|
+
window.addEventListener("blur", onBlur);
|
|
386
553
|
window.addEventListener("focus", onFocus);
|
|
554
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
387
555
|
const poll = window.setInterval(() => {
|
|
388
556
|
if (settled) return;
|
|
389
557
|
try {
|
|
390
558
|
const href = popup.location.href;
|
|
391
|
-
if (href
|
|
559
|
+
if (href) {
|
|
392
560
|
const popupUrl = new URL(href);
|
|
393
561
|
const code = popupUrl.searchParams.get("code");
|
|
394
562
|
const popupState = popupUrl.searchParams.get("state");
|
|
@@ -415,10 +583,14 @@ async function authorize(config, scopes, context, callbacks) {
|
|
|
415
583
|
}
|
|
416
584
|
} catch {
|
|
417
585
|
}
|
|
418
|
-
if (popup.closed) {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
586
|
+
if (popup.closed && openerRegainedAttention) {
|
|
587
|
+
try {
|
|
588
|
+
const raw = localStorage.getItem("hiofu_oauth_result");
|
|
589
|
+
if (raw) {
|
|
590
|
+
handleResult(JSON.parse(raw), "close_check");
|
|
591
|
+
}
|
|
592
|
+
} catch {
|
|
593
|
+
}
|
|
422
594
|
}
|
|
423
595
|
}, 500);
|
|
424
596
|
overallTimeout = window.setTimeout(() => {
|
|
@@ -429,20 +601,81 @@ async function authorize(config, scopes, context, callbacks) {
|
|
|
429
601
|
} catch {
|
|
430
602
|
}
|
|
431
603
|
callbacks?.onPopupClosed?.("timed_out");
|
|
432
|
-
reject(
|
|
604
|
+
reject(
|
|
605
|
+
new HiofuPopupError(
|
|
606
|
+
"timed_out",
|
|
607
|
+
"Authorization timed out. Please try again."
|
|
608
|
+
)
|
|
609
|
+
);
|
|
433
610
|
}, authorizeTimeoutMs);
|
|
434
611
|
});
|
|
435
612
|
}
|
|
436
613
|
|
|
614
|
+
// src/random.ts
|
|
615
|
+
var fallbackCounter = 0;
|
|
616
|
+
function createRandomId(prefix = "hiofu") {
|
|
617
|
+
const cryptoApi = globalThis.crypto;
|
|
618
|
+
if (typeof cryptoApi?.randomUUID === "function") {
|
|
619
|
+
return `${prefix}_${cryptoApi.randomUUID()}`;
|
|
620
|
+
}
|
|
621
|
+
if (typeof cryptoApi?.getRandomValues === "function") {
|
|
622
|
+
const bytes = new Uint8Array(16);
|
|
623
|
+
cryptoApi.getRandomValues(bytes);
|
|
624
|
+
const suffix = Array.from(
|
|
625
|
+
bytes,
|
|
626
|
+
(byte) => byte.toString(16).padStart(2, "0")
|
|
627
|
+
).join("");
|
|
628
|
+
return `${prefix}_${Date.now()}_${suffix}`;
|
|
629
|
+
}
|
|
630
|
+
fallbackCounter += 1;
|
|
631
|
+
const clock = typeof globalThis.performance?.now === "function" ? Math.floor(globalThis.performance.now() * 1e3) : 0;
|
|
632
|
+
return `${prefix}_${Date.now()}_${clock}_${fallbackCounter}`;
|
|
633
|
+
}
|
|
634
|
+
|
|
437
635
|
// src/storage.ts
|
|
438
636
|
var memory = /* @__PURE__ */ new Map();
|
|
637
|
+
function legacyStorageKey(clientId) {
|
|
638
|
+
return `hiofu:${clientId}:token`;
|
|
639
|
+
}
|
|
640
|
+
function storageOrigin() {
|
|
641
|
+
if (typeof window === "undefined") return "server";
|
|
642
|
+
return window.location?.origin || "unknown-origin";
|
|
643
|
+
}
|
|
644
|
+
function storageKey(clientId) {
|
|
645
|
+
return `hiofu:${storageOrigin()}:${clientId}:token`;
|
|
646
|
+
}
|
|
647
|
+
function parseToken(raw) {
|
|
648
|
+
try {
|
|
649
|
+
return JSON.parse(raw);
|
|
650
|
+
} catch {
|
|
651
|
+
return null;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
function sessionSafeToken(token) {
|
|
655
|
+
return {
|
|
656
|
+
...token,
|
|
657
|
+
refreshToken: null
|
|
658
|
+
};
|
|
659
|
+
}
|
|
439
660
|
function readToken(clientId, storage) {
|
|
440
661
|
if (storage === "memory") return memory.get(clientId) ?? null;
|
|
441
662
|
if (typeof window === "undefined") return null;
|
|
442
663
|
try {
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
664
|
+
const key = storageKey(clientId);
|
|
665
|
+
const raw = window.sessionStorage.getItem(key);
|
|
666
|
+
if (raw) {
|
|
667
|
+
const parsed2 = parseToken(raw);
|
|
668
|
+
return parsed2 ? sessionSafeToken(parsed2) : null;
|
|
669
|
+
}
|
|
670
|
+
const legacyKey = legacyStorageKey(clientId);
|
|
671
|
+
const legacyRaw = window.sessionStorage.getItem(legacyKey);
|
|
672
|
+
if (!legacyRaw) return null;
|
|
673
|
+
const parsed = parseToken(legacyRaw);
|
|
674
|
+
if (!parsed) return null;
|
|
675
|
+
const migrated = sessionSafeToken(parsed);
|
|
676
|
+
window.sessionStorage.setItem(key, JSON.stringify(migrated));
|
|
677
|
+
window.sessionStorage.removeItem(legacyKey);
|
|
678
|
+
return migrated;
|
|
446
679
|
} catch {
|
|
447
680
|
return null;
|
|
448
681
|
}
|
|
@@ -455,9 +688,10 @@ function writeToken(clientId, storage, token) {
|
|
|
455
688
|
if (typeof window === "undefined") return;
|
|
456
689
|
try {
|
|
457
690
|
window.sessionStorage.setItem(
|
|
458
|
-
|
|
459
|
-
JSON.stringify(token)
|
|
691
|
+
storageKey(clientId),
|
|
692
|
+
JSON.stringify(sessionSafeToken(token))
|
|
460
693
|
);
|
|
694
|
+
window.sessionStorage.removeItem(legacyStorageKey(clientId));
|
|
461
695
|
} catch {
|
|
462
696
|
}
|
|
463
697
|
}
|
|
@@ -468,7 +702,8 @@ function clearToken(clientId, storage) {
|
|
|
468
702
|
}
|
|
469
703
|
if (typeof window === "undefined") return;
|
|
470
704
|
try {
|
|
471
|
-
window.sessionStorage.removeItem(
|
|
705
|
+
window.sessionStorage.removeItem(storageKey(clientId));
|
|
706
|
+
window.sessionStorage.removeItem(legacyStorageKey(clientId));
|
|
472
707
|
} catch {
|
|
473
708
|
}
|
|
474
709
|
}
|
|
@@ -495,10 +730,7 @@ function normalizeApplyScopes(scopes) {
|
|
|
495
730
|
return dedupeScopes(normalized);
|
|
496
731
|
}
|
|
497
732
|
function generateIdempotencyKey() {
|
|
498
|
-
|
|
499
|
-
return `hiofu_${crypto.randomUUID()}`;
|
|
500
|
-
}
|
|
501
|
-
return `hiofu_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
733
|
+
return createRandomId();
|
|
502
734
|
}
|
|
503
735
|
function toPublicToken(token) {
|
|
504
736
|
return {
|
|
@@ -735,9 +967,9 @@ function autoBind(client) {
|
|
|
735
967
|
const variationId = target.getAttribute("data-hiofu-variation-id") ?? void 0;
|
|
736
968
|
const idempotencyKey = target.getAttribute("data-hiofu-idempotency-key") ?? void 0;
|
|
737
969
|
const scopes = parseScopes(target.getAttribute("data-hiofu-scopes"));
|
|
738
|
-
if (!jobId || !jobTitle
|
|
970
|
+
if (!jobId || !jobTitle) {
|
|
739
971
|
const err = new Error(
|
|
740
|
-
"data-job-id
|
|
972
|
+
"data-job-id and data-job-title are required"
|
|
741
973
|
);
|
|
742
974
|
target.dispatchEvent(
|
|
743
975
|
new CustomEvent("hiofu:apply:error", {
|
|
@@ -751,17 +983,17 @@ function autoBind(client) {
|
|
|
751
983
|
try {
|
|
752
984
|
const applyOptions = {
|
|
753
985
|
jobId,
|
|
754
|
-
jobTitle
|
|
755
|
-
employerId,
|
|
756
|
-
employerName
|
|
986
|
+
jobTitle
|
|
757
987
|
};
|
|
988
|
+
if (employerId) applyOptions.employerId = employerId;
|
|
989
|
+
if (employerName) applyOptions.employerName = employerName;
|
|
758
990
|
if (variationId) applyOptions.variationId = variationId;
|
|
759
991
|
if (idempotencyKey) applyOptions.idempotencyKey = idempotencyKey;
|
|
760
992
|
if (scopes) applyOptions.scopes = scopes;
|
|
761
993
|
if (externalRoleId || externalEmployerId) {
|
|
762
994
|
applyOptions.role = {
|
|
763
995
|
externalRoleId: externalRoleId ?? jobId,
|
|
764
|
-
externalEmployerId: externalEmployerId ?? employerId,
|
|
996
|
+
externalEmployerId: externalEmployerId ?? employerId ?? void 0,
|
|
765
997
|
title: target.getAttribute("data-role-title") ?? jobTitle,
|
|
766
998
|
description: target.getAttribute("data-role-description") ?? void 0,
|
|
767
999
|
department: target.getAttribute("data-role-department") ?? void 0,
|
|
@@ -855,10 +1087,7 @@ var ENDPOINTS = {
|
|
|
855
1087
|
}
|
|
856
1088
|
};
|
|
857
1089
|
function createCorrelationId() {
|
|
858
|
-
|
|
859
|
-
return `hiofu_${crypto.randomUUID()}`;
|
|
860
|
-
}
|
|
861
|
-
return `hiofu_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
1090
|
+
return createRandomId();
|
|
862
1091
|
}
|
|
863
1092
|
function assertPublicKey(environment, publicKey) {
|
|
864
1093
|
if (environment === "sandbox" && !publicKey.startsWith("pk_test_")) {
|
|
@@ -880,17 +1109,14 @@ function assertPublicKey(environment, publicKey) {
|
|
|
880
1109
|
}
|
|
881
1110
|
function toApplyOptions(payload) {
|
|
882
1111
|
const locations = payload.role.locations ?? (payload.role.location ? [payload.role.location] : void 0);
|
|
883
|
-
|
|
1112
|
+
const options = {
|
|
884
1113
|
jobId: payload.externalJobId,
|
|
885
1114
|
jobTitle: payload.jobTitle ?? payload.role.title,
|
|
886
|
-
employerId: payload.externalEmployerId,
|
|
887
|
-
employerName: payload.employerName ?? payload.externalEmployerId,
|
|
888
1115
|
scopes: payload.scopes,
|
|
889
1116
|
variationId: payload.variationId,
|
|
890
1117
|
idempotencyKey: payload.idempotencyKey,
|
|
891
1118
|
role: {
|
|
892
1119
|
externalRoleId: payload.externalJobId,
|
|
893
|
-
externalEmployerId: payload.externalEmployerId,
|
|
894
1120
|
title: payload.role.title,
|
|
895
1121
|
description: payload.role.description,
|
|
896
1122
|
locations,
|
|
@@ -904,6 +1130,14 @@ function toApplyOptions(payload) {
|
|
|
904
1130
|
}
|
|
905
1131
|
}
|
|
906
1132
|
};
|
|
1133
|
+
if (payload.externalEmployerId) {
|
|
1134
|
+
options.employerId = payload.externalEmployerId;
|
|
1135
|
+
options.role.externalEmployerId = payload.externalEmployerId;
|
|
1136
|
+
}
|
|
1137
|
+
if (payload.employerName) {
|
|
1138
|
+
options.employerName = payload.employerName;
|
|
1139
|
+
}
|
|
1140
|
+
return options;
|
|
907
1141
|
}
|
|
908
1142
|
function toNormalizedResult(result, environment, partnerApplicationId) {
|
|
909
1143
|
const submittedAt = result.application.submittedAt instanceof Date ? result.application.submittedAt.toISOString() : result.application.submittedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -924,12 +1158,26 @@ function toApplyError(error, correlationId) {
|
|
|
924
1158
|
let retryable = false;
|
|
925
1159
|
if (error instanceof HiofuConfigurationError) {
|
|
926
1160
|
code = error.code === "hiofu.environment_mismatch" ? "environment_mismatch" : "configuration_error";
|
|
1161
|
+
} else if (error instanceof HiofuPopupError) {
|
|
1162
|
+
if (error.reason === "timed_out") {
|
|
1163
|
+
code = "timeout";
|
|
1164
|
+
} else {
|
|
1165
|
+
code = "popup_closed";
|
|
1166
|
+
}
|
|
1167
|
+
retryable = true;
|
|
927
1168
|
} else if (/popup blocked/i.test(message)) {
|
|
928
1169
|
code = "popup_blocked";
|
|
929
1170
|
retryable = true;
|
|
1171
|
+
} else if (/authorization popup closed|popup closed/i.test(message)) {
|
|
1172
|
+
code = "popup_closed";
|
|
1173
|
+
retryable = true;
|
|
930
1174
|
} else if (/timed out/i.test(message)) {
|
|
931
1175
|
code = "timeout";
|
|
932
1176
|
retryable = true;
|
|
1177
|
+
} else if (/unknown or inactive client|redirect_uri not registered|partner is not approved|must accept dpa|unknown scope|scope\(s\) not permitted|pkce/i.test(
|
|
1178
|
+
message
|
|
1179
|
+
)) {
|
|
1180
|
+
code = "configuration_error";
|
|
933
1181
|
} else if (/access_denied|consent/i.test(message)) {
|
|
934
1182
|
code = "consent_required";
|
|
935
1183
|
} else if (error instanceof HiofuApiError) {
|
|
@@ -992,10 +1240,10 @@ function createApplyClient(config) {
|
|
|
992
1240
|
const applyError = toApplyError(err, correlationId);
|
|
993
1241
|
if (applyError.code === "consent_required") {
|
|
994
1242
|
config.onCancel?.({ reason: "user_cancelled", correlationId });
|
|
1243
|
+
} else if (applyError.code === "popup_closed") {
|
|
1244
|
+
config.onCancel?.({ reason: "popup_closed", correlationId });
|
|
995
1245
|
} else if (applyError.code === "timeout") {
|
|
996
1246
|
config.onCancel?.({ reason: "timeout", correlationId });
|
|
997
|
-
} else if (/popup closed/i.test(applyError.message)) {
|
|
998
|
-
config.onCancel?.({ reason: "popup_closed", correlationId });
|
|
999
1247
|
}
|
|
1000
1248
|
config.onError?.(applyError);
|
|
1001
1249
|
throw applyError;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as HiofuClient, a as HiofuScope, b as HiofuApplyResult, c as HiofuConfig, d as HiofuEvent, e as HiofuApplyOptions, f as HiofuTokenSet } from './client-
|
|
2
|
-
export { D as DEFAULT_APPLY_SCOPES, g as DEFAULT_AUTHORIZE_SCOPES, h as HiofuApplyRole, i as HiofuPartner } from './client-
|
|
1
|
+
import { H as HiofuClient, a as HiofuScope, b as HiofuApplyResult, c as HiofuConfig, d as HiofuEvent, e as HiofuApplyOptions, f as HiofuTokenSet } from './client-BTGUPzt9.cjs';
|
|
2
|
+
export { D as DEFAULT_APPLY_SCOPES, g as DEFAULT_AUTHORIZE_SCOPES, h as HiofuApplyRole, i as HiofuPartner } from './client-BTGUPzt9.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Scan the document for `[data-hiofu-apply]` buttons and wire them up to call
|
|
@@ -33,7 +33,7 @@ declare class HiofuApiError extends Error {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
type HiofuEnvironment = "sandbox" | "production";
|
|
36
|
-
type HiofuApplyErrorCode = "configuration_error" | "environment_mismatch" | "popup_blocked" | "auth_failed" | "consent_required" | "role_mapping_failed" | "submit_failed" | "timeout";
|
|
36
|
+
type HiofuApplyErrorCode = "configuration_error" | "environment_mismatch" | "popup_blocked" | "popup_closed" | "auth_failed" | "consent_required" | "role_mapping_failed" | "submit_failed" | "timeout";
|
|
37
37
|
declare class HiofuApplyError extends Error {
|
|
38
38
|
readonly code: HiofuApplyErrorCode;
|
|
39
39
|
readonly correlationId: string;
|
|
@@ -68,7 +68,7 @@ interface HiofuCreateApplyClientConfig {
|
|
|
68
68
|
apiBase?: string;
|
|
69
69
|
}
|
|
70
70
|
interface HiofuApplyPayload {
|
|
71
|
-
externalEmployerId
|
|
71
|
+
externalEmployerId?: string;
|
|
72
72
|
externalJobId: string;
|
|
73
73
|
role: {
|
|
74
74
|
title: string;
|
|
@@ -117,6 +117,12 @@ declare class HiofuConfigurationError extends Error {
|
|
|
117
117
|
constructor(code: HiofuConfigurationErrorCode, message: string, details?: Record<string, unknown>);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
type HiofuPopupErrorReason = "user_closed" | "timed_out";
|
|
121
|
+
declare class HiofuPopupError extends Error {
|
|
122
|
+
readonly reason: HiofuPopupErrorReason;
|
|
123
|
+
constructor(reason: HiofuPopupErrorReason, message: string);
|
|
124
|
+
}
|
|
125
|
+
|
|
120
126
|
/**
|
|
121
127
|
* @fileoverview Hiofu brand assets exposed for partners that want their
|
|
122
128
|
* "Apply with Hiofu" button to match the canonical look. All values here are
|
|
@@ -155,4 +161,4 @@ declare const Hiofu: {
|
|
|
155
161
|
logout(): Promise<void>;
|
|
156
162
|
};
|
|
157
163
|
|
|
158
|
-
export { HIOFU_BRAND_COLOR, HIOFU_BRAND_SOFT, HIOFU_BUTTON_LABEL, HIOFU_FONT_FAMILY, HIOFU_FONT_URL, HIOFU_TAGLINE, HIOFU_WORDMARK, Hiofu, HiofuApiError, type HiofuApplyClient, HiofuApplyError, type HiofuApplyErrorCode, HiofuApplyOptions, type HiofuApplyPayload, HiofuApplyResult, type HiofuCancelContext, HiofuClient, HiofuConfig, HiofuConfigurationError, type HiofuCreateApplyClientConfig, type HiofuEnvironment, HiofuEvent, type HiofuNormalizedApplyResult, HiofuScope, HiofuTokenSet, autoBind, bootstrapFromScriptTag, createApplyClient, hiofuLogoSvg, isAutoBound };
|
|
164
|
+
export { HIOFU_BRAND_COLOR, HIOFU_BRAND_SOFT, HIOFU_BUTTON_LABEL, HIOFU_FONT_FAMILY, HIOFU_FONT_URL, HIOFU_TAGLINE, HIOFU_WORDMARK, Hiofu, HiofuApiError, type HiofuApplyClient, HiofuApplyError, type HiofuApplyErrorCode, HiofuApplyOptions, type HiofuApplyPayload, HiofuApplyResult, type HiofuCancelContext, HiofuClient, HiofuConfig, HiofuConfigurationError, type HiofuCreateApplyClientConfig, type HiofuEnvironment, HiofuEvent, type HiofuNormalizedApplyResult, HiofuPopupError, HiofuScope, HiofuTokenSet, autoBind, bootstrapFromScriptTag, createApplyClient, hiofuLogoSvg, isAutoBound };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as HiofuClient, a as HiofuScope, b as HiofuApplyResult, c as HiofuConfig, d as HiofuEvent, e as HiofuApplyOptions, f as HiofuTokenSet } from './client-
|
|
2
|
-
export { D as DEFAULT_APPLY_SCOPES, g as DEFAULT_AUTHORIZE_SCOPES, h as HiofuApplyRole, i as HiofuPartner } from './client-
|
|
1
|
+
import { H as HiofuClient, a as HiofuScope, b as HiofuApplyResult, c as HiofuConfig, d as HiofuEvent, e as HiofuApplyOptions, f as HiofuTokenSet } from './client-BTGUPzt9.js';
|
|
2
|
+
export { D as DEFAULT_APPLY_SCOPES, g as DEFAULT_AUTHORIZE_SCOPES, h as HiofuApplyRole, i as HiofuPartner } from './client-BTGUPzt9.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Scan the document for `[data-hiofu-apply]` buttons and wire them up to call
|
|
@@ -33,7 +33,7 @@ declare class HiofuApiError extends Error {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
type HiofuEnvironment = "sandbox" | "production";
|
|
36
|
-
type HiofuApplyErrorCode = "configuration_error" | "environment_mismatch" | "popup_blocked" | "auth_failed" | "consent_required" | "role_mapping_failed" | "submit_failed" | "timeout";
|
|
36
|
+
type HiofuApplyErrorCode = "configuration_error" | "environment_mismatch" | "popup_blocked" | "popup_closed" | "auth_failed" | "consent_required" | "role_mapping_failed" | "submit_failed" | "timeout";
|
|
37
37
|
declare class HiofuApplyError extends Error {
|
|
38
38
|
readonly code: HiofuApplyErrorCode;
|
|
39
39
|
readonly correlationId: string;
|
|
@@ -68,7 +68,7 @@ interface HiofuCreateApplyClientConfig {
|
|
|
68
68
|
apiBase?: string;
|
|
69
69
|
}
|
|
70
70
|
interface HiofuApplyPayload {
|
|
71
|
-
externalEmployerId
|
|
71
|
+
externalEmployerId?: string;
|
|
72
72
|
externalJobId: string;
|
|
73
73
|
role: {
|
|
74
74
|
title: string;
|
|
@@ -117,6 +117,12 @@ declare class HiofuConfigurationError extends Error {
|
|
|
117
117
|
constructor(code: HiofuConfigurationErrorCode, message: string, details?: Record<string, unknown>);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
type HiofuPopupErrorReason = "user_closed" | "timed_out";
|
|
121
|
+
declare class HiofuPopupError extends Error {
|
|
122
|
+
readonly reason: HiofuPopupErrorReason;
|
|
123
|
+
constructor(reason: HiofuPopupErrorReason, message: string);
|
|
124
|
+
}
|
|
125
|
+
|
|
120
126
|
/**
|
|
121
127
|
* @fileoverview Hiofu brand assets exposed for partners that want their
|
|
122
128
|
* "Apply with Hiofu" button to match the canonical look. All values here are
|
|
@@ -155,4 +161,4 @@ declare const Hiofu: {
|
|
|
155
161
|
logout(): Promise<void>;
|
|
156
162
|
};
|
|
157
163
|
|
|
158
|
-
export { HIOFU_BRAND_COLOR, HIOFU_BRAND_SOFT, HIOFU_BUTTON_LABEL, HIOFU_FONT_FAMILY, HIOFU_FONT_URL, HIOFU_TAGLINE, HIOFU_WORDMARK, Hiofu, HiofuApiError, type HiofuApplyClient, HiofuApplyError, type HiofuApplyErrorCode, HiofuApplyOptions, type HiofuApplyPayload, HiofuApplyResult, type HiofuCancelContext, HiofuClient, HiofuConfig, HiofuConfigurationError, type HiofuCreateApplyClientConfig, type HiofuEnvironment, HiofuEvent, type HiofuNormalizedApplyResult, HiofuScope, HiofuTokenSet, autoBind, bootstrapFromScriptTag, createApplyClient, hiofuLogoSvg, isAutoBound };
|
|
164
|
+
export { HIOFU_BRAND_COLOR, HIOFU_BRAND_SOFT, HIOFU_BUTTON_LABEL, HIOFU_FONT_FAMILY, HIOFU_FONT_URL, HIOFU_TAGLINE, HIOFU_WORDMARK, Hiofu, HiofuApiError, type HiofuApplyClient, HiofuApplyError, type HiofuApplyErrorCode, HiofuApplyOptions, type HiofuApplyPayload, HiofuApplyResult, type HiofuCancelContext, HiofuClient, HiofuConfig, HiofuConfigurationError, type HiofuCreateApplyClientConfig, type HiofuEnvironment, HiofuEvent, type HiofuNormalizedApplyResult, HiofuPopupError, HiofuScope, HiofuTokenSet, autoBind, bootstrapFromScriptTag, createApplyClient, hiofuLogoSvg, isAutoBound };
|