@authon/js 0.2.1 → 0.3.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/README.ko.md +190 -0
- package/README.md +408 -51
- package/dist/index.cjs +778 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -2
- package/dist/index.d.ts +78 -2
- package/dist/index.js +776 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var AuthonMfaRequiredError = class extends Error {
|
|
3
|
+
mfaToken;
|
|
4
|
+
constructor(mfaToken) {
|
|
5
|
+
super("MFA verification required");
|
|
6
|
+
this.name = "AuthonMfaRequiredError";
|
|
7
|
+
this.mfaToken = mfaToken;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
1
11
|
// src/modal.ts
|
|
2
12
|
import { DEFAULT_BRANDING } from "@authon/shared";
|
|
3
13
|
|
|
@@ -470,6 +480,9 @@ var SessionManager = class {
|
|
|
470
480
|
this.scheduleRefresh(tokens.expiresIn);
|
|
471
481
|
}
|
|
472
482
|
}
|
|
483
|
+
updateUser(user) {
|
|
484
|
+
this.user = user;
|
|
485
|
+
}
|
|
473
486
|
clearSession() {
|
|
474
487
|
this.accessToken = null;
|
|
475
488
|
this.refreshToken = null;
|
|
@@ -531,6 +544,404 @@ var SessionManager = class {
|
|
|
531
544
|
}
|
|
532
545
|
};
|
|
533
546
|
|
|
547
|
+
// src/qrcode.ts
|
|
548
|
+
var EXP = [];
|
|
549
|
+
var LOG = new Array(256).fill(0);
|
|
550
|
+
(() => {
|
|
551
|
+
let v = 1;
|
|
552
|
+
for (let i = 0; i < 255; i++) {
|
|
553
|
+
EXP[i] = v;
|
|
554
|
+
LOG[v] = i;
|
|
555
|
+
v <<= 1;
|
|
556
|
+
if (v & 256) v ^= 285;
|
|
557
|
+
}
|
|
558
|
+
for (let i = 255; i < 512; i++) EXP[i] = EXP[i - 255];
|
|
559
|
+
})();
|
|
560
|
+
var gfMul = (a, b) => a && b ? EXP[LOG[a] + LOG[b]] : 0;
|
|
561
|
+
function rsEncode(data, ecLen) {
|
|
562
|
+
let g = [1];
|
|
563
|
+
for (let i = 0; i < ecLen; i++) {
|
|
564
|
+
const ng = new Array(g.length + 1).fill(0);
|
|
565
|
+
for (let j = 0; j < g.length; j++) {
|
|
566
|
+
ng[j] ^= gfMul(g[j], EXP[i]);
|
|
567
|
+
ng[j + 1] ^= g[j];
|
|
568
|
+
}
|
|
569
|
+
g = ng;
|
|
570
|
+
}
|
|
571
|
+
const rem = new Array(ecLen).fill(0);
|
|
572
|
+
for (const d of data) {
|
|
573
|
+
const fb = d ^ rem[0];
|
|
574
|
+
for (let j = 0; j < ecLen - 1; j++) {
|
|
575
|
+
rem[j] = rem[j + 1] ^ gfMul(g[ecLen - 1 - j], fb);
|
|
576
|
+
}
|
|
577
|
+
rem[ecLen - 1] = gfMul(g[0], fb);
|
|
578
|
+
}
|
|
579
|
+
return rem;
|
|
580
|
+
}
|
|
581
|
+
var VER = [
|
|
582
|
+
{ total: 0, ec: 0, g1: 0, g1d: 0, g2: 0, g2d: 0, align: [] },
|
|
583
|
+
// dummy
|
|
584
|
+
{ total: 26, ec: 7, g1: 1, g1d: 19, g2: 0, g2d: 0, align: [] },
|
|
585
|
+
{ total: 44, ec: 10, g1: 1, g1d: 34, g2: 0, g2d: 0, align: [6, 18] },
|
|
586
|
+
{ total: 70, ec: 15, g1: 1, g1d: 55, g2: 0, g2d: 0, align: [6, 22] },
|
|
587
|
+
{ total: 100, ec: 20, g1: 1, g1d: 80, g2: 0, g2d: 0, align: [6, 26] },
|
|
588
|
+
{ total: 134, ec: 26, g1: 1, g1d: 108, g2: 0, g2d: 0, align: [6, 30] },
|
|
589
|
+
{ total: 172, ec: 18, g1: 2, g1d: 68, g2: 0, g2d: 0, align: [6, 34] },
|
|
590
|
+
{ total: 196, ec: 20, g1: 2, g1d: 78, g2: 0, g2d: 0, align: [6, 22, 38] },
|
|
591
|
+
{ total: 242, ec: 24, g1: 2, g1d: 97, g2: 0, g2d: 0, align: [6, 24, 42] },
|
|
592
|
+
{ total: 292, ec: 30, g1: 2, g1d: 116, g2: 0, g2d: 0, align: [6, 26, 46] },
|
|
593
|
+
{ total: 346, ec: 18, g1: 2, g1d: 68, g2: 2, g2d: 69, align: [6, 28, 50] },
|
|
594
|
+
{ total: 404, ec: 20, g1: 4, g1d: 81, g2: 0, g2d: 0, align: [6, 30, 54] },
|
|
595
|
+
{ total: 466, ec: 24, g1: 2, g1d: 92, g2: 2, g2d: 93, align: [6, 32, 58] },
|
|
596
|
+
{ total: 532, ec: 26, g1: 4, g1d: 107, g2: 0, g2d: 0, align: [6, 34, 62] }
|
|
597
|
+
];
|
|
598
|
+
function dataCapacity(ver) {
|
|
599
|
+
const v = VER[ver];
|
|
600
|
+
return v.g1 * v.g1d + v.g2 * v.g2d;
|
|
601
|
+
}
|
|
602
|
+
function pickVersion(byteLen) {
|
|
603
|
+
for (let v = 1; v < VER.length; v++) {
|
|
604
|
+
const headerBits = 4 + (v <= 9 ? 8 : 16);
|
|
605
|
+
const available = dataCapacity(v) * 8 - headerBits;
|
|
606
|
+
if (byteLen * 8 <= available) return v;
|
|
607
|
+
}
|
|
608
|
+
throw new Error(`Data too long for QR code (${byteLen} bytes)`);
|
|
609
|
+
}
|
|
610
|
+
function encodeData(bytes, ver) {
|
|
611
|
+
const cap = dataCapacity(ver);
|
|
612
|
+
const countBits = ver <= 9 ? 8 : 16;
|
|
613
|
+
const bits = [];
|
|
614
|
+
const push = (val, len) => {
|
|
615
|
+
for (let i = len - 1; i >= 0; i--) bits.push(val >> i & 1);
|
|
616
|
+
};
|
|
617
|
+
push(4, 4);
|
|
618
|
+
push(bytes.length, countBits);
|
|
619
|
+
for (const b of bytes) push(b, 8);
|
|
620
|
+
push(0, Math.min(4, cap * 8 - bits.length));
|
|
621
|
+
while (bits.length % 8) bits.push(0);
|
|
622
|
+
const padBytes = [236, 17];
|
|
623
|
+
let pi = 0;
|
|
624
|
+
while (bits.length < cap * 8) {
|
|
625
|
+
push(padBytes[pi], 8);
|
|
626
|
+
pi ^= 1;
|
|
627
|
+
}
|
|
628
|
+
const cw = [];
|
|
629
|
+
for (let i = 0; i < bits.length; i += 8) {
|
|
630
|
+
let byte = 0;
|
|
631
|
+
for (let j = 0; j < 8; j++) byte = byte << 1 | bits[i + j];
|
|
632
|
+
cw.push(byte);
|
|
633
|
+
}
|
|
634
|
+
return cw;
|
|
635
|
+
}
|
|
636
|
+
function computeCodewords(ver, dataCW) {
|
|
637
|
+
const v = VER[ver];
|
|
638
|
+
const blocks = [];
|
|
639
|
+
const ecBlocks = [];
|
|
640
|
+
let offset = 0;
|
|
641
|
+
for (let i = 0; i < v.g1; i++) {
|
|
642
|
+
const block = dataCW.slice(offset, offset + v.g1d);
|
|
643
|
+
blocks.push(block);
|
|
644
|
+
ecBlocks.push(rsEncode(block, v.ec));
|
|
645
|
+
offset += v.g1d;
|
|
646
|
+
}
|
|
647
|
+
for (let i = 0; i < v.g2; i++) {
|
|
648
|
+
const block = dataCW.slice(offset, offset + v.g2d);
|
|
649
|
+
blocks.push(block);
|
|
650
|
+
ecBlocks.push(rsEncode(block, v.ec));
|
|
651
|
+
offset += v.g2d;
|
|
652
|
+
}
|
|
653
|
+
const result = [];
|
|
654
|
+
const maxDataLen = Math.max(v.g1d, v.g2d || 0);
|
|
655
|
+
for (let i = 0; i < maxDataLen; i++) {
|
|
656
|
+
for (const block of blocks) {
|
|
657
|
+
if (i < block.length) result.push(block[i]);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
for (let i = 0; i < v.ec; i++) {
|
|
661
|
+
for (const block of ecBlocks) result.push(block[i]);
|
|
662
|
+
}
|
|
663
|
+
return result;
|
|
664
|
+
}
|
|
665
|
+
var UNSET = -1;
|
|
666
|
+
var DARK = 1;
|
|
667
|
+
var LIGHT = 0;
|
|
668
|
+
function createMatrix(size) {
|
|
669
|
+
return Array.from({ length: size }, () => new Array(size).fill(UNSET));
|
|
670
|
+
}
|
|
671
|
+
function setModule(m, r, c, dark) {
|
|
672
|
+
if (r >= 0 && r < m.length && c >= 0 && c < m.length) m[r][c] = dark ? DARK : LIGHT;
|
|
673
|
+
}
|
|
674
|
+
function placeFinderPattern(m, row, col) {
|
|
675
|
+
for (let r = -1; r <= 7; r++) {
|
|
676
|
+
for (let c = -1; c <= 7; c++) {
|
|
677
|
+
const dark = r >= 0 && r <= 6 && c >= 0 && c <= 6 && (r === 0 || r === 6 || c === 0 || c === 6 || r >= 2 && r <= 4 && c >= 2 && c <= 4);
|
|
678
|
+
setModule(m, row + r, col + c, dark);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
function placeAlignmentPattern(m, row, col) {
|
|
683
|
+
for (let r = -2; r <= 2; r++) {
|
|
684
|
+
for (let c = -2; c <= 2; c++) {
|
|
685
|
+
const dark = Math.abs(r) === 2 || Math.abs(c) === 2 || r === 0 && c === 0;
|
|
686
|
+
m[row + r][col + c] = dark ? DARK : LIGHT;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
function isReserved(m, r, c) {
|
|
691
|
+
return m[r][c] !== UNSET;
|
|
692
|
+
}
|
|
693
|
+
function buildMatrix(ver, codewords) {
|
|
694
|
+
const size = ver * 4 + 17;
|
|
695
|
+
const m = createMatrix(size);
|
|
696
|
+
placeFinderPattern(m, 0, 0);
|
|
697
|
+
placeFinderPattern(m, 0, size - 7);
|
|
698
|
+
placeFinderPattern(m, size - 7, 0);
|
|
699
|
+
for (let i = 8; i < size - 8; i++) {
|
|
700
|
+
m[6][i] = i % 2 === 0 ? DARK : LIGHT;
|
|
701
|
+
m[i][6] = i % 2 === 0 ? DARK : LIGHT;
|
|
702
|
+
}
|
|
703
|
+
const ap = VER[ver].align;
|
|
704
|
+
if (ap.length > 0) {
|
|
705
|
+
for (const r of ap) {
|
|
706
|
+
for (const c of ap) {
|
|
707
|
+
if (r <= 8 && c <= 8) continue;
|
|
708
|
+
if (r <= 8 && c >= size - 8) continue;
|
|
709
|
+
if (r >= size - 8 && c <= 8) continue;
|
|
710
|
+
placeAlignmentPattern(m, r, c);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
m[4 * ver + 9][8] = DARK;
|
|
715
|
+
for (let i = 0; i < 9; i++) {
|
|
716
|
+
if (m[8][i] === UNSET) m[8][i] = LIGHT;
|
|
717
|
+
if (m[i][8] === UNSET) m[i][8] = LIGHT;
|
|
718
|
+
}
|
|
719
|
+
for (let i = 0; i < 8; i++) {
|
|
720
|
+
if (m[8][size - 1 - i] === UNSET) m[8][size - 1 - i] = LIGHT;
|
|
721
|
+
if (m[size - 1 - i][8] === UNSET) m[size - 1 - i][8] = LIGHT;
|
|
722
|
+
}
|
|
723
|
+
if (ver >= 7) {
|
|
724
|
+
for (let i = 0; i < 6; i++) {
|
|
725
|
+
for (let j = 0; j < 3; j++) {
|
|
726
|
+
m[i][size - 11 + j] = LIGHT;
|
|
727
|
+
m[size - 11 + j][i] = LIGHT;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
let bitIdx = 0;
|
|
732
|
+
const totalBits = codewords.length * 8;
|
|
733
|
+
let upward = true;
|
|
734
|
+
for (let right = size - 1; right >= 0; right -= 2) {
|
|
735
|
+
if (right === 6) right = 5;
|
|
736
|
+
for (let i = 0; i < size; i++) {
|
|
737
|
+
const row = upward ? size - 1 - i : i;
|
|
738
|
+
for (const dc of [0, -1]) {
|
|
739
|
+
const col = right + dc;
|
|
740
|
+
if (col < 0 || col >= size) continue;
|
|
741
|
+
if (isReserved(m, row, col)) continue;
|
|
742
|
+
if (bitIdx < totalBits) {
|
|
743
|
+
const byteIdx = bitIdx >> 3;
|
|
744
|
+
const bitPos = 7 - (bitIdx & 7);
|
|
745
|
+
m[row][col] = codewords[byteIdx] >> bitPos & 1;
|
|
746
|
+
bitIdx++;
|
|
747
|
+
} else {
|
|
748
|
+
m[row][col] = LIGHT;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
upward = !upward;
|
|
753
|
+
}
|
|
754
|
+
return m;
|
|
755
|
+
}
|
|
756
|
+
var MASKS = [
|
|
757
|
+
(r, c) => (r + c) % 2 === 0,
|
|
758
|
+
(r) => r % 2 === 0,
|
|
759
|
+
(_, c) => c % 3 === 0,
|
|
760
|
+
(r, c) => (r + c) % 3 === 0,
|
|
761
|
+
(r, c) => (Math.floor(r / 2) + Math.floor(c / 3)) % 2 === 0,
|
|
762
|
+
(r, c) => r * c % 2 + r * c % 3 === 0,
|
|
763
|
+
(r, c) => (r * c % 2 + r * c % 3) % 2 === 0,
|
|
764
|
+
(r, c) => ((r + c) % 2 + r * c % 3) % 2 === 0
|
|
765
|
+
];
|
|
766
|
+
function applyMask(m, maskIdx, template) {
|
|
767
|
+
const size = m.length;
|
|
768
|
+
const result = m.map((row) => [...row]);
|
|
769
|
+
const fn = MASKS[maskIdx];
|
|
770
|
+
for (let r = 0; r < size; r++) {
|
|
771
|
+
for (let c = 0; c < size; c++) {
|
|
772
|
+
if (template[r][c] !== UNSET) continue;
|
|
773
|
+
if (fn(r, c)) result[r][c] ^= 1;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
return result;
|
|
777
|
+
}
|
|
778
|
+
function penalty(m) {
|
|
779
|
+
const size = m.length;
|
|
780
|
+
let score = 0;
|
|
781
|
+
for (let r = 0; r < size; r++) {
|
|
782
|
+
let count = 1;
|
|
783
|
+
for (let c = 1; c < size; c++) {
|
|
784
|
+
if (m[r][c] === m[r][c - 1]) {
|
|
785
|
+
count++;
|
|
786
|
+
} else {
|
|
787
|
+
if (count >= 5) score += count - 2;
|
|
788
|
+
count = 1;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
if (count >= 5) score += count - 2;
|
|
792
|
+
}
|
|
793
|
+
for (let c = 0; c < size; c++) {
|
|
794
|
+
let count = 1;
|
|
795
|
+
for (let r = 1; r < size; r++) {
|
|
796
|
+
if (m[r][c] === m[r - 1][c]) {
|
|
797
|
+
count++;
|
|
798
|
+
} else {
|
|
799
|
+
if (count >= 5) score += count - 2;
|
|
800
|
+
count = 1;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
if (count >= 5) score += count - 2;
|
|
804
|
+
}
|
|
805
|
+
for (let r = 0; r < size - 1; r++) {
|
|
806
|
+
for (let c = 0; c < size - 1; c++) {
|
|
807
|
+
const v = m[r][c];
|
|
808
|
+
if (v === m[r][c + 1] && v === m[r + 1][c] && v === m[r + 1][c + 1]) score += 3;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
const pat1 = [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0];
|
|
812
|
+
const pat2 = [0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1];
|
|
813
|
+
for (let r = 0; r < size; r++) {
|
|
814
|
+
for (let c = 0; c <= size - 11; c++) {
|
|
815
|
+
let match1 = true, match2 = true;
|
|
816
|
+
for (let k = 0; k < 11; k++) {
|
|
817
|
+
if (m[r][c + k] !== pat1[k]) match1 = false;
|
|
818
|
+
if (m[r][c + k] !== pat2[k]) match2 = false;
|
|
819
|
+
}
|
|
820
|
+
if (match1 || match2) score += 40;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
for (let c = 0; c < size; c++) {
|
|
824
|
+
for (let r = 0; r <= size - 11; r++) {
|
|
825
|
+
let match1 = true, match2 = true;
|
|
826
|
+
for (let k = 0; k < 11; k++) {
|
|
827
|
+
if (m[r + k][c] !== pat1[k]) match1 = false;
|
|
828
|
+
if (m[r + k][c] !== pat2[k]) match2 = false;
|
|
829
|
+
}
|
|
830
|
+
if (match1 || match2) score += 40;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
let dark = 0;
|
|
834
|
+
for (let r = 0; r < size; r++) for (let c = 0; c < size; c++) if (m[r][c]) dark++;
|
|
835
|
+
const pct = dark * 100 / (size * size);
|
|
836
|
+
const prev5 = Math.floor(pct / 5) * 5;
|
|
837
|
+
const next5 = prev5 + 5;
|
|
838
|
+
score += Math.min(Math.abs(prev5 - 50) / 5, Math.abs(next5 - 50) / 5) * 10;
|
|
839
|
+
return score;
|
|
840
|
+
}
|
|
841
|
+
function bchEncode(data, gen, dataBits) {
|
|
842
|
+
let d = data << 15 - dataBits;
|
|
843
|
+
const genLen = Math.floor(Math.log2(gen)) + 1;
|
|
844
|
+
const totalBits = dataBits + (genLen - 1);
|
|
845
|
+
d = data << totalBits - dataBits;
|
|
846
|
+
for (let i = dataBits - 1; i >= 0; i--) {
|
|
847
|
+
if (d & 1 << i + genLen - 1) d ^= gen << i;
|
|
848
|
+
}
|
|
849
|
+
return data << genLen - 1 | d;
|
|
850
|
+
}
|
|
851
|
+
function placeFormatInfo(m, maskIdx) {
|
|
852
|
+
const size = m.length;
|
|
853
|
+
const data = 1 << 3 | maskIdx;
|
|
854
|
+
let format = bchEncode(data, 1335, 5);
|
|
855
|
+
format ^= 21522;
|
|
856
|
+
const bits = [];
|
|
857
|
+
for (let i = 14; i >= 0; i--) bits.push(format >> i & 1);
|
|
858
|
+
const hPos = [0, 1, 2, 3, 4, 5, 7, 8, size - 8, size - 7, size - 6, size - 5, size - 4, size - 3, size - 2];
|
|
859
|
+
for (let i = 0; i < 15; i++) m[8][hPos[i]] = bits[i];
|
|
860
|
+
const vPos = [size - 1, size - 2, size - 3, size - 4, size - 5, size - 6, size - 7, size - 8, 7, 5, 4, 3, 2, 1, 0];
|
|
861
|
+
for (let i = 0; i < 15; i++) m[vPos[i]][8] = bits[i];
|
|
862
|
+
}
|
|
863
|
+
function placeVersionInfo(m, ver) {
|
|
864
|
+
if (ver < 7) return;
|
|
865
|
+
const size = m.length;
|
|
866
|
+
let info = bchEncode(ver, 7973, 6);
|
|
867
|
+
for (let i = 0; i < 18; i++) {
|
|
868
|
+
const bit = info >> i & 1;
|
|
869
|
+
const r = Math.floor(i / 3);
|
|
870
|
+
const c = size - 11 + i % 3;
|
|
871
|
+
m[r][c] = bit;
|
|
872
|
+
m[c][r] = bit;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
function generateQrSvg(text, moduleSize = 4) {
|
|
876
|
+
const bytes = Array.from(new TextEncoder().encode(text));
|
|
877
|
+
const ver = pickVersion(bytes.length);
|
|
878
|
+
const dataCW = encodeData(bytes, ver);
|
|
879
|
+
const allCW = computeCodewords(ver, dataCW);
|
|
880
|
+
const size = ver * 4 + 17;
|
|
881
|
+
const template = createMatrix(size);
|
|
882
|
+
placeFinderPattern(template, 0, 0);
|
|
883
|
+
placeFinderPattern(template, 0, size - 7);
|
|
884
|
+
placeFinderPattern(template, size - 7, 0);
|
|
885
|
+
for (let i = 8; i < size - 8; i++) {
|
|
886
|
+
template[6][i] = LIGHT;
|
|
887
|
+
template[i][6] = LIGHT;
|
|
888
|
+
}
|
|
889
|
+
const ap = VER[ver].align;
|
|
890
|
+
for (const r of ap) {
|
|
891
|
+
for (const c of ap) {
|
|
892
|
+
if (r <= 8 && c <= 8) continue;
|
|
893
|
+
if (r <= 8 && c >= size - 8) continue;
|
|
894
|
+
if (r >= size - 8 && c <= 8) continue;
|
|
895
|
+
for (let dr = -2; dr <= 2; dr++) for (let dc = -2; dc <= 2; dc++) template[r + dr][c + dc] = LIGHT;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
template[4 * ver + 9][8] = LIGHT;
|
|
899
|
+
for (let i = 0; i < 9; i++) {
|
|
900
|
+
if (template[8][i] === UNSET) template[8][i] = LIGHT;
|
|
901
|
+
if (template[i][8] === UNSET) template[i][8] = LIGHT;
|
|
902
|
+
}
|
|
903
|
+
for (let i = 0; i < 8; i++) {
|
|
904
|
+
if (template[8][size - 1 - i] === UNSET) template[8][size - 1 - i] = LIGHT;
|
|
905
|
+
if (template[size - 1 - i][8] === UNSET) template[size - 1 - i][8] = LIGHT;
|
|
906
|
+
}
|
|
907
|
+
if (ver >= 7) {
|
|
908
|
+
for (let i = 0; i < 6; i++) for (let j = 0; j < 3; j++) {
|
|
909
|
+
template[i][size - 11 + j] = LIGHT;
|
|
910
|
+
template[size - 11 + j][i] = LIGHT;
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
const base = buildMatrix(ver, allCW);
|
|
914
|
+
let bestMask = 0;
|
|
915
|
+
let bestScore = Infinity;
|
|
916
|
+
for (let mask = 0; mask < 8; mask++) {
|
|
917
|
+
const masked = applyMask(base, mask, template);
|
|
918
|
+
placeFormatInfo(masked, mask);
|
|
919
|
+
placeVersionInfo(masked, ver);
|
|
920
|
+
const s = penalty(masked);
|
|
921
|
+
if (s < bestScore) {
|
|
922
|
+
bestScore = s;
|
|
923
|
+
bestMask = mask;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
const final = applyMask(base, bestMask, template);
|
|
927
|
+
placeFormatInfo(final, bestMask);
|
|
928
|
+
placeVersionInfo(final, ver);
|
|
929
|
+
const quiet = 4;
|
|
930
|
+
const total = size + quiet * 2;
|
|
931
|
+
const px = total * moduleSize;
|
|
932
|
+
let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${total} ${total}" width="${px}" height="${px}" shape-rendering="crispEdges">`;
|
|
933
|
+
svg += `<rect width="${total}" height="${total}" fill="#fff"/>`;
|
|
934
|
+
for (let r = 0; r < size; r++) {
|
|
935
|
+
for (let c = 0; c < size; c++) {
|
|
936
|
+
if (final[r][c] === DARK) {
|
|
937
|
+
svg += `<rect x="${c + quiet}" y="${r + quiet}" width="1" height="1" fill="#000"/>`;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
svg += "</svg>";
|
|
942
|
+
return svg;
|
|
943
|
+
}
|
|
944
|
+
|
|
534
945
|
// src/authon.ts
|
|
535
946
|
var Authon = class {
|
|
536
947
|
publishableKey;
|
|
@@ -573,10 +984,17 @@ var Authon = class {
|
|
|
573
984
|
await this.startOAuthFlow(provider, options);
|
|
574
985
|
}
|
|
575
986
|
async signInWithEmail(email, password) {
|
|
576
|
-
const
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
987
|
+
const res = await this.apiPost(
|
|
988
|
+
"/v1/auth/signin",
|
|
989
|
+
{ email, password }
|
|
990
|
+
);
|
|
991
|
+
if (res.mfaRequired && res.mfaToken) {
|
|
992
|
+
this.emit("mfaRequired", res.mfaToken);
|
|
993
|
+
throw new AuthonMfaRequiredError(res.mfaToken);
|
|
994
|
+
}
|
|
995
|
+
this.session.setSession(res);
|
|
996
|
+
this.emit("signedIn", res.user);
|
|
997
|
+
return res.user;
|
|
580
998
|
}
|
|
581
999
|
async signUpWithEmail(email, password, meta) {
|
|
582
1000
|
const tokens = await this.apiPost("/v1/auth/signup", {
|
|
@@ -604,6 +1022,258 @@ var Authon = class {
|
|
|
604
1022
|
set.add(listener);
|
|
605
1023
|
return () => set.delete(listener);
|
|
606
1024
|
}
|
|
1025
|
+
// ── MFA ──
|
|
1026
|
+
async setupMfa() {
|
|
1027
|
+
const token = this.session.getToken();
|
|
1028
|
+
if (!token) throw new Error("Must be signed in to setup MFA");
|
|
1029
|
+
const res = await this.apiPostAuth("/v1/auth/mfa/totp/setup", void 0, token);
|
|
1030
|
+
return { ...res, qrCodeSvg: generateQrSvg(res.qrCodeUri) };
|
|
1031
|
+
}
|
|
1032
|
+
async verifyMfaSetup(code) {
|
|
1033
|
+
const token = this.session.getToken();
|
|
1034
|
+
if (!token) throw new Error("Must be signed in to verify MFA setup");
|
|
1035
|
+
await this.apiPostAuth("/v1/auth/mfa/totp/verify-setup", { code }, token);
|
|
1036
|
+
}
|
|
1037
|
+
async verifyMfa(mfaToken, code) {
|
|
1038
|
+
const res = await this.apiPost("/v1/auth/mfa/verify", { mfaToken, code });
|
|
1039
|
+
this.session.setSession(res);
|
|
1040
|
+
this.emit("signedIn", res.user);
|
|
1041
|
+
return res.user;
|
|
1042
|
+
}
|
|
1043
|
+
async disableMfa(code) {
|
|
1044
|
+
const token = this.session.getToken();
|
|
1045
|
+
if (!token) throw new Error("Must be signed in to disable MFA");
|
|
1046
|
+
await this.apiPostAuth("/v1/auth/mfa/disable", { code }, token);
|
|
1047
|
+
}
|
|
1048
|
+
async getMfaStatus() {
|
|
1049
|
+
const token = this.session.getToken();
|
|
1050
|
+
if (!token) throw new Error("Must be signed in to get MFA status");
|
|
1051
|
+
const res = await fetch(`${this.config.apiUrl}/v1/auth/mfa/status`, {
|
|
1052
|
+
headers: {
|
|
1053
|
+
"x-api-key": this.publishableKey,
|
|
1054
|
+
Authorization: `Bearer ${token}`
|
|
1055
|
+
},
|
|
1056
|
+
credentials: "include"
|
|
1057
|
+
});
|
|
1058
|
+
if (!res.ok) throw new Error(await this.parseApiError(res, "/v1/auth/mfa/status"));
|
|
1059
|
+
return res.json();
|
|
1060
|
+
}
|
|
1061
|
+
async regenerateBackupCodes(code) {
|
|
1062
|
+
const token = this.session.getToken();
|
|
1063
|
+
if (!token) throw new Error("Must be signed in to regenerate backup codes");
|
|
1064
|
+
const res = await this.apiPostAuth(
|
|
1065
|
+
"/v1/auth/mfa/backup-codes/regenerate",
|
|
1066
|
+
{ code },
|
|
1067
|
+
token
|
|
1068
|
+
);
|
|
1069
|
+
return res.backupCodes;
|
|
1070
|
+
}
|
|
1071
|
+
// ── Passwordless ──
|
|
1072
|
+
async sendMagicLink(email) {
|
|
1073
|
+
await this.apiPost("/v1/auth/passwordless/magic-link", { email });
|
|
1074
|
+
}
|
|
1075
|
+
async sendEmailOtp(email) {
|
|
1076
|
+
await this.apiPost("/v1/auth/passwordless/email-otp", { email });
|
|
1077
|
+
}
|
|
1078
|
+
async verifyPasswordless(options) {
|
|
1079
|
+
const res = await this.apiPost("/v1/auth/passwordless/verify", options);
|
|
1080
|
+
this.session.setSession(res);
|
|
1081
|
+
this.emit("signedIn", res.user);
|
|
1082
|
+
return res.user;
|
|
1083
|
+
}
|
|
1084
|
+
// ── Passkeys ──
|
|
1085
|
+
async registerPasskey(name) {
|
|
1086
|
+
const token = this.session.getToken();
|
|
1087
|
+
if (!token) throw new Error("Must be signed in to register a passkey");
|
|
1088
|
+
const options = await this.apiPostAuth(
|
|
1089
|
+
"/v1/auth/passkeys/register/options",
|
|
1090
|
+
name ? { name } : void 0,
|
|
1091
|
+
token
|
|
1092
|
+
);
|
|
1093
|
+
const credential = await navigator.credentials.create({
|
|
1094
|
+
publicKey: this.deserializeCreationOptions(options.options)
|
|
1095
|
+
});
|
|
1096
|
+
const attestation = credential.response;
|
|
1097
|
+
const result = await this.apiPostAuth(
|
|
1098
|
+
"/v1/auth/passkeys/register/verify",
|
|
1099
|
+
{
|
|
1100
|
+
id: credential.id,
|
|
1101
|
+
rawId: this.bufferToBase64url(credential.rawId),
|
|
1102
|
+
type: credential.type,
|
|
1103
|
+
response: {
|
|
1104
|
+
attestationObject: this.bufferToBase64url(attestation.attestationObject),
|
|
1105
|
+
clientDataJSON: this.bufferToBase64url(attestation.clientDataJSON)
|
|
1106
|
+
}
|
|
1107
|
+
},
|
|
1108
|
+
token
|
|
1109
|
+
);
|
|
1110
|
+
this.emit("passkeyRegistered", result);
|
|
1111
|
+
return result;
|
|
1112
|
+
}
|
|
1113
|
+
async authenticateWithPasskey(email) {
|
|
1114
|
+
const options = await this.apiPost(
|
|
1115
|
+
"/v1/auth/passkeys/authenticate/options",
|
|
1116
|
+
email ? { email } : void 0
|
|
1117
|
+
);
|
|
1118
|
+
const credential = await navigator.credentials.get({
|
|
1119
|
+
publicKey: this.deserializeRequestOptions(options.options)
|
|
1120
|
+
});
|
|
1121
|
+
const assertion = credential.response;
|
|
1122
|
+
const res = await this.apiPost("/v1/auth/passkeys/authenticate/verify", {
|
|
1123
|
+
id: credential.id,
|
|
1124
|
+
rawId: this.bufferToBase64url(credential.rawId),
|
|
1125
|
+
type: credential.type,
|
|
1126
|
+
response: {
|
|
1127
|
+
authenticatorData: this.bufferToBase64url(assertion.authenticatorData),
|
|
1128
|
+
clientDataJSON: this.bufferToBase64url(assertion.clientDataJSON),
|
|
1129
|
+
signature: this.bufferToBase64url(assertion.signature),
|
|
1130
|
+
userHandle: assertion.userHandle ? this.bufferToBase64url(assertion.userHandle) : void 0
|
|
1131
|
+
}
|
|
1132
|
+
});
|
|
1133
|
+
this.session.setSession(res);
|
|
1134
|
+
this.emit("signedIn", res.user);
|
|
1135
|
+
return res.user;
|
|
1136
|
+
}
|
|
1137
|
+
async listPasskeys() {
|
|
1138
|
+
const token = this.session.getToken();
|
|
1139
|
+
if (!token) throw new Error("Must be signed in to list passkeys");
|
|
1140
|
+
return this.apiGetAuth("/v1/auth/passkeys", token);
|
|
1141
|
+
}
|
|
1142
|
+
async renamePasskey(passkeyId, name) {
|
|
1143
|
+
const token = this.session.getToken();
|
|
1144
|
+
if (!token) throw new Error("Must be signed in to rename a passkey");
|
|
1145
|
+
return this.apiPatchAuth(`/v1/auth/passkeys/${passkeyId}`, { name }, token);
|
|
1146
|
+
}
|
|
1147
|
+
async revokePasskey(passkeyId) {
|
|
1148
|
+
const token = this.session.getToken();
|
|
1149
|
+
if (!token) throw new Error("Must be signed in to revoke a passkey");
|
|
1150
|
+
await this.apiDeleteAuth(`/v1/auth/passkeys/${passkeyId}`, token);
|
|
1151
|
+
}
|
|
1152
|
+
// ── Web3 ──
|
|
1153
|
+
async web3GetNonce(address, chain, walletType, chainId) {
|
|
1154
|
+
return this.apiPost("/v1/auth/web3/nonce", {
|
|
1155
|
+
address,
|
|
1156
|
+
chain,
|
|
1157
|
+
walletType,
|
|
1158
|
+
...chainId != null ? { chainId } : {}
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
async web3Verify(message, signature, address, chain, walletType) {
|
|
1162
|
+
const res = await this.apiPost("/v1/auth/web3/verify", {
|
|
1163
|
+
message,
|
|
1164
|
+
signature,
|
|
1165
|
+
address,
|
|
1166
|
+
chain,
|
|
1167
|
+
walletType
|
|
1168
|
+
});
|
|
1169
|
+
this.session.setSession(res);
|
|
1170
|
+
this.emit("signedIn", res.user);
|
|
1171
|
+
return res.user;
|
|
1172
|
+
}
|
|
1173
|
+
async listWallets() {
|
|
1174
|
+
const token = this.session.getToken();
|
|
1175
|
+
if (!token) throw new Error("Must be signed in to list wallets");
|
|
1176
|
+
return this.apiGetAuth("/v1/auth/web3/wallets", token);
|
|
1177
|
+
}
|
|
1178
|
+
async linkWallet(params) {
|
|
1179
|
+
const token = this.session.getToken();
|
|
1180
|
+
if (!token) throw new Error("Must be signed in to link a wallet");
|
|
1181
|
+
const wallet = await this.apiPostAuth("/v1/auth/web3/wallets/link", params, token);
|
|
1182
|
+
this.emit("web3Connected", wallet);
|
|
1183
|
+
return wallet;
|
|
1184
|
+
}
|
|
1185
|
+
async unlinkWallet(walletId) {
|
|
1186
|
+
const token = this.session.getToken();
|
|
1187
|
+
if (!token) throw new Error("Must be signed in to unlink a wallet");
|
|
1188
|
+
await this.apiDeleteAuth(`/v1/auth/web3/wallets/${walletId}`, token);
|
|
1189
|
+
}
|
|
1190
|
+
// ── User Profile ──
|
|
1191
|
+
async updateProfile(data) {
|
|
1192
|
+
const token = this.session.getToken();
|
|
1193
|
+
if (!token) throw new Error("Must be signed in to update profile");
|
|
1194
|
+
const user = await this.apiPatchAuth("/v1/auth/me", data, token);
|
|
1195
|
+
this.session.updateUser(user);
|
|
1196
|
+
return user;
|
|
1197
|
+
}
|
|
1198
|
+
// ── Session Management ──
|
|
1199
|
+
async listSessions() {
|
|
1200
|
+
const token = this.session.getToken();
|
|
1201
|
+
if (!token) throw new Error("Must be signed in to list sessions");
|
|
1202
|
+
return this.apiGetAuth("/v1/auth/me/sessions", token);
|
|
1203
|
+
}
|
|
1204
|
+
async revokeSession(sessionId) {
|
|
1205
|
+
const token = this.session.getToken();
|
|
1206
|
+
if (!token) throw new Error("Must be signed in to revoke a session");
|
|
1207
|
+
await this.apiDeleteAuth(`/v1/auth/me/sessions/${sessionId}`, token);
|
|
1208
|
+
}
|
|
1209
|
+
// ── Organizations ──
|
|
1210
|
+
organizations = {
|
|
1211
|
+
list: async () => {
|
|
1212
|
+
const token = this.session.getToken();
|
|
1213
|
+
if (!token) throw new Error("Must be signed in to list organizations");
|
|
1214
|
+
return this.apiGetAuth("/v1/auth/organizations", token);
|
|
1215
|
+
},
|
|
1216
|
+
create: async (params) => {
|
|
1217
|
+
const token = this.session.getToken();
|
|
1218
|
+
if (!token) throw new Error("Must be signed in to create an organization");
|
|
1219
|
+
return this.apiPostAuth("/v1/auth/organizations", params, token);
|
|
1220
|
+
},
|
|
1221
|
+
get: async (orgId) => {
|
|
1222
|
+
const token = this.session.getToken();
|
|
1223
|
+
if (!token) throw new Error("Must be signed in to get organization");
|
|
1224
|
+
return this.apiGetAuth(`/v1/auth/organizations/${orgId}`, token);
|
|
1225
|
+
},
|
|
1226
|
+
update: async (orgId, params) => {
|
|
1227
|
+
const token = this.session.getToken();
|
|
1228
|
+
if (!token) throw new Error("Must be signed in to update organization");
|
|
1229
|
+
return this.apiPatchAuth(`/v1/auth/organizations/${orgId}`, params, token);
|
|
1230
|
+
},
|
|
1231
|
+
delete: async (orgId) => {
|
|
1232
|
+
const token = this.session.getToken();
|
|
1233
|
+
if (!token) throw new Error("Must be signed in to delete organization");
|
|
1234
|
+
await this.apiDeleteAuth(`/v1/auth/organizations/${orgId}`, token);
|
|
1235
|
+
},
|
|
1236
|
+
getMembers: async (orgId) => {
|
|
1237
|
+
const token = this.session.getToken();
|
|
1238
|
+
if (!token) throw new Error("Must be signed in to get organization members");
|
|
1239
|
+
return this.apiGetAuth(`/v1/auth/organizations/${orgId}/members`, token);
|
|
1240
|
+
},
|
|
1241
|
+
invite: async (orgId, params) => {
|
|
1242
|
+
const token = this.session.getToken();
|
|
1243
|
+
if (!token) throw new Error("Must be signed in to invite a member");
|
|
1244
|
+
return this.apiPostAuth(`/v1/auth/organizations/${orgId}/invitations`, params, token);
|
|
1245
|
+
},
|
|
1246
|
+
getInvitations: async (orgId) => {
|
|
1247
|
+
const token = this.session.getToken();
|
|
1248
|
+
if (!token) throw new Error("Must be signed in to get invitations");
|
|
1249
|
+
return this.apiGetAuth(`/v1/auth/organizations/${orgId}/invitations`, token);
|
|
1250
|
+
},
|
|
1251
|
+
acceptInvitation: async (token) => {
|
|
1252
|
+
const authToken = this.session.getToken();
|
|
1253
|
+
if (!authToken) throw new Error("Must be signed in to accept an invitation");
|
|
1254
|
+
return this.apiPostAuth(`/v1/auth/organizations/invitations/${token}/accept`, void 0, authToken);
|
|
1255
|
+
},
|
|
1256
|
+
rejectInvitation: async (token) => {
|
|
1257
|
+
const authToken = this.session.getToken();
|
|
1258
|
+
if (!authToken) throw new Error("Must be signed in to reject an invitation");
|
|
1259
|
+
await this.apiPostAuth(`/v1/auth/organizations/invitations/${token}/reject`, void 0, authToken);
|
|
1260
|
+
},
|
|
1261
|
+
removeMember: async (orgId, memberId) => {
|
|
1262
|
+
const token = this.session.getToken();
|
|
1263
|
+
if (!token) throw new Error("Must be signed in to remove a member");
|
|
1264
|
+
await this.apiDeleteAuth(`/v1/auth/organizations/${orgId}/members/${memberId}`, token);
|
|
1265
|
+
},
|
|
1266
|
+
updateMemberRole: async (orgId, memberId, role) => {
|
|
1267
|
+
const token = this.session.getToken();
|
|
1268
|
+
if (!token) throw new Error("Must be signed in to update member role");
|
|
1269
|
+
return this.apiPatchAuth(`/v1/auth/organizations/${orgId}/members/${memberId}`, { role }, token);
|
|
1270
|
+
},
|
|
1271
|
+
leave: async (orgId) => {
|
|
1272
|
+
const token = this.session.getToken();
|
|
1273
|
+
if (!token) throw new Error("Must be signed in to leave organization");
|
|
1274
|
+
await this.apiPostAuth(`/v1/auth/organizations/${orgId}/leave`, void 0, token);
|
|
1275
|
+
}
|
|
1276
|
+
};
|
|
607
1277
|
destroy() {
|
|
608
1278
|
this.modal?.close();
|
|
609
1279
|
this.session.destroy();
|
|
@@ -894,6 +1564,106 @@ var Authon = class {
|
|
|
894
1564
|
if (!res.ok) throw new Error(await this.parseApiError(res, path));
|
|
895
1565
|
return res.json();
|
|
896
1566
|
}
|
|
1567
|
+
async apiPostAuth(path, body, token) {
|
|
1568
|
+
const res = await fetch(`${this.config.apiUrl}${path}`, {
|
|
1569
|
+
method: "POST",
|
|
1570
|
+
headers: {
|
|
1571
|
+
"Content-Type": "application/json",
|
|
1572
|
+
"x-api-key": this.publishableKey,
|
|
1573
|
+
Authorization: `Bearer ${token}`
|
|
1574
|
+
},
|
|
1575
|
+
credentials: "include",
|
|
1576
|
+
body: body ? JSON.stringify(body) : void 0
|
|
1577
|
+
});
|
|
1578
|
+
if (!res.ok) throw new Error(await this.parseApiError(res, path));
|
|
1579
|
+
return res.json();
|
|
1580
|
+
}
|
|
1581
|
+
async apiGetAuth(path, token) {
|
|
1582
|
+
const res = await fetch(`${this.config.apiUrl}${path}`, {
|
|
1583
|
+
headers: {
|
|
1584
|
+
"x-api-key": this.publishableKey,
|
|
1585
|
+
Authorization: `Bearer ${token}`
|
|
1586
|
+
},
|
|
1587
|
+
credentials: "include"
|
|
1588
|
+
});
|
|
1589
|
+
if (!res.ok) throw new Error(await this.parseApiError(res, path));
|
|
1590
|
+
return res.json();
|
|
1591
|
+
}
|
|
1592
|
+
async apiPatchAuth(path, body, token) {
|
|
1593
|
+
const res = await fetch(`${this.config.apiUrl}${path}`, {
|
|
1594
|
+
method: "PATCH",
|
|
1595
|
+
headers: {
|
|
1596
|
+
"Content-Type": "application/json",
|
|
1597
|
+
"x-api-key": this.publishableKey,
|
|
1598
|
+
Authorization: `Bearer ${token}`
|
|
1599
|
+
},
|
|
1600
|
+
credentials: "include",
|
|
1601
|
+
body: body ? JSON.stringify(body) : void 0
|
|
1602
|
+
});
|
|
1603
|
+
if (!res.ok) throw new Error(await this.parseApiError(res, path));
|
|
1604
|
+
return res.json();
|
|
1605
|
+
}
|
|
1606
|
+
async apiDeleteAuth(path, token) {
|
|
1607
|
+
const res = await fetch(`${this.config.apiUrl}${path}`, {
|
|
1608
|
+
method: "DELETE",
|
|
1609
|
+
headers: {
|
|
1610
|
+
"x-api-key": this.publishableKey,
|
|
1611
|
+
Authorization: `Bearer ${token}`
|
|
1612
|
+
},
|
|
1613
|
+
credentials: "include"
|
|
1614
|
+
});
|
|
1615
|
+
if (!res.ok) throw new Error(await this.parseApiError(res, path));
|
|
1616
|
+
}
|
|
1617
|
+
// ── WebAuthn helpers ──
|
|
1618
|
+
bufferToBase64url(buffer) {
|
|
1619
|
+
const bytes = new Uint8Array(buffer);
|
|
1620
|
+
let binary = "";
|
|
1621
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1622
|
+
binary += String.fromCharCode(bytes[i]);
|
|
1623
|
+
}
|
|
1624
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
1625
|
+
}
|
|
1626
|
+
base64urlToBuffer(base64url) {
|
|
1627
|
+
const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
|
|
1628
|
+
const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
|
|
1629
|
+
const binary = atob(padded);
|
|
1630
|
+
const bytes = new Uint8Array(binary.length);
|
|
1631
|
+
for (let i = 0; i < binary.length; i++) {
|
|
1632
|
+
bytes[i] = binary.charCodeAt(i);
|
|
1633
|
+
}
|
|
1634
|
+
return bytes.buffer;
|
|
1635
|
+
}
|
|
1636
|
+
deserializeCreationOptions(options) {
|
|
1637
|
+
const opts = { ...options };
|
|
1638
|
+
if (typeof opts.challenge === "string") {
|
|
1639
|
+
opts.challenge = this.base64urlToBuffer(opts.challenge);
|
|
1640
|
+
}
|
|
1641
|
+
if (opts.user && typeof opts.user.id === "string") {
|
|
1642
|
+
opts.user.id = this.base64urlToBuffer(
|
|
1643
|
+
opts.user.id
|
|
1644
|
+
);
|
|
1645
|
+
}
|
|
1646
|
+
if (Array.isArray(opts.excludeCredentials)) {
|
|
1647
|
+
opts.excludeCredentials = opts.excludeCredentials.map((c) => ({
|
|
1648
|
+
...c,
|
|
1649
|
+
id: typeof c.id === "string" ? this.base64urlToBuffer(c.id) : c.id
|
|
1650
|
+
}));
|
|
1651
|
+
}
|
|
1652
|
+
return opts;
|
|
1653
|
+
}
|
|
1654
|
+
deserializeRequestOptions(options) {
|
|
1655
|
+
const opts = { ...options };
|
|
1656
|
+
if (typeof opts.challenge === "string") {
|
|
1657
|
+
opts.challenge = this.base64urlToBuffer(opts.challenge);
|
|
1658
|
+
}
|
|
1659
|
+
if (Array.isArray(opts.allowCredentials)) {
|
|
1660
|
+
opts.allowCredentials = opts.allowCredentials.map((c) => ({
|
|
1661
|
+
...c,
|
|
1662
|
+
id: typeof c.id === "string" ? this.base64urlToBuffer(c.id) : c.id
|
|
1663
|
+
}));
|
|
1664
|
+
}
|
|
1665
|
+
return opts;
|
|
1666
|
+
}
|
|
897
1667
|
async parseApiError(res, path) {
|
|
898
1668
|
try {
|
|
899
1669
|
const body = await res.json();
|
|
@@ -910,6 +1680,8 @@ var Authon = class {
|
|
|
910
1680
|
};
|
|
911
1681
|
export {
|
|
912
1682
|
Authon,
|
|
1683
|
+
AuthonMfaRequiredError,
|
|
1684
|
+
generateQrSvg,
|
|
913
1685
|
getProviderButtonConfig
|
|
914
1686
|
};
|
|
915
1687
|
//# sourceMappingURL=index.js.map
|