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