postex-auth-sdk-stage 2.3.0 → 3.0.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.md +39 -9
- package/dist/auth.d.ts +24 -9
- package/dist/postex-auth-sdk-stage.es.js +385 -369
- package/dist/postex-auth-sdk-stage.iife.js +1 -1
- package/dist/postex-auth-sdk-stage.umd.js +1 -1
- package/package.json +1 -1
|
@@ -1,137 +1,137 @@
|
|
|
1
|
-
function
|
|
1
|
+
function O() {
|
|
2
2
|
return typeof window < "u" && typeof window.PublicKeyCredential < "u" && typeof navigator < "u" && typeof navigator.credentials < "u";
|
|
3
3
|
}
|
|
4
|
-
async function
|
|
5
|
-
if (!
|
|
4
|
+
async function j() {
|
|
5
|
+
if (!O()) return !1;
|
|
6
6
|
try {
|
|
7
7
|
return await PublicKeyCredential.isConditionalMediationAvailable?.() ?? !1;
|
|
8
8
|
} catch {
|
|
9
9
|
return !1;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
const e = new Uint8Array(
|
|
14
|
-
let
|
|
12
|
+
function N(a) {
|
|
13
|
+
const e = new Uint8Array(a);
|
|
14
|
+
let s = "";
|
|
15
15
|
for (let t = 0; t < e.byteLength; t++)
|
|
16
|
-
|
|
17
|
-
return btoa(
|
|
16
|
+
s += String.fromCharCode(e[t]);
|
|
17
|
+
return btoa(s);
|
|
18
18
|
}
|
|
19
|
-
function C(
|
|
20
|
-
if (typeof
|
|
19
|
+
function C(a) {
|
|
20
|
+
if (typeof a != "string" || !a)
|
|
21
21
|
throw new Error("Invalid base64: expected non-empty string");
|
|
22
|
-
const e =
|
|
22
|
+
const e = a.replace(/\s/g, "").replace(/-/g, "+").replace(/_/g, "/"), s = e.length % 4, t = s > 0 ? e + "=".repeat(4 - s) : e;
|
|
23
23
|
try {
|
|
24
|
-
const
|
|
25
|
-
for (let
|
|
26
|
-
|
|
27
|
-
return
|
|
24
|
+
const n = atob(t), r = new Uint8Array(n.length);
|
|
25
|
+
for (let o = 0; o < n.length; o++)
|
|
26
|
+
r[o] = n.charCodeAt(o);
|
|
27
|
+
return r.buffer;
|
|
28
28
|
} catch {
|
|
29
29
|
throw new Error(
|
|
30
30
|
"Invalid base64: string is not correctly encoded. Check challenge/credentialId from server."
|
|
31
31
|
);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
function
|
|
35
|
-
return
|
|
34
|
+
function y(a) {
|
|
35
|
+
return N(a).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
36
36
|
}
|
|
37
|
-
function
|
|
37
|
+
function H(a) {
|
|
38
38
|
return /^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i.test(
|
|
39
|
-
|
|
39
|
+
a
|
|
40
40
|
);
|
|
41
41
|
}
|
|
42
|
-
function
|
|
43
|
-
const e =
|
|
44
|
-
for (let t = 0; t <
|
|
45
|
-
|
|
46
|
-
return
|
|
42
|
+
function J(a) {
|
|
43
|
+
const e = a.replace(/-/g, ""), s = new Uint8Array(e.length / 2);
|
|
44
|
+
for (let t = 0; t < s.length; t++)
|
|
45
|
+
s[t] = parseInt(e.substr(t * 2, 2), 16);
|
|
46
|
+
return s.buffer;
|
|
47
47
|
}
|
|
48
|
-
function
|
|
49
|
-
if (!
|
|
48
|
+
function b(a) {
|
|
49
|
+
if (!a || typeof a != "string")
|
|
50
50
|
throw new Error("Invalid input: expected non-empty string");
|
|
51
|
-
return
|
|
51
|
+
return H(a) ? J(a) : C(a);
|
|
52
52
|
}
|
|
53
|
-
function k(
|
|
54
|
-
return new TextEncoder().encode(
|
|
53
|
+
function k(a) {
|
|
54
|
+
return new TextEncoder().encode(a).buffer;
|
|
55
55
|
}
|
|
56
|
-
function
|
|
57
|
-
return String.fromCharCode(...
|
|
56
|
+
function F(a) {
|
|
57
|
+
return String.fromCharCode(...a);
|
|
58
58
|
}
|
|
59
|
-
const
|
|
59
|
+
const G = "xpay_webauthn", W = 1, u = "passkey_data", E = "passkey_email", _ = "passkey_mobile_number";
|
|
60
60
|
function m() {
|
|
61
|
-
return new Promise((
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
const t =
|
|
61
|
+
return new Promise((a, e) => {
|
|
62
|
+
const s = indexedDB.open(G, W);
|
|
63
|
+
s.onerror = () => e(s.error), s.onsuccess = () => a(s.result), s.onupgradeneeded = () => {
|
|
64
|
+
const t = s.result;
|
|
65
65
|
t.objectStoreNames.contains(u) || t.createObjectStore(u);
|
|
66
66
|
};
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
-
async function
|
|
69
|
+
async function Y() {
|
|
70
70
|
try {
|
|
71
|
-
const
|
|
72
|
-
return new Promise((e,
|
|
73
|
-
const t =
|
|
74
|
-
|
|
71
|
+
const a = await m();
|
|
72
|
+
return new Promise((e, s) => {
|
|
73
|
+
const t = a.transaction(u, "readonly"), r = t.objectStore(u).get(E);
|
|
74
|
+
r.onerror = () => s(r.error), r.onsuccess = () => e(r.result ?? null), t.oncomplete = () => a.close();
|
|
75
75
|
});
|
|
76
76
|
} catch {
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
async function
|
|
80
|
+
async function V(a) {
|
|
81
81
|
try {
|
|
82
82
|
const e = await m();
|
|
83
|
-
return new Promise((
|
|
84
|
-
const
|
|
85
|
-
|
|
83
|
+
return new Promise((s, t) => {
|
|
84
|
+
const n = e.transaction(u, "readwrite"), o = n.objectStore(u).put(a, E);
|
|
85
|
+
o.onerror = () => t(o.error), o.onsuccess = () => s(), n.oncomplete = () => e.close();
|
|
86
86
|
});
|
|
87
87
|
} catch {
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
async function
|
|
90
|
+
async function X() {
|
|
91
91
|
try {
|
|
92
|
-
const
|
|
93
|
-
return new Promise((e,
|
|
94
|
-
const t =
|
|
95
|
-
|
|
92
|
+
const a = await m();
|
|
93
|
+
return new Promise((e, s) => {
|
|
94
|
+
const t = a.transaction(u, "readwrite"), r = t.objectStore(u).delete(E);
|
|
95
|
+
r.onerror = () => s(r.error), r.onsuccess = () => e(), t.oncomplete = () => a.close();
|
|
96
96
|
});
|
|
97
97
|
} catch {
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
async function
|
|
100
|
+
async function Z() {
|
|
101
101
|
try {
|
|
102
|
-
const
|
|
103
|
-
return new Promise((e,
|
|
104
|
-
const t =
|
|
105
|
-
|
|
102
|
+
const a = await m();
|
|
103
|
+
return new Promise((e, s) => {
|
|
104
|
+
const t = a.transaction(u, "readonly"), r = t.objectStore(u).get(_);
|
|
105
|
+
r.onerror = () => s(r.error), r.onsuccess = () => e(r.result ?? null), t.oncomplete = () => a.close();
|
|
106
106
|
});
|
|
107
107
|
} catch {
|
|
108
108
|
return null;
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
async function
|
|
111
|
+
async function Q(a) {
|
|
112
112
|
try {
|
|
113
113
|
const e = await m();
|
|
114
|
-
return new Promise((
|
|
115
|
-
const
|
|
116
|
-
|
|
114
|
+
return new Promise((s, t) => {
|
|
115
|
+
const n = e.transaction(u, "readwrite"), o = n.objectStore(u).put(a, _);
|
|
116
|
+
o.onerror = () => t(o.error), o.onsuccess = () => s(), n.oncomplete = () => e.close();
|
|
117
117
|
});
|
|
118
118
|
} catch {
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
-
async function
|
|
121
|
+
async function ee() {
|
|
122
122
|
try {
|
|
123
|
-
const
|
|
124
|
-
return new Promise((e,
|
|
125
|
-
const t =
|
|
126
|
-
|
|
123
|
+
const a = await m();
|
|
124
|
+
return new Promise((e, s) => {
|
|
125
|
+
const t = a.transaction(u, "readwrite"), r = t.objectStore(u).delete(_);
|
|
126
|
+
r.onerror = () => s(r.error), r.onsuccess = () => e(), t.oncomplete = () => a.close();
|
|
127
127
|
});
|
|
128
128
|
} catch {
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
-
const S = "dpop_private_key",
|
|
132
|
-
function
|
|
133
|
-
if (!
|
|
134
|
-
const e =
|
|
131
|
+
const S = "dpop_private_key", v = "dpop_public_key_jwk";
|
|
132
|
+
function K(a) {
|
|
133
|
+
if (!a || typeof a != "object") return !1;
|
|
134
|
+
const e = a;
|
|
135
135
|
return e.kty === "EC" && e.crv === "P-256" && typeof e.x == "string" && typeof e.y == "string";
|
|
136
136
|
}
|
|
137
137
|
class g extends Error {
|
|
@@ -139,65 +139,65 @@ class g extends Error {
|
|
|
139
139
|
super(e), this.name = "DPoPProofGenerationError";
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
function
|
|
142
|
+
function te(a) {
|
|
143
143
|
return {
|
|
144
144
|
kty: "EC",
|
|
145
145
|
crv: "P-256",
|
|
146
|
-
x:
|
|
147
|
-
y:
|
|
146
|
+
x: a.x,
|
|
147
|
+
y: a.y
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
|
-
async function
|
|
150
|
+
async function q(a) {
|
|
151
151
|
const e = JSON.stringify({
|
|
152
|
-
crv:
|
|
153
|
-
kty:
|
|
154
|
-
x:
|
|
155
|
-
y:
|
|
156
|
-
}),
|
|
152
|
+
crv: a.crv,
|
|
153
|
+
kty: a.kty,
|
|
154
|
+
x: a.x,
|
|
155
|
+
y: a.y
|
|
156
|
+
}), s = await crypto.subtle.digest(
|
|
157
157
|
"SHA-256",
|
|
158
158
|
new TextEncoder().encode(e)
|
|
159
159
|
);
|
|
160
|
-
return
|
|
160
|
+
return y(s);
|
|
161
161
|
}
|
|
162
|
-
async function
|
|
162
|
+
async function se(a) {
|
|
163
163
|
try {
|
|
164
164
|
const e = await m();
|
|
165
|
-
return new Promise((
|
|
166
|
-
const
|
|
167
|
-
|
|
165
|
+
return new Promise((s, t) => {
|
|
166
|
+
const n = e.transaction(u, "readwrite"), o = n.objectStore(u).put(a, S);
|
|
167
|
+
o.onerror = () => t(o.error), o.onsuccess = () => s(), n.oncomplete = () => e.close();
|
|
168
168
|
});
|
|
169
169
|
} catch (e) {
|
|
170
170
|
console.error("Failed to store DPoP private key:", e);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
-
async function re(
|
|
173
|
+
async function re(a) {
|
|
174
174
|
try {
|
|
175
175
|
const e = await m();
|
|
176
|
-
return new Promise((
|
|
177
|
-
const
|
|
178
|
-
|
|
176
|
+
return new Promise((s, t) => {
|
|
177
|
+
const n = e.transaction(u, "readwrite"), o = n.objectStore(u).put(a, v);
|
|
178
|
+
o.onerror = () => t(o.error), o.onsuccess = () => s(), n.oncomplete = () => e.close();
|
|
179
179
|
});
|
|
180
180
|
} catch (e) {
|
|
181
181
|
console.error("Failed to store DPoP public key JWK:", e);
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
-
async function
|
|
184
|
+
async function $() {
|
|
185
185
|
try {
|
|
186
|
-
const
|
|
187
|
-
return new Promise((e,
|
|
188
|
-
const t =
|
|
189
|
-
|
|
186
|
+
const a = await m();
|
|
187
|
+
return new Promise((e, s) => {
|
|
188
|
+
const t = a.transaction(u, "readonly"), r = t.objectStore(u).get(S);
|
|
189
|
+
r.onerror = () => s(r.error), r.onsuccess = () => e(r.result ?? null), t.oncomplete = () => a.close();
|
|
190
190
|
});
|
|
191
191
|
} catch {
|
|
192
192
|
return null;
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
|
-
async function
|
|
195
|
+
async function B() {
|
|
196
196
|
try {
|
|
197
|
-
const
|
|
198
|
-
return new Promise((e,
|
|
199
|
-
const t =
|
|
200
|
-
|
|
197
|
+
const a = await m();
|
|
198
|
+
return new Promise((e, s) => {
|
|
199
|
+
const t = a.transaction(u, "readonly"), r = t.objectStore(u).get(v);
|
|
200
|
+
r.onerror = () => s(r.error), r.onsuccess = () => e(r.result ?? null), t.oncomplete = () => a.close();
|
|
201
201
|
});
|
|
202
202
|
} catch {
|
|
203
203
|
return null;
|
|
@@ -205,18 +205,18 @@ async function $() {
|
|
|
205
205
|
}
|
|
206
206
|
async function T() {
|
|
207
207
|
try {
|
|
208
|
-
const
|
|
209
|
-
return new Promise((e,
|
|
210
|
-
const t =
|
|
211
|
-
|
|
212
|
-
|
|
208
|
+
const a = await m();
|
|
209
|
+
return new Promise((e, s) => {
|
|
210
|
+
const t = a.transaction(u, "readwrite"), n = t.objectStore(u);
|
|
211
|
+
n.delete(S), n.delete(v), t.onerror = () => s(t.error), t.oncomplete = () => {
|
|
212
|
+
a.close(), e();
|
|
213
213
|
};
|
|
214
214
|
});
|
|
215
215
|
} catch {
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
async function ne() {
|
|
219
|
-
const
|
|
219
|
+
const a = await crypto.subtle.generateKey(
|
|
220
220
|
{
|
|
221
221
|
name: "ECDSA",
|
|
222
222
|
namedCurve: "P-256"
|
|
@@ -224,241 +224,253 @@ async function ne() {
|
|
|
224
224
|
!1,
|
|
225
225
|
// Private key is non-extractable
|
|
226
226
|
["sign", "verify"]
|
|
227
|
-
), e = await crypto.subtle.exportKey("jwk",
|
|
228
|
-
return await
|
|
227
|
+
), e = await crypto.subtle.exportKey("jwk", a.publicKey), s = te(e), t = await q(s);
|
|
228
|
+
return await se(a.privateKey), await re(s), { publicKey: s, thumbprint: t };
|
|
229
229
|
}
|
|
230
|
-
async function
|
|
231
|
-
const
|
|
232
|
-
return
|
|
230
|
+
async function oe() {
|
|
231
|
+
const a = await $(), e = await B();
|
|
232
|
+
return a && K(e) ? {
|
|
233
233
|
publicKey: e,
|
|
234
|
-
thumbprint: await
|
|
235
|
-
} : ((
|
|
234
|
+
thumbprint: await q(e)
|
|
235
|
+
} : ((a || e) && await T(), ne());
|
|
236
236
|
}
|
|
237
|
-
async function
|
|
237
|
+
async function ae(a, e, s) {
|
|
238
238
|
try {
|
|
239
|
-
const t = await
|
|
240
|
-
if (!t || !
|
|
239
|
+
const t = await $(), n = await B();
|
|
240
|
+
if (!t || !K(n))
|
|
241
241
|
throw new g(
|
|
242
242
|
"DPoP key material is unavailable or invalid"
|
|
243
243
|
);
|
|
244
|
-
const
|
|
244
|
+
const r = {
|
|
245
245
|
typ: "dpop+jwt",
|
|
246
246
|
alg: "ES256",
|
|
247
|
-
jwk:
|
|
247
|
+
jwk: n
|
|
248
248
|
// Public key in JWK format
|
|
249
|
-
},
|
|
249
|
+
}, o = new URL(
|
|
250
250
|
e,
|
|
251
251
|
typeof window < "u" ? window.location.origin : void 0
|
|
252
|
-
), l = `${
|
|
252
|
+
), l = `${o.origin}${o.pathname}`, c = {
|
|
253
253
|
jti: crypto.randomUUID(),
|
|
254
|
-
htm:
|
|
254
|
+
htm: a.toUpperCase(),
|
|
255
255
|
htu: l,
|
|
256
256
|
iat: Math.floor(Date.now() / 1e3)
|
|
257
257
|
};
|
|
258
|
-
if (
|
|
259
|
-
const
|
|
260
|
-
c.ath =
|
|
258
|
+
if (s) {
|
|
259
|
+
const L = new TextEncoder().encode(s), M = await crypto.subtle.digest("SHA-256", L);
|
|
260
|
+
c.ath = y(M);
|
|
261
261
|
}
|
|
262
|
-
const d =
|
|
263
|
-
new TextEncoder().encode(JSON.stringify(
|
|
264
|
-
), i =
|
|
262
|
+
const d = y(
|
|
263
|
+
new TextEncoder().encode(JSON.stringify(r)).buffer
|
|
264
|
+
), i = y(
|
|
265
265
|
new TextEncoder().encode(JSON.stringify(c)).buffer
|
|
266
|
-
),
|
|
266
|
+
), h = `${d}.${i}`, f = await crypto.subtle.sign(
|
|
267
267
|
{
|
|
268
268
|
name: "ECDSA",
|
|
269
269
|
hash: { name: "SHA-256" }
|
|
270
270
|
},
|
|
271
271
|
t,
|
|
272
|
-
new TextEncoder().encode(
|
|
273
|
-
), w =
|
|
272
|
+
new TextEncoder().encode(h)
|
|
273
|
+
), w = y(f);
|
|
274
274
|
return `${d}.${i}.${w}`;
|
|
275
275
|
} catch (t) {
|
|
276
276
|
throw console.error("Failed to generate DPoP proof:", t), t instanceof g ? t : new g("Failed to generate DPoP proof");
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
|
-
const
|
|
280
|
-
isWebAuthnSupported:
|
|
281
|
-
isConditionalUISupported:
|
|
282
|
-
arrayBufferToBase64:
|
|
279
|
+
const U = {
|
|
280
|
+
isWebAuthnSupported: O,
|
|
281
|
+
isConditionalUISupported: j,
|
|
282
|
+
arrayBufferToBase64: N,
|
|
283
283
|
base64ToArrayBuffer: C,
|
|
284
|
-
arrayBufferToBase64url:
|
|
285
|
-
base64urlToArrayBuffer:
|
|
284
|
+
arrayBufferToBase64url: y,
|
|
285
|
+
base64urlToArrayBuffer: b,
|
|
286
286
|
stringToArrayBuffer: k,
|
|
287
|
-
uint8ArrayToString:
|
|
288
|
-
getPasskeyEmail:
|
|
289
|
-
setPasskeyEmail:
|
|
290
|
-
clearPasskeyEmail:
|
|
291
|
-
getPasskeyMobileNumber:
|
|
292
|
-
setPasskeyMobileNumber:
|
|
293
|
-
clearPasskeyMobileNumber:
|
|
287
|
+
uint8ArrayToString: F,
|
|
288
|
+
getPasskeyEmail: Y,
|
|
289
|
+
setPasskeyEmail: V,
|
|
290
|
+
clearPasskeyEmail: X,
|
|
291
|
+
getPasskeyMobileNumber: Z,
|
|
292
|
+
setPasskeyMobileNumber: Q,
|
|
293
|
+
clearPasskeyMobileNumber: ee
|
|
294
294
|
};
|
|
295
|
-
typeof window < "u" && (window.WebAuthn =
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
const
|
|
295
|
+
typeof window < "u" && (window.WebAuthn = U);
|
|
296
|
+
const ie = typeof window < "u" ? window : globalThis;
|
|
297
|
+
ie.WebAuthn = U;
|
|
298
|
+
const P = "postex-auth-token", ce = "postexglobal", le = {
|
|
299
299
|
xstak: "https://auth-stage.xstak.com/public/v1",
|
|
300
300
|
postex: "https://auth-stage.postex.pk/public/v1",
|
|
301
301
|
callcourier: "https://auth-stage.callcourier.com.pk/public/v1",
|
|
302
302
|
postexglobal: "https://auth-stage.postexglobal.com/public/v1",
|
|
303
303
|
postexsa: "https://auth-stage.postex.sa/public/v1"
|
|
304
|
-
},
|
|
305
|
-
class
|
|
306
|
-
constructor(e,
|
|
307
|
-
super(t ?? `Request failed with status ${e}`), this.response = { status: e, data:
|
|
304
|
+
}, ue = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/, de = /^\+[1-9]\d{6,14}$/, he = /^\d{6}$/, pe = /^[A-Za-z0-9_-]{16,512}$/, ye = /[\u0000-\u001F\u007F-\u009F]/, me = /[A-Za-z]/, fe = /[\u0400-\u04FF]/, A = 254, x = 16, I = 64, D = 64;
|
|
305
|
+
class we extends Error {
|
|
306
|
+
constructor(e, s, t) {
|
|
307
|
+
super(t ?? `Request failed with status ${e}`), this.response = { status: e, data: s }, this.name = "AuthSDKFetchError";
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
|
-
class
|
|
311
|
-
constructor(e,
|
|
312
|
-
super(
|
|
310
|
+
class p extends Error {
|
|
311
|
+
constructor(e, s, t = "invalid_input") {
|
|
312
|
+
super(s), this.field = e, this.code = t, this.name = "SDKValidationError";
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
|
-
const
|
|
316
|
-
class
|
|
315
|
+
const R = "auth_sdk_refresh_token";
|
|
316
|
+
class z {
|
|
317
317
|
constructor(e) {
|
|
318
318
|
this.config = e, this.dpopInitializationPromise = this.createDPoPInitializationPromise();
|
|
319
319
|
}
|
|
320
320
|
getBaseUrl() {
|
|
321
|
-
const e = this.config.appId ??
|
|
322
|
-
return
|
|
321
|
+
const e = this.config.appId ?? ce;
|
|
322
|
+
return le[e];
|
|
323
323
|
}
|
|
324
324
|
async initializeDPoPState() {
|
|
325
|
-
await
|
|
325
|
+
await oe();
|
|
326
326
|
}
|
|
327
327
|
async ensureDPoPInitialized() {
|
|
328
328
|
await this.dpopInitializationPromise;
|
|
329
329
|
}
|
|
330
330
|
createDPoPInitializationPromise() {
|
|
331
331
|
const e = this.initializeDPoPState();
|
|
332
|
-
return e.catch((
|
|
333
|
-
console.warn("[AuthSDK] DPoP initialization failed:",
|
|
332
|
+
return e.catch((s) => {
|
|
333
|
+
console.warn("[AuthSDK] DPoP initialization failed:", s);
|
|
334
334
|
}), e;
|
|
335
335
|
}
|
|
336
336
|
resetDPoPInitialization() {
|
|
337
337
|
this.dpopInitializationPromise = this.createDPoPInitializationPromise();
|
|
338
338
|
}
|
|
339
|
-
async getRequiredDPoPProof(e,
|
|
340
|
-
return await this.ensureDPoPInitialized(),
|
|
339
|
+
async getRequiredDPoPProof(e, s, t) {
|
|
340
|
+
return await this.ensureDPoPInitialized(), ae(e.toUpperCase(), s, t);
|
|
341
341
|
}
|
|
342
342
|
containsControlChars(e) {
|
|
343
|
-
return
|
|
343
|
+
return ye.test(e);
|
|
344
344
|
}
|
|
345
345
|
hasMixedLatinAndCyrillic(e) {
|
|
346
|
-
return
|
|
346
|
+
return me.test(e) && fe.test(e);
|
|
347
347
|
}
|
|
348
|
-
assertNoControlChars(e,
|
|
349
|
-
if (this.containsControlChars(
|
|
350
|
-
throw new
|
|
348
|
+
assertNoControlChars(e, s) {
|
|
349
|
+
if (this.containsControlChars(s))
|
|
350
|
+
throw new p(
|
|
351
351
|
e,
|
|
352
352
|
`${e} must not contain control characters`
|
|
353
353
|
);
|
|
354
354
|
}
|
|
355
|
-
validateEmail(e,
|
|
355
|
+
validateEmail(e, s = "email") {
|
|
356
356
|
const t = e.trim();
|
|
357
357
|
if (!t)
|
|
358
|
-
throw new
|
|
359
|
-
if (t.length >
|
|
360
|
-
throw new
|
|
361
|
-
|
|
362
|
-
`${
|
|
358
|
+
throw new p(s, `${s} is required`);
|
|
359
|
+
if (t.length > A)
|
|
360
|
+
throw new p(
|
|
361
|
+
s,
|
|
362
|
+
`${s} must be ${A} characters or fewer`
|
|
363
363
|
);
|
|
364
|
-
this.assertNoControlChars(
|
|
365
|
-
const [
|
|
366
|
-
if (this.hasMixedLatinAndCyrillic(
|
|
367
|
-
throw new
|
|
368
|
-
|
|
369
|
-
`${
|
|
364
|
+
this.assertNoControlChars(s, t);
|
|
365
|
+
const [n = ""] = t.split("@");
|
|
366
|
+
if (this.hasMixedLatinAndCyrillic(n))
|
|
367
|
+
throw new p(
|
|
368
|
+
s,
|
|
369
|
+
`${s} must not mix Latin and Cyrillic characters in the local part`
|
|
370
370
|
);
|
|
371
|
-
if (!
|
|
372
|
-
throw new
|
|
371
|
+
if (!ue.test(t))
|
|
372
|
+
throw new p(s, `${s} must be a valid email`);
|
|
373
373
|
return t;
|
|
374
374
|
}
|
|
375
|
-
validateMobileNumber(e,
|
|
375
|
+
validateMobileNumber(e, s = "mobileNumber") {
|
|
376
376
|
const t = e.trim();
|
|
377
377
|
if (!t)
|
|
378
|
-
throw new
|
|
378
|
+
throw new p(s, `${s} is required`);
|
|
379
379
|
if (t.length > x)
|
|
380
|
-
throw new
|
|
381
|
-
|
|
382
|
-
`${
|
|
380
|
+
throw new p(
|
|
381
|
+
s,
|
|
382
|
+
`${s} must be ${x} characters or fewer`
|
|
383
383
|
);
|
|
384
|
-
if (this.assertNoControlChars(
|
|
385
|
-
throw new
|
|
384
|
+
if (this.assertNoControlChars(s, t), !de.test(t))
|
|
385
|
+
throw new p(s, `${s} must be in E.164 format`);
|
|
386
386
|
return t;
|
|
387
387
|
}
|
|
388
|
-
|
|
388
|
+
validateUsername(e, s = "username") {
|
|
389
|
+
const t = e.trim();
|
|
390
|
+
if (!t)
|
|
391
|
+
throw new p(s, `${s} is required`);
|
|
392
|
+
if (t.length > I)
|
|
393
|
+
throw new p(
|
|
394
|
+
s,
|
|
395
|
+
`${s} must be ${I} characters or fewer`
|
|
396
|
+
);
|
|
397
|
+
return this.assertNoControlChars(s, t), t;
|
|
398
|
+
}
|
|
399
|
+
validateOTP(e, s = "otp") {
|
|
389
400
|
const t = e.trim();
|
|
390
|
-
if (this.assertNoControlChars(
|
|
391
|
-
throw new
|
|
401
|
+
if (this.assertNoControlChars(s, t), !he.test(t))
|
|
402
|
+
throw new p(s, `${s} must be a 6-digit code`);
|
|
392
403
|
return t;
|
|
393
404
|
}
|
|
394
|
-
validateMagicLinkToken(e,
|
|
405
|
+
validateMagicLinkToken(e, s = "token") {
|
|
395
406
|
const t = e.trim();
|
|
396
|
-
if (this.assertNoControlChars(
|
|
397
|
-
throw new
|
|
398
|
-
|
|
399
|
-
`${
|
|
407
|
+
if (this.assertNoControlChars(s, t), !pe.test(t))
|
|
408
|
+
throw new p(
|
|
409
|
+
s,
|
|
410
|
+
`${s} must be 16-512 URL-safe characters`
|
|
400
411
|
);
|
|
401
412
|
return t;
|
|
402
413
|
}
|
|
403
414
|
validateRealm(e) {
|
|
404
|
-
const
|
|
405
|
-
if (
|
|
406
|
-
if (this.assertNoControlChars("realm",
|
|
407
|
-
throw new
|
|
415
|
+
const s = e?.trim();
|
|
416
|
+
if (s) {
|
|
417
|
+
if (this.assertNoControlChars("realm", s), s.length > D)
|
|
418
|
+
throw new p(
|
|
408
419
|
"realm",
|
|
409
|
-
`realm must be ${
|
|
420
|
+
`realm must be ${D} characters or fewer`
|
|
410
421
|
);
|
|
411
|
-
return
|
|
422
|
+
return s;
|
|
412
423
|
}
|
|
413
424
|
}
|
|
414
425
|
normalizeAndValidateIdentifier(e) {
|
|
415
426
|
return typeof e == "string" ? { email: this.validateEmail(e) } : {
|
|
416
427
|
email: e.email ? this.validateEmail(e.email) : void 0,
|
|
417
|
-
mobileNumber: e.mobileNumber ? this.validateMobileNumber(e.mobileNumber) : void 0
|
|
428
|
+
mobileNumber: e.mobileNumber ? this.validateMobileNumber(e.mobileNumber) : void 0,
|
|
429
|
+
username: e.username ? this.validateUsername(e.username) : void 0
|
|
418
430
|
};
|
|
419
431
|
}
|
|
420
432
|
normalizeAuthIdentifier(e) {
|
|
421
433
|
return this.normalizeAndValidateIdentifier(e);
|
|
422
434
|
}
|
|
423
|
-
extractRealm(e,
|
|
424
|
-
const t =
|
|
435
|
+
extractRealm(e, s) {
|
|
436
|
+
const t = s?.realm ?? (e && typeof e != "string" ? e.realm : void 0);
|
|
425
437
|
return this.validateRealm(t);
|
|
426
438
|
}
|
|
427
|
-
buildAuthRequestBody(e,
|
|
428
|
-
const t = this.normalizeAuthIdentifier(e),
|
|
439
|
+
buildAuthRequestBody(e, s) {
|
|
440
|
+
const t = this.normalizeAuthIdentifier(e), n = this.extractRealm(e, s);
|
|
429
441
|
return {
|
|
430
442
|
...t,
|
|
431
|
-
...
|
|
443
|
+
...n ? { realm: n } : {}
|
|
432
444
|
};
|
|
433
445
|
}
|
|
434
|
-
buildUrl(e,
|
|
435
|
-
const t = this.getBaseUrl().replace(/\/$/, ""),
|
|
436
|
-
if (!
|
|
437
|
-
const
|
|
438
|
-
return `${
|
|
446
|
+
buildUrl(e, s) {
|
|
447
|
+
const t = this.getBaseUrl().replace(/\/$/, ""), n = e.startsWith("/") ? e : `/${e}`, r = `${t}${n}`;
|
|
448
|
+
if (!s || Object.keys(s).length === 0) return r;
|
|
449
|
+
const o = new URLSearchParams(s).toString();
|
|
450
|
+
return `${r}?${o}`;
|
|
439
451
|
}
|
|
440
|
-
async request(e,
|
|
441
|
-
const
|
|
452
|
+
async request(e, s, t) {
|
|
453
|
+
const n = this.buildUrl(s, t?.params), r = {
|
|
442
454
|
"Content-Type": "application/json",
|
|
443
455
|
Accept: "application/json",
|
|
444
456
|
"X-API-Key": this.config.apiKey ?? "",
|
|
445
457
|
...t?.headers
|
|
446
|
-
},
|
|
458
|
+
}, o = {
|
|
447
459
|
method: e,
|
|
448
460
|
credentials: "include",
|
|
449
|
-
headers:
|
|
461
|
+
headers: r
|
|
450
462
|
};
|
|
451
|
-
t?.body !== void 0 && t?.body !== null && (
|
|
452
|
-
const l = await fetch(
|
|
463
|
+
t?.body !== void 0 && t?.body !== null && (o.body = JSON.stringify(t.body));
|
|
464
|
+
const l = await fetch(n, o);
|
|
453
465
|
if (!l.ok) {
|
|
454
466
|
let i;
|
|
455
467
|
try {
|
|
456
|
-
const
|
|
457
|
-
i =
|
|
468
|
+
const h = await l.text();
|
|
469
|
+
i = h ? JSON.parse(h) : void 0;
|
|
458
470
|
} catch {
|
|
459
471
|
i = void 0;
|
|
460
472
|
}
|
|
461
|
-
throw l.status === 401 && (await this.clearTokens(), await T(), this.resetDPoPInitialization()), new
|
|
473
|
+
throw l.status === 401 && (await this.clearTokens(), await T(), this.resetDPoPInitialization()), new we(l.status, i);
|
|
462
474
|
}
|
|
463
475
|
const c = await l.text();
|
|
464
476
|
return { data: c ? JSON.parse(c) : {} };
|
|
@@ -469,60 +481,64 @@ class U {
|
|
|
469
481
|
* @param method - HTTP method (e.g. "GET", "POST")
|
|
470
482
|
* @param url - Full request URL
|
|
471
483
|
*/
|
|
472
|
-
async getRequestAuthHeaders(e,
|
|
473
|
-
const t = localStorage.getItem(
|
|
484
|
+
async getRequestAuthHeaders(e, s) {
|
|
485
|
+
const t = localStorage.getItem(P);
|
|
474
486
|
if (!t) return {};
|
|
475
|
-
const
|
|
487
|
+
const n = s.startsWith("http") ? s : `${this.getBaseUrl()}${s}`, r = await this.getRequiredDPoPProof(e, n, t);
|
|
476
488
|
return {
|
|
477
489
|
Authorization: `Bearer ${t}`,
|
|
478
|
-
DPoP:
|
|
490
|
+
DPoP: r
|
|
479
491
|
};
|
|
480
492
|
}
|
|
481
493
|
/**
|
|
482
494
|
* GET /auth/status - Check if client has trusted device session and what auth method is available.
|
|
483
495
|
* Returns no_session | session_found | webauthn_ready per PostEx Auth BFF spec.
|
|
484
496
|
*/
|
|
485
|
-
async getStatus(e,
|
|
486
|
-
const t = this.normalizeAuthIdentifier(e),
|
|
487
|
-
t.email && (
|
|
488
|
-
const
|
|
489
|
-
params:
|
|
497
|
+
async getStatus(e, s) {
|
|
498
|
+
const t = this.normalizeAuthIdentifier(e), n = this.extractRealm(e, s), r = {};
|
|
499
|
+
t.email && (r.email = t.email), t.mobileNumber && (r.mobileNumber = t.mobileNumber), t.username && (r.username = t.username), n && (r.realm = n);
|
|
500
|
+
const o = await this.request("GET", "/auth/status", {
|
|
501
|
+
params: r
|
|
490
502
|
});
|
|
491
|
-
return
|
|
503
|
+
return o.data.data ?? o.data;
|
|
492
504
|
}
|
|
493
505
|
/**
|
|
494
506
|
* POST /auth/initiate - Unified entry: returns webauthn_challenge or otp_sent.
|
|
495
|
-
* Sets auth_session cookie when otp_sent.
|
|
507
|
+
* Sets auth_session cookie and includes delivery metadata when otp_sent.
|
|
496
508
|
*/
|
|
497
|
-
async initiateAuth(e,
|
|
498
|
-
const t = this.buildAuthRequestBody(e,
|
|
509
|
+
async initiateAuth(e, s) {
|
|
510
|
+
const t = this.buildAuthRequestBody(e, s), r = (await this.request("POST", "/auth/initiate", {
|
|
499
511
|
body: t
|
|
500
|
-
}),
|
|
512
|
+
})).data, o = r.data;
|
|
501
513
|
return {
|
|
502
|
-
status:
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
514
|
+
status: o.status,
|
|
515
|
+
message: r.message,
|
|
516
|
+
delivery: o.delivery,
|
|
517
|
+
challenge: o.challenge,
|
|
518
|
+
credentialIds: o.credentialIds,
|
|
519
|
+
rp: o.rp
|
|
506
520
|
};
|
|
507
521
|
}
|
|
508
522
|
/**
|
|
509
|
-
* POST /otp/initiate - Direct OTP initiation using email
|
|
510
|
-
* Requires at least one identifier: email or
|
|
523
|
+
* POST /otp/initiate - Direct OTP initiation using email, mobile number, or username.
|
|
524
|
+
* Requires at least one identifier: email, mobileNumber, or username.
|
|
511
525
|
*/
|
|
512
|
-
async initiateOTP(e,
|
|
513
|
-
const t = this.normalizeAuthIdentifier(e),
|
|
514
|
-
if (!
|
|
515
|
-
throw new
|
|
526
|
+
async initiateOTP(e, s) {
|
|
527
|
+
const t = this.normalizeAuthIdentifier(e), n = this.extractRealm(e, s), r = t.email, o = t.mobileNumber, l = t.username;
|
|
528
|
+
if (!r && !o && !l)
|
|
529
|
+
throw new p(
|
|
516
530
|
"identifier",
|
|
517
|
-
"Either mobileNumber or
|
|
531
|
+
"Either mobileNumber, email, or username is required"
|
|
518
532
|
);
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
const
|
|
522
|
-
body:
|
|
523
|
-
})).data;
|
|
533
|
+
const c = {};
|
|
534
|
+
r && (c.email = r), o && (c.mobileNumber = o), l && (c.username = l), n && (c.realm = n);
|
|
535
|
+
const i = (await this.request("POST", "/otp/initiate", {
|
|
536
|
+
body: c
|
|
537
|
+
})).data, h = i.data;
|
|
524
538
|
return {
|
|
525
|
-
message:
|
|
539
|
+
message: i.message,
|
|
540
|
+
success: i.success,
|
|
541
|
+
...h
|
|
526
542
|
};
|
|
527
543
|
}
|
|
528
544
|
/**
|
|
@@ -530,13 +546,13 @@ class U {
|
|
|
530
546
|
* Stores tokens from the response.
|
|
531
547
|
*/
|
|
532
548
|
async verifyOTP(e) {
|
|
533
|
-
const
|
|
549
|
+
const s = this.validateOTP(e), t = await this.getRequiredDPoPProof(
|
|
534
550
|
"POST",
|
|
535
551
|
`${this.getBaseUrl()}/otp/verify`
|
|
536
|
-
),
|
|
537
|
-
body: { otp:
|
|
552
|
+
), n = await this.request("POST", "/otp/verify", {
|
|
553
|
+
body: { otp: s },
|
|
538
554
|
headers: { DPoP: t }
|
|
539
|
-
}),
|
|
555
|
+
}), r = n.data.data ?? n.data, o = r.AuthenticationResult ?? r, l = o.access_token ?? o.accessToken ?? o.AccessToken, c = o.refresh_token ?? o.refreshToken ?? o.RefreshToken, d = o.expires_in ?? o.expiresIn, i = o.token_type ?? o.tokenType;
|
|
540
556
|
return l && await this.storeTokens({
|
|
541
557
|
accessToken: l,
|
|
542
558
|
refreshToken: c,
|
|
@@ -547,21 +563,21 @@ class U {
|
|
|
547
563
|
refresh_token: c,
|
|
548
564
|
expires_in: d,
|
|
549
565
|
token_type: i,
|
|
550
|
-
verified:
|
|
551
|
-
email:
|
|
552
|
-
...
|
|
566
|
+
verified: o.verified,
|
|
567
|
+
email: o.email ?? o.Email,
|
|
568
|
+
...o
|
|
553
569
|
};
|
|
554
570
|
}
|
|
555
571
|
/**
|
|
556
|
-
* POST /resend - Resend OTP code to the user's email.
|
|
572
|
+
* POST /otp/resend - Resend OTP code to the user's email or mobile number.
|
|
557
573
|
* No payload required, relies on auth_session cookie.
|
|
558
574
|
*/
|
|
559
575
|
async resendOTP() {
|
|
560
|
-
const
|
|
576
|
+
const s = (await this.request("POST", "/otp/resend", {})).data;
|
|
561
577
|
return {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
...
|
|
578
|
+
message: s.message,
|
|
579
|
+
success: s.success,
|
|
580
|
+
...s.data
|
|
565
581
|
};
|
|
566
582
|
}
|
|
567
583
|
/**
|
|
@@ -570,24 +586,24 @@ class U {
|
|
|
570
586
|
*/
|
|
571
587
|
async verifySignupOTP({
|
|
572
588
|
mobileNumber: e,
|
|
573
|
-
otp:
|
|
589
|
+
otp: s
|
|
574
590
|
}) {
|
|
575
|
-
const t = this.validateMobileNumber(e),
|
|
591
|
+
const t = this.validateMobileNumber(e), n = this.validateOTP(s), r = await this.getRequiredDPoPProof(
|
|
576
592
|
"POST",
|
|
577
593
|
`${this.getBaseUrl()}/otp/signup/verify`
|
|
578
|
-
),
|
|
579
|
-
body: { mobileNumber: t, otp:
|
|
580
|
-
headers: { DPoP:
|
|
581
|
-
}), l =
|
|
594
|
+
), o = await this.request("POST", "/otp/signup/verify", {
|
|
595
|
+
body: { mobileNumber: t, otp: n },
|
|
596
|
+
headers: { DPoP: r }
|
|
597
|
+
}), l = o.data.data ?? o.data, c = l.AuthenticationResult ?? l, d = c.access_token ?? c.accessToken ?? c.AccessToken, i = c.refresh_token ?? c.refreshToken ?? c.RefreshToken, h = c.expires_in ?? c.expiresIn, f = c.token_type ?? c.tokenType;
|
|
582
598
|
return d && await this.storeTokens({
|
|
583
599
|
accessToken: d,
|
|
584
600
|
refreshToken: i,
|
|
585
|
-
expiresIn:
|
|
601
|
+
expiresIn: h,
|
|
586
602
|
tokenType: f
|
|
587
603
|
}), {
|
|
588
604
|
access_token: d,
|
|
589
605
|
refresh_token: i,
|
|
590
|
-
expires_in:
|
|
606
|
+
expires_in: h,
|
|
591
607
|
token_type: f,
|
|
592
608
|
verified: c.verified,
|
|
593
609
|
email: c.email ?? c.Email,
|
|
@@ -599,15 +615,15 @@ class U {
|
|
|
599
615
|
*/
|
|
600
616
|
async resendSignupOTP({
|
|
601
617
|
mobileNumber: e,
|
|
602
|
-
email:
|
|
618
|
+
email: s = ""
|
|
603
619
|
}) {
|
|
604
|
-
const t = this.validateMobileNumber(e),
|
|
605
|
-
body: { email:
|
|
606
|
-
}),
|
|
620
|
+
const t = this.validateMobileNumber(e), n = s ? this.validateEmail(s) : "", r = await this.request("POST", "/otp/signup/resend", {
|
|
621
|
+
body: { email: n, mobileNumber: t }
|
|
622
|
+
}), o = r.data.data ?? r.data;
|
|
607
623
|
return {
|
|
608
|
-
success:
|
|
609
|
-
message:
|
|
610
|
-
...
|
|
624
|
+
success: o.success,
|
|
625
|
+
message: o.message,
|
|
626
|
+
...o
|
|
611
627
|
};
|
|
612
628
|
}
|
|
613
629
|
/**
|
|
@@ -615,10 +631,10 @@ class U {
|
|
|
615
631
|
* Sets auth_session cookie on success.
|
|
616
632
|
*/
|
|
617
633
|
async verifyMagicLink(e) {
|
|
618
|
-
const
|
|
634
|
+
const s = this.validateMagicLinkToken(e);
|
|
619
635
|
await this.request("GET", "/verify/magic-link", {
|
|
620
636
|
params: {
|
|
621
|
-
token:
|
|
637
|
+
token: s,
|
|
622
638
|
redirect_mode: "frontend"
|
|
623
639
|
}
|
|
624
640
|
});
|
|
@@ -635,16 +651,16 @@ class U {
|
|
|
635
651
|
{
|
|
636
652
|
body: {}
|
|
637
653
|
}
|
|
638
|
-
),
|
|
639
|
-
return
|
|
640
|
-
accessToken:
|
|
641
|
-
refreshToken:
|
|
642
|
-
expiresIn:
|
|
654
|
+
), s = e.data.data ?? e.data, t = s.AuthenticationResult ?? s, n = t.access_token ?? t.accessToken ?? t.AccessToken, r = t.refresh_token ?? t.refreshToken ?? t.RefreshToken, o = t.expires_in ?? t.expiresIn, l = t.token_type ?? t.tokenType;
|
|
655
|
+
return n && await this.storeTokens({
|
|
656
|
+
accessToken: n,
|
|
657
|
+
refreshToken: r,
|
|
658
|
+
expiresIn: o,
|
|
643
659
|
tokenType: l
|
|
644
660
|
}), {
|
|
645
|
-
access_token:
|
|
646
|
-
refresh_token:
|
|
647
|
-
expires_in:
|
|
661
|
+
access_token: n,
|
|
662
|
+
refresh_token: r,
|
|
663
|
+
expires_in: o,
|
|
648
664
|
token_type: l,
|
|
649
665
|
verified: t.verified,
|
|
650
666
|
email: t.email ?? t.Email,
|
|
@@ -662,38 +678,38 @@ class U {
|
|
|
662
678
|
return e.data.data ?? e.data;
|
|
663
679
|
}
|
|
664
680
|
async registerPasskey(e) {
|
|
665
|
-
const
|
|
666
|
-
let
|
|
681
|
+
const s = this.validateEmail(e), t = await this.initiatePasskeyRegistration();
|
|
682
|
+
let n;
|
|
667
683
|
if (t?.user?.id)
|
|
668
684
|
try {
|
|
669
|
-
|
|
685
|
+
n = b(t.user.id);
|
|
670
686
|
} catch {
|
|
671
|
-
|
|
687
|
+
n = k(t.user.id);
|
|
672
688
|
}
|
|
673
689
|
else
|
|
674
|
-
|
|
675
|
-
const
|
|
690
|
+
n = k(s);
|
|
691
|
+
const r = (t.pubKeyCredParams ?? [
|
|
676
692
|
{ type: "public-key", alg: -7 },
|
|
677
693
|
{ type: "public-key", alg: -257 }
|
|
678
694
|
]).map((w) => ({
|
|
679
695
|
type: "public-key",
|
|
680
696
|
alg: w.alg
|
|
681
|
-
})),
|
|
697
|
+
})), o = t.excludeCredentials?.map((w) => ({
|
|
682
698
|
type: "public-key",
|
|
683
|
-
id:
|
|
699
|
+
id: b(w)
|
|
684
700
|
})), l = {
|
|
685
|
-
challenge:
|
|
701
|
+
challenge: b(t.challenge),
|
|
686
702
|
rp: {
|
|
687
703
|
name: t.rp?.name ?? "XPay",
|
|
688
704
|
id: t.rp?.id ?? window.location.hostname
|
|
689
705
|
},
|
|
690
706
|
user: {
|
|
691
|
-
id:
|
|
692
|
-
name: t.user?.name ??
|
|
693
|
-
displayName: t.user?.displayName ??
|
|
707
|
+
id: n,
|
|
708
|
+
name: t.user?.name ?? s,
|
|
709
|
+
displayName: t.user?.displayName ?? s
|
|
694
710
|
},
|
|
695
|
-
pubKeyCredParams:
|
|
696
|
-
excludeCredentials:
|
|
711
|
+
pubKeyCredParams: r,
|
|
712
|
+
excludeCredentials: o,
|
|
697
713
|
timeout: t.timeout ?? 6e4,
|
|
698
714
|
attestation: "direct",
|
|
699
715
|
authenticatorSelection: {
|
|
@@ -706,12 +722,12 @@ class U {
|
|
|
706
722
|
});
|
|
707
723
|
if (!c) throw new Error("Credential creation failed");
|
|
708
724
|
const d = c.response, i = {
|
|
709
|
-
clientDataJSON:
|
|
710
|
-
attestationObject:
|
|
711
|
-
rawId:
|
|
725
|
+
clientDataJSON: y(d.clientDataJSON),
|
|
726
|
+
attestationObject: y(d.attestationObject),
|
|
727
|
+
rawId: y(c.rawId)
|
|
712
728
|
};
|
|
713
729
|
if (!i.rawId) throw new Error("Raw ID is required");
|
|
714
|
-
const
|
|
730
|
+
const h = await this.getRequiredDPoPProof(
|
|
715
731
|
"POST",
|
|
716
732
|
`${this.getBaseUrl()}/webauthn/register/challenge`
|
|
717
733
|
), f = await this.request(
|
|
@@ -719,7 +735,7 @@ class U {
|
|
|
719
735
|
"/webauthn/register/challenge",
|
|
720
736
|
{
|
|
721
737
|
body: i,
|
|
722
|
-
headers: { DPoP:
|
|
738
|
+
headers: { DPoP: h }
|
|
723
739
|
}
|
|
724
740
|
);
|
|
725
741
|
return f.data.data ?? f.data;
|
|
@@ -729,31 +745,31 @@ class U {
|
|
|
729
745
|
*/
|
|
730
746
|
async authenticateWithPasskey({
|
|
731
747
|
challenge: e,
|
|
732
|
-
rp:
|
|
748
|
+
rp: s,
|
|
733
749
|
credentialIds: t
|
|
734
750
|
}) {
|
|
735
|
-
const
|
|
751
|
+
const n = await navigator.credentials.get({
|
|
736
752
|
publicKey: {
|
|
737
|
-
challenge:
|
|
738
|
-
rpId:
|
|
753
|
+
challenge: b(e),
|
|
754
|
+
rpId: s?.host ?? void 0,
|
|
739
755
|
allowCredentials: t.map((w) => ({
|
|
740
756
|
type: "public-key",
|
|
741
|
-
id:
|
|
757
|
+
id: b(w),
|
|
742
758
|
transports: ["internal"]
|
|
743
759
|
})),
|
|
744
760
|
timeout: 6e4,
|
|
745
761
|
userVerification: "required"
|
|
746
762
|
}
|
|
747
763
|
});
|
|
748
|
-
if (!
|
|
749
|
-
const
|
|
750
|
-
clientDataJSON:
|
|
751
|
-
authenticatorData:
|
|
752
|
-
|
|
764
|
+
if (!n) throw new Error("Authentication failed");
|
|
765
|
+
const r = n.response, o = {
|
|
766
|
+
clientDataJSON: y(r.clientDataJSON),
|
|
767
|
+
authenticatorData: y(
|
|
768
|
+
r.authenticatorData
|
|
753
769
|
),
|
|
754
|
-
signature:
|
|
755
|
-
rawId:
|
|
756
|
-
userHandle:
|
|
770
|
+
signature: y(r.signature),
|
|
771
|
+
rawId: y(n.rawId),
|
|
772
|
+
userHandle: r.userHandle ? y(r.userHandle) : ""
|
|
757
773
|
}, l = await this.getRequiredDPoPProof(
|
|
758
774
|
"POST",
|
|
759
775
|
`${this.getBaseUrl()}/webauthn/authenticate/challenge`
|
|
@@ -761,17 +777,17 @@ class U {
|
|
|
761
777
|
"POST",
|
|
762
778
|
"/webauthn/authenticate/challenge",
|
|
763
779
|
{
|
|
764
|
-
body:
|
|
780
|
+
body: o,
|
|
765
781
|
headers: { DPoP: l }
|
|
766
782
|
}
|
|
767
|
-
), d = c.data.data ?? c.data, i = d.AuthenticationResult ?? d,
|
|
768
|
-
return
|
|
769
|
-
accessToken:
|
|
783
|
+
), d = c.data.data ?? c.data, i = d.AuthenticationResult ?? d, h = i.AccessToken ?? i.accessToken ?? i.access_token, f = i.RefreshToken ?? i.refreshToken ?? i.refresh_token;
|
|
784
|
+
return h && await this.storeTokens({
|
|
785
|
+
accessToken: h,
|
|
770
786
|
refreshToken: f,
|
|
771
787
|
expiresIn: i.expiresIn ?? i.ExpiresIn,
|
|
772
788
|
tokenType: i.tokenType ?? i.token_type
|
|
773
789
|
}), {
|
|
774
|
-
access_token:
|
|
790
|
+
access_token: h,
|
|
775
791
|
refresh_token: f,
|
|
776
792
|
email: i.email,
|
|
777
793
|
name: i.name ?? i.userName,
|
|
@@ -784,50 +800,50 @@ class U {
|
|
|
784
800
|
* GET /webauthn/credentials/:username - Get user's passkey status.
|
|
785
801
|
*/
|
|
786
802
|
async getPasskeyStatus(e) {
|
|
787
|
-
const t = `/webauthn/credentials/${encodeURIComponent(e)}`,
|
|
788
|
-
headers:
|
|
789
|
-
}),
|
|
803
|
+
const t = `/webauthn/credentials/${encodeURIComponent(e)}`, n = await this.signRequest("GET", t), r = await this.request("GET", t, {
|
|
804
|
+
headers: n.headers
|
|
805
|
+
}), o = r.data.data ?? r.data;
|
|
790
806
|
return {
|
|
791
|
-
...
|
|
792
|
-
hasCredentials: !!(
|
|
807
|
+
...o,
|
|
808
|
+
hasCredentials: !!(o.hasCredentials ?? o.credentialId)
|
|
793
809
|
};
|
|
794
810
|
}
|
|
795
811
|
/**
|
|
796
812
|
* DELETE /webauthn/credentials/:username - Remove passkey.
|
|
797
813
|
*/
|
|
798
814
|
async removePasskey(e) {
|
|
799
|
-
const t = `/webauthn/credentials/${encodeURIComponent(e)}`,
|
|
815
|
+
const t = `/webauthn/credentials/${encodeURIComponent(e)}`, n = await this.signRequest("DELETE", t);
|
|
800
816
|
await this.request("DELETE", t, {
|
|
801
|
-
headers:
|
|
817
|
+
headers: n.headers
|
|
802
818
|
});
|
|
803
819
|
}
|
|
804
820
|
/**
|
|
805
821
|
* Signs a request with DPoP and Authorization headers (internal use).
|
|
806
822
|
*/
|
|
807
|
-
async signRequest(e,
|
|
808
|
-
const
|
|
809
|
-
return { ...t, headers: { ...t.headers, ...
|
|
823
|
+
async signRequest(e, s, t = {}) {
|
|
824
|
+
const n = s.startsWith("http") ? s : `${this.getBaseUrl()}${s}`, r = await this.getRequestAuthHeaders(e, n);
|
|
825
|
+
return { ...t, headers: { ...t.headers, ...r } };
|
|
810
826
|
}
|
|
811
827
|
/**
|
|
812
828
|
* Replaces native fetch or Axios with a DPoP-signed version.
|
|
813
829
|
*/
|
|
814
|
-
async authenticatedFetch(e,
|
|
815
|
-
const t = typeof e == "string" ? e : e instanceof URL ? e.toString() : e.url,
|
|
816
|
-
headers:
|
|
830
|
+
async authenticatedFetch(e, s) {
|
|
831
|
+
const t = typeof e == "string" ? e : e instanceof URL ? e.toString() : e.url, n = s?.method || "GET", r = await this.signRequest(n, t, {
|
|
832
|
+
headers: s?.headers
|
|
817
833
|
});
|
|
818
|
-
return fetch(e, { ...
|
|
834
|
+
return fetch(e, { ...s, headers: r.headers });
|
|
819
835
|
}
|
|
820
836
|
/**
|
|
821
837
|
* Store tokens from /webauthn/authenticate (per spec: sessionStorage preferred).
|
|
822
838
|
*/
|
|
823
839
|
async storeTokens(e) {
|
|
824
|
-
localStorage.setItem(
|
|
840
|
+
localStorage.setItem(P, e.accessToken), e.refreshToken && localStorage.setItem(R, e.refreshToken);
|
|
825
841
|
}
|
|
826
842
|
/**
|
|
827
843
|
* Clear stored tokens (call on logout).
|
|
828
844
|
*/
|
|
829
845
|
async clearTokens() {
|
|
830
|
-
localStorage.removeItem(
|
|
846
|
+
localStorage.removeItem(P), localStorage.removeItem(R);
|
|
831
847
|
}
|
|
832
848
|
/**
|
|
833
849
|
* POST /auth/refresh - Refresh access token using server-stored refresh token.
|
|
@@ -835,16 +851,16 @@ class U {
|
|
|
835
851
|
* Rate limit: 10 requests per minute.
|
|
836
852
|
*/
|
|
837
853
|
async refreshToken(e) {
|
|
838
|
-
const
|
|
839
|
-
body:
|
|
840
|
-
}),
|
|
841
|
-
return
|
|
842
|
-
accessToken:
|
|
854
|
+
const s = this.extractRealm(void 0, e), t = await this.request("POST", "/auth/refresh", {
|
|
855
|
+
body: s ? { realm: s } : {}
|
|
856
|
+
}), n = t.data.data ?? t.data, r = n.access_token, o = n.token_type, l = n.expires_in;
|
|
857
|
+
return r && await this.storeTokens({
|
|
858
|
+
accessToken: r,
|
|
843
859
|
expiresIn: l,
|
|
844
|
-
tokenType:
|
|
860
|
+
tokenType: o
|
|
845
861
|
}), {
|
|
846
|
-
access_token:
|
|
847
|
-
token_type:
|
|
862
|
+
access_token: r,
|
|
863
|
+
token_type: o,
|
|
848
864
|
expires_in: l
|
|
849
865
|
};
|
|
850
866
|
}
|
|
@@ -854,35 +870,35 @@ class U {
|
|
|
854
870
|
*/
|
|
855
871
|
async logout() {
|
|
856
872
|
try {
|
|
857
|
-
const
|
|
858
|
-
await this.request("POST", "/auth/logout",
|
|
873
|
+
const s = await this.getAccessToken() ? await this.signRequest("POST", "/auth/logout", { body: {} }) : { body: {} };
|
|
874
|
+
await this.request("POST", "/auth/logout", s), await T(), this.resetDPoPInitialization();
|
|
859
875
|
} catch {
|
|
860
876
|
}
|
|
861
877
|
await this.clearTokens();
|
|
862
878
|
}
|
|
863
879
|
async getAccessToken() {
|
|
864
|
-
return localStorage.getItem(
|
|
880
|
+
return localStorage.getItem(P);
|
|
865
881
|
}
|
|
866
882
|
}
|
|
867
|
-
typeof window < "u" && (window.AuthSDK =
|
|
868
|
-
const
|
|
869
|
-
|
|
883
|
+
typeof window < "u" && (window.AuthSDK = z);
|
|
884
|
+
const be = typeof window < "u" ? window : globalThis;
|
|
885
|
+
be.AuthSDK = z;
|
|
870
886
|
export {
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
887
|
+
z as AuthSDK,
|
|
888
|
+
we as AuthSDKFetchError,
|
|
889
|
+
p as SDKValidationError,
|
|
890
|
+
N as arrayBufferToBase64,
|
|
891
|
+
y as arrayBufferToBase64url,
|
|
876
892
|
C as base64ToArrayBuffer,
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
893
|
+
b as base64urlToArrayBuffer,
|
|
894
|
+
X as clearPasskeyEmail,
|
|
895
|
+
ee as clearPasskeyMobileNumber,
|
|
896
|
+
Y as getPasskeyEmail,
|
|
897
|
+
Z as getPasskeyMobileNumber,
|
|
898
|
+
j as isConditionalUISupported,
|
|
899
|
+
O as isWebAuthnSupported,
|
|
900
|
+
V as setPasskeyEmail,
|
|
901
|
+
Q as setPasskeyMobileNumber,
|
|
886
902
|
k as stringToArrayBuffer,
|
|
887
|
-
|
|
903
|
+
F as uint8ArrayToString
|
|
888
904
|
};
|