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