postex-auth-sdk-stage 1.3.2 → 2.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/dist/auth.d.ts +15 -17
- package/dist/postex-auth-sdk-stage.es.js +219 -209
- package/dist/postex-auth-sdk-stage.es.js.map +1 -1
- package/dist/postex-auth-sdk-stage.iife.js +1 -1
- package/dist/postex-auth-sdk-stage.iife.js.map +1 -1
- package/dist/postex-auth-sdk-stage.umd.js +1 -1
- package/dist/postex-auth-sdk-stage.umd.js.map +1 -1
- package/package.json +6 -6
|
@@ -16,22 +16,22 @@ function y(a) {
|
|
|
16
16
|
n += String.fromCharCode(e[t]);
|
|
17
17
|
return btoa(n);
|
|
18
18
|
}
|
|
19
|
-
function
|
|
19
|
+
function m(a) {
|
|
20
20
|
if (typeof a != "string" || !a)
|
|
21
21
|
throw new Error("Invalid base64: expected non-empty string");
|
|
22
22
|
const e = a.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 o = 0; o <
|
|
26
|
-
|
|
27
|
-
return
|
|
24
|
+
const s = atob(t), r = new Uint8Array(s.length);
|
|
25
|
+
for (let o = 0; o < s.length; o++)
|
|
26
|
+
r[o] = s.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
|
|
34
|
+
function w(a) {
|
|
35
35
|
return y(a).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
36
36
|
}
|
|
37
37
|
function J(a) {
|
|
@@ -48,7 +48,7 @@ function L(a) {
|
|
|
48
48
|
function M(a) {
|
|
49
49
|
if (!a || typeof a != "string")
|
|
50
50
|
throw new Error("Invalid input: expected non-empty string");
|
|
51
|
-
return J(a) ? L(a) :
|
|
51
|
+
return J(a) ? L(a) : m(a);
|
|
52
52
|
}
|
|
53
53
|
function _(a) {
|
|
54
54
|
return new TextEncoder().encode(a).buffer;
|
|
@@ -56,53 +56,53 @@ function _(a) {
|
|
|
56
56
|
function W(a) {
|
|
57
57
|
return String.fromCharCode(...a);
|
|
58
58
|
}
|
|
59
|
-
const H = "xpay_webauthn", Y = 1,
|
|
59
|
+
const H = "xpay_webauthn", Y = 1, l = "passkey_data", S = "passkey_email", x = "passkey_mobile_number";
|
|
60
60
|
function h() {
|
|
61
61
|
return new Promise((a, e) => {
|
|
62
62
|
const n = indexedDB.open(H, Y);
|
|
63
63
|
n.onerror = () => e(n.error), n.onsuccess = () => a(n.result), n.onupgradeneeded = () => {
|
|
64
64
|
const t = n.result;
|
|
65
|
-
t.objectStoreNames.contains(
|
|
65
|
+
t.objectStoreNames.contains(l) || t.createObjectStore(l);
|
|
66
66
|
};
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
-
async function
|
|
69
|
+
async function z() {
|
|
70
70
|
try {
|
|
71
71
|
const a = await h();
|
|
72
72
|
return new Promise((e, n) => {
|
|
73
|
-
const t = a.transaction(
|
|
74
|
-
|
|
73
|
+
const t = a.transaction(l, "readonly"), r = t.objectStore(l).get(S);
|
|
74
|
+
r.onerror = () => n(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 F(a) {
|
|
81
81
|
try {
|
|
82
82
|
const e = await h();
|
|
83
83
|
return new Promise((n, t) => {
|
|
84
|
-
const
|
|
85
|
-
o.onerror = () => t(o.error), o.onsuccess = () => n(),
|
|
84
|
+
const s = e.transaction(l, "readwrite"), o = s.objectStore(l).put(a, S);
|
|
85
|
+
o.onerror = () => t(o.error), o.onsuccess = () => n(), s.oncomplete = () => e.close();
|
|
86
86
|
});
|
|
87
87
|
} catch {
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
async function
|
|
90
|
+
async function G() {
|
|
91
91
|
try {
|
|
92
92
|
const a = await h();
|
|
93
93
|
return new Promise((e, n) => {
|
|
94
|
-
const t = a.transaction(
|
|
95
|
-
|
|
94
|
+
const t = a.transaction(l, "readwrite"), r = t.objectStore(l).delete(S);
|
|
95
|
+
r.onerror = () => n(r.error), r.onsuccess = () => e(), t.oncomplete = () => a.close();
|
|
96
96
|
});
|
|
97
97
|
} catch {
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
async function
|
|
100
|
+
async function V() {
|
|
101
101
|
try {
|
|
102
102
|
const a = await h();
|
|
103
103
|
return new Promise((e, n) => {
|
|
104
|
-
const t = a.transaction(
|
|
105
|
-
|
|
104
|
+
const t = a.transaction(l, "readonly"), r = t.objectStore(l).get(x);
|
|
105
|
+
r.onerror = () => n(r.error), r.onsuccess = () => e(r.result ?? null), t.oncomplete = () => a.close();
|
|
106
106
|
});
|
|
107
107
|
} catch {
|
|
108
108
|
return null;
|
|
@@ -112,8 +112,8 @@ async function X(a) {
|
|
|
112
112
|
try {
|
|
113
113
|
const e = await h();
|
|
114
114
|
return new Promise((n, t) => {
|
|
115
|
-
const
|
|
116
|
-
o.onerror = () => t(o.error), o.onsuccess = () => n(),
|
|
115
|
+
const s = e.transaction(l, "readwrite"), o = s.objectStore(l).put(a, x);
|
|
116
|
+
o.onerror = () => t(o.error), o.onsuccess = () => n(), s.oncomplete = () => e.close();
|
|
117
117
|
});
|
|
118
118
|
} catch {
|
|
119
119
|
}
|
|
@@ -122,13 +122,13 @@ async function Q() {
|
|
|
122
122
|
try {
|
|
123
123
|
const a = await h();
|
|
124
124
|
return new Promise((e, n) => {
|
|
125
|
-
const t = a.transaction(
|
|
126
|
-
|
|
125
|
+
const t = a.transaction(l, "readwrite"), r = t.objectStore(l).delete(x);
|
|
126
|
+
r.onerror = () => n(r.error), r.onsuccess = () => e(), t.oncomplete = () => a.close();
|
|
127
127
|
});
|
|
128
128
|
} catch {
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
-
const
|
|
131
|
+
const E = "dpop_private_key", I = "dpop_public_key_jwk";
|
|
132
132
|
function D(a) {
|
|
133
133
|
return {
|
|
134
134
|
kty: "EC",
|
|
@@ -147,14 +147,14 @@ async function q(a) {
|
|
|
147
147
|
"SHA-256",
|
|
148
148
|
new TextEncoder().encode(e)
|
|
149
149
|
);
|
|
150
|
-
return
|
|
150
|
+
return w(n);
|
|
151
151
|
}
|
|
152
152
|
async function B(a) {
|
|
153
153
|
try {
|
|
154
154
|
const e = await h();
|
|
155
155
|
return new Promise((n, t) => {
|
|
156
|
-
const
|
|
157
|
-
o.onerror = () => t(o.error), o.onsuccess = () => n(),
|
|
156
|
+
const s = e.transaction(l, "readwrite"), o = s.objectStore(l).put(a, E);
|
|
157
|
+
o.onerror = () => t(o.error), o.onsuccess = () => n(), s.oncomplete = () => e.close();
|
|
158
158
|
});
|
|
159
159
|
} catch (e) {
|
|
160
160
|
console.error("Failed to store DPoP private key:", e);
|
|
@@ -164,8 +164,8 @@ async function Z(a) {
|
|
|
164
164
|
try {
|
|
165
165
|
const e = await h();
|
|
166
166
|
return new Promise((n, t) => {
|
|
167
|
-
const
|
|
168
|
-
o.onerror = () => t(o.error), o.onsuccess = () => n(),
|
|
167
|
+
const s = e.transaction(l, "readwrite"), o = s.objectStore(l).put(a, I);
|
|
168
|
+
o.onerror = () => t(o.error), o.onsuccess = () => n(), s.oncomplete = () => e.close();
|
|
169
169
|
});
|
|
170
170
|
} catch (e) {
|
|
171
171
|
console.error("Failed to store DPoP public key JWK:", e);
|
|
@@ -175,8 +175,8 @@ async function A() {
|
|
|
175
175
|
try {
|
|
176
176
|
const a = await h();
|
|
177
177
|
return new Promise((e, n) => {
|
|
178
|
-
const t = a.transaction(
|
|
179
|
-
|
|
178
|
+
const t = a.transaction(l, "readonly"), r = t.objectStore(l).get(E);
|
|
179
|
+
r.onerror = () => n(r.error), r.onsuccess = () => e(r.result ?? null), t.oncomplete = () => a.close();
|
|
180
180
|
});
|
|
181
181
|
} catch {
|
|
182
182
|
return null;
|
|
@@ -186,8 +186,8 @@ async function R() {
|
|
|
186
186
|
try {
|
|
187
187
|
const a = await h();
|
|
188
188
|
return new Promise((e, n) => {
|
|
189
|
-
const t = a.transaction(
|
|
190
|
-
|
|
189
|
+
const t = a.transaction(l, "readonly"), r = t.objectStore(l).get(I);
|
|
190
|
+
r.onerror = () => n(r.error), r.onsuccess = () => e(r.result ?? null), t.oncomplete = () => a.close();
|
|
191
191
|
});
|
|
192
192
|
} catch {
|
|
193
193
|
return null;
|
|
@@ -197,8 +197,8 @@ async function N() {
|
|
|
197
197
|
try {
|
|
198
198
|
const a = await h();
|
|
199
199
|
return new Promise((e, n) => {
|
|
200
|
-
const t = a.transaction(
|
|
201
|
-
|
|
200
|
+
const t = a.transaction(l, "readwrite"), s = t.objectStore(l);
|
|
201
|
+
s.delete(E), s.delete(I), t.onerror = () => n(t.error), t.oncomplete = () => {
|
|
202
202
|
a.close(), e();
|
|
203
203
|
};
|
|
204
204
|
});
|
|
@@ -217,41 +217,41 @@ async function g() {
|
|
|
217
217
|
), e = await crypto.subtle.exportKey("jwk", a.publicKey), n = D(e), t = await q(n);
|
|
218
218
|
return await B(a.privateKey), await Z(n), { publicKey: n, thumbprint: t };
|
|
219
219
|
}
|
|
220
|
-
async function
|
|
220
|
+
async function k(a, e, n) {
|
|
221
221
|
try {
|
|
222
|
-
const t = await A(),
|
|
223
|
-
if (!t || !
|
|
224
|
-
const
|
|
222
|
+
const t = await A(), s = await R();
|
|
223
|
+
if (!t || !s) return null;
|
|
224
|
+
const r = {
|
|
225
225
|
typ: "dpop+jwt",
|
|
226
226
|
alg: "ES256",
|
|
227
|
-
jwk:
|
|
227
|
+
jwk: s
|
|
228
228
|
// Public key in JWK format
|
|
229
229
|
}, o = new URL(
|
|
230
230
|
e,
|
|
231
231
|
typeof window < "u" ? window.location.origin : void 0
|
|
232
|
-
),
|
|
232
|
+
), i = `${o.origin}${o.pathname}`, u = {
|
|
233
233
|
jti: crypto.randomUUID(),
|
|
234
234
|
htm: a.toUpperCase(),
|
|
235
|
-
htu:
|
|
235
|
+
htu: i,
|
|
236
236
|
iat: Math.floor(Date.now() / 1e3)
|
|
237
237
|
};
|
|
238
238
|
if (n) {
|
|
239
239
|
const P = new TextEncoder().encode(n), $ = await crypto.subtle.digest("SHA-256", P);
|
|
240
|
-
|
|
240
|
+
u.ath = w($);
|
|
241
241
|
}
|
|
242
|
-
const
|
|
243
|
-
new TextEncoder().encode(JSON.stringify(
|
|
244
|
-
),
|
|
245
|
-
new TextEncoder().encode(JSON.stringify(
|
|
246
|
-
), p = `${
|
|
242
|
+
const d = w(
|
|
243
|
+
new TextEncoder().encode(JSON.stringify(r)).buffer
|
|
244
|
+
), c = w(
|
|
245
|
+
new TextEncoder().encode(JSON.stringify(u)).buffer
|
|
246
|
+
), p = `${d}.${c}`, f = await crypto.subtle.sign(
|
|
247
247
|
{
|
|
248
248
|
name: "ECDSA",
|
|
249
249
|
hash: { name: "SHA-256" }
|
|
250
250
|
},
|
|
251
251
|
t,
|
|
252
252
|
new TextEncoder().encode(p)
|
|
253
|
-
), b =
|
|
254
|
-
return `${
|
|
253
|
+
), b = w(f);
|
|
254
|
+
return `${d}.${c}.${b}`;
|
|
255
255
|
} catch (t) {
|
|
256
256
|
return console.error("Failed to generate DPoP proof:", t), null;
|
|
257
257
|
}
|
|
@@ -263,15 +263,15 @@ const te = B, U = {
|
|
|
263
263
|
isWebAuthnSupported: K,
|
|
264
264
|
isConditionalUISupported: j,
|
|
265
265
|
arrayBufferToBase64: y,
|
|
266
|
-
base64ToArrayBuffer:
|
|
267
|
-
arrayBufferToBase64url:
|
|
266
|
+
base64ToArrayBuffer: m,
|
|
267
|
+
arrayBufferToBase64url: w,
|
|
268
268
|
base64urlToArrayBuffer: M,
|
|
269
269
|
stringToArrayBuffer: _,
|
|
270
270
|
uint8ArrayToString: W,
|
|
271
|
-
getPasskeyEmail:
|
|
272
|
-
setPasskeyEmail:
|
|
273
|
-
clearPasskeyEmail:
|
|
274
|
-
getPasskeyMobileNumber:
|
|
271
|
+
getPasskeyEmail: z,
|
|
272
|
+
setPasskeyEmail: F,
|
|
273
|
+
clearPasskeyEmail: G,
|
|
274
|
+
getPasskeyMobileNumber: V,
|
|
275
275
|
setPasskeyMobileNumber: X,
|
|
276
276
|
clearPasskeyMobileNumber: Q,
|
|
277
277
|
toMinimalJWK: D,
|
|
@@ -280,14 +280,14 @@ const te = B, U = {
|
|
|
280
280
|
getDPoPPublicKeyJWK: R,
|
|
281
281
|
clearDPoPKey: N,
|
|
282
282
|
generateDPoPKeyPair: g,
|
|
283
|
-
generateDPoPProof:
|
|
283
|
+
generateDPoPProof: k,
|
|
284
284
|
isDPoPEnabled: ee,
|
|
285
285
|
storeDPoPKey: te
|
|
286
286
|
};
|
|
287
287
|
typeof window < "u" && (window.WebAuthn = U);
|
|
288
288
|
const ne = typeof window < "u" ? window : globalThis;
|
|
289
289
|
ne.WebAuthn = U;
|
|
290
|
-
const T = "postex-auth-token",
|
|
290
|
+
const T = "postex-auth-token", re = "postexglobal", se = {
|
|
291
291
|
xstak: "https://auth-stage.xstak.com/public/v1",
|
|
292
292
|
postex: "https://auth-stage.postex.pk/public/v1",
|
|
293
293
|
callcourier: "https://auth-stage.callcourier.com.pk/public/v1",
|
|
@@ -299,14 +299,14 @@ class oe extends Error {
|
|
|
299
299
|
super(t ?? `Request failed with status ${e}`), this.response = { status: e, data: n }, this.name = "AuthSDKFetchError";
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
|
-
const
|
|
302
|
+
const v = "auth_sdk_id_token", O = "auth_sdk_refresh_token";
|
|
303
303
|
class C {
|
|
304
304
|
constructor(e) {
|
|
305
305
|
this.config = e;
|
|
306
306
|
}
|
|
307
307
|
getBaseUrl() {
|
|
308
|
-
const e = this.config.appId ??
|
|
309
|
-
return
|
|
308
|
+
const e = this.config.appId ?? re;
|
|
309
|
+
return se[e];
|
|
310
310
|
}
|
|
311
311
|
normalizeAuthIdentifier(e) {
|
|
312
312
|
return typeof e == "string" ? { email: e } : {
|
|
@@ -314,14 +314,24 @@ class C {
|
|
|
314
314
|
mobileNumber: e.mobileNumber
|
|
315
315
|
};
|
|
316
316
|
}
|
|
317
|
+
extractRealm(e, n) {
|
|
318
|
+
return (n?.realm ?? (e && typeof e != "string" ? e.realm : void 0))?.trim() || void 0;
|
|
319
|
+
}
|
|
320
|
+
buildAuthRequestBody(e, n) {
|
|
321
|
+
const t = this.normalizeAuthIdentifier(e), s = this.extractRealm(e, n);
|
|
322
|
+
return {
|
|
323
|
+
...t,
|
|
324
|
+
...s ? { realm: s } : {}
|
|
325
|
+
};
|
|
326
|
+
}
|
|
317
327
|
buildUrl(e, n) {
|
|
318
|
-
const t = this.getBaseUrl().replace(/\/$/, ""),
|
|
319
|
-
if (!n || Object.keys(n).length === 0) return
|
|
328
|
+
const t = this.getBaseUrl().replace(/\/$/, ""), s = e.startsWith("/") ? e : `/${e}`, r = `${t}${s}`;
|
|
329
|
+
if (!n || Object.keys(n).length === 0) return r;
|
|
320
330
|
const o = new URLSearchParams(n).toString();
|
|
321
|
-
return `${
|
|
331
|
+
return `${r}?${o}`;
|
|
322
332
|
}
|
|
323
333
|
async request(e, n, t) {
|
|
324
|
-
const
|
|
334
|
+
const s = this.buildUrl(n, t?.params), r = {
|
|
325
335
|
"Content-Type": "application/json",
|
|
326
336
|
Accept: "application/json",
|
|
327
337
|
"X-API-Key": this.config.apiKey ?? "",
|
|
@@ -329,22 +339,22 @@ class C {
|
|
|
329
339
|
}, o = {
|
|
330
340
|
method: e,
|
|
331
341
|
credentials: "include",
|
|
332
|
-
headers:
|
|
342
|
+
headers: r
|
|
333
343
|
};
|
|
334
344
|
t?.body !== void 0 && t?.body !== null && (o.body = JSON.stringify(t.body));
|
|
335
|
-
const
|
|
336
|
-
if (!
|
|
337
|
-
let
|
|
345
|
+
const i = await fetch(s, o);
|
|
346
|
+
if (!i.ok) {
|
|
347
|
+
let c;
|
|
338
348
|
try {
|
|
339
|
-
const p = await
|
|
340
|
-
|
|
349
|
+
const p = await i.text();
|
|
350
|
+
c = p ? JSON.parse(p) : void 0;
|
|
341
351
|
} catch {
|
|
342
|
-
|
|
352
|
+
c = void 0;
|
|
343
353
|
}
|
|
344
|
-
throw
|
|
354
|
+
throw i.status === 401 && await this.clearTokens(), new oe(i.status, c);
|
|
345
355
|
}
|
|
346
|
-
const
|
|
347
|
-
return { data:
|
|
356
|
+
const u = await i.text();
|
|
357
|
+
return { data: u ? JSON.parse(u) : {} };
|
|
348
358
|
}
|
|
349
359
|
/**
|
|
350
360
|
* Returns auth headers (Authorization + DPoP) for the given request.
|
|
@@ -355,35 +365,35 @@ class C {
|
|
|
355
365
|
async getRequestAuthHeaders(e, n) {
|
|
356
366
|
const t = localStorage.getItem(T);
|
|
357
367
|
if (!t) return {};
|
|
358
|
-
const
|
|
368
|
+
const s = n.startsWith("http") ? n : `${this.getBaseUrl()}${n}`, r = await k(
|
|
359
369
|
e.toUpperCase(),
|
|
360
|
-
|
|
370
|
+
s,
|
|
361
371
|
t
|
|
362
372
|
), o = {
|
|
363
373
|
Authorization: `Bearer ${t}`
|
|
364
374
|
};
|
|
365
|
-
return
|
|
375
|
+
return r && (o.DPoP = r), o;
|
|
366
376
|
}
|
|
367
377
|
/**
|
|
368
378
|
* GET /auth/status - Check if client has trusted device session and what auth method is available.
|
|
369
379
|
* Returns no_session | session_found | webauthn_ready per PostEx Auth BFF spec.
|
|
370
380
|
*/
|
|
371
|
-
async getStatus(e) {
|
|
372
|
-
const n = {};
|
|
373
|
-
|
|
374
|
-
const
|
|
375
|
-
params:
|
|
381
|
+
async getStatus(e, n) {
|
|
382
|
+
const t = this.normalizeAuthIdentifier(e), s = this.extractRealm(e, n), r = {};
|
|
383
|
+
t.email && (r.email = t.email), t.mobileNumber && (r.mobileNumber = t.mobileNumber), s && (r.realm = s);
|
|
384
|
+
const o = await this.request("GET", "/auth/status", {
|
|
385
|
+
params: r
|
|
376
386
|
});
|
|
377
|
-
return
|
|
387
|
+
return o.data.data ?? o.data;
|
|
378
388
|
}
|
|
379
389
|
/**
|
|
380
390
|
* POST /auth/initiate - Unified entry: returns webauthn_challenge or otp_sent.
|
|
381
391
|
* Sets auth_session cookie when otp_sent.
|
|
382
392
|
*/
|
|
383
|
-
async initiateAuth(e) {
|
|
384
|
-
const
|
|
385
|
-
body:
|
|
386
|
-
}), r =
|
|
393
|
+
async initiateAuth(e, n) {
|
|
394
|
+
const t = this.buildAuthRequestBody(e, n), s = await this.request("POST", "/auth/initiate", {
|
|
395
|
+
body: t
|
|
396
|
+
}), r = s.data.data ?? s.data;
|
|
387
397
|
return {
|
|
388
398
|
status: r.status,
|
|
389
399
|
challenge: r.challenge,
|
|
@@ -395,17 +405,17 @@ class C {
|
|
|
395
405
|
* POST /otp/initiate - Direct OTP initiation using email or mobile number.
|
|
396
406
|
* Requires at least one identifier: email or mobileNumber.
|
|
397
407
|
*/
|
|
398
|
-
async initiateOTP(e) {
|
|
399
|
-
const
|
|
400
|
-
if (!
|
|
408
|
+
async initiateOTP(e, n) {
|
|
409
|
+
const t = this.normalizeAuthIdentifier(e), s = this.extractRealm(e, n), r = t.email?.trim(), o = t.mobileNumber?.trim();
|
|
410
|
+
if (!r && !o)
|
|
401
411
|
throw new Error("Either mobileNumber or email is required");
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
const
|
|
405
|
-
body:
|
|
412
|
+
const i = {};
|
|
413
|
+
r && (i.email = r), o && (i.mobileNumber = o), s && (i.realm = s);
|
|
414
|
+
const d = (await this.request("POST", "/otp/initiate", {
|
|
415
|
+
body: i
|
|
406
416
|
})).data;
|
|
407
417
|
return {
|
|
408
|
-
message:
|
|
418
|
+
message: d.message ?? d.data?.message
|
|
409
419
|
};
|
|
410
420
|
}
|
|
411
421
|
/**
|
|
@@ -414,28 +424,28 @@ class C {
|
|
|
414
424
|
*/
|
|
415
425
|
async verifyOTP(e) {
|
|
416
426
|
await g();
|
|
417
|
-
const n = await
|
|
427
|
+
const n = await k(
|
|
418
428
|
"POST",
|
|
419
429
|
`${this.getBaseUrl()}/otp/verify`
|
|
420
430
|
), t = await this.request("POST", "/otp/verify", {
|
|
421
431
|
body: { otp: e },
|
|
422
432
|
headers: n ? { DPoP: n } : {}
|
|
423
|
-
}),
|
|
433
|
+
}), s = t.data.data ?? t.data, r = s.AuthenticationResult ?? s, o = r.access_token ?? r.accessToken ?? r.AccessToken, i = r.refresh_token ?? r.refreshToken ?? r.RefreshToken, u = r.id_token ?? r.idToken ?? r.IdToken, d = r.expires_in ?? r.expiresIn ?? r.ExpiresIn ?? 3600, c = r.token_type ?? r.tokenType ?? r.TokenType ?? "Bearer";
|
|
424
434
|
return o && await this.storeTokens({
|
|
425
435
|
accessToken: o,
|
|
426
|
-
refreshToken:
|
|
427
|
-
idToken:
|
|
428
|
-
expiresIn:
|
|
429
|
-
tokenType:
|
|
436
|
+
refreshToken: i ?? "",
|
|
437
|
+
idToken: u ?? "",
|
|
438
|
+
expiresIn: d ?? 3600,
|
|
439
|
+
tokenType: c ?? "Bearer"
|
|
430
440
|
}), {
|
|
431
441
|
access_token: o,
|
|
432
|
-
refresh_token:
|
|
433
|
-
id_token:
|
|
434
|
-
expires_in:
|
|
435
|
-
token_type:
|
|
436
|
-
verified:
|
|
437
|
-
email:
|
|
438
|
-
...
|
|
442
|
+
refresh_token: i ?? "",
|
|
443
|
+
id_token: u ?? "",
|
|
444
|
+
expires_in: d,
|
|
445
|
+
token_type: c,
|
|
446
|
+
verified: r.verified,
|
|
447
|
+
email: r.email ?? r.Email ?? "",
|
|
448
|
+
...r
|
|
439
449
|
};
|
|
440
450
|
}
|
|
441
451
|
/**
|
|
@@ -445,7 +455,7 @@ class C {
|
|
|
445
455
|
async resendOTP() {
|
|
446
456
|
const e = await this.request("POST", "/otp/resend", {}), n = e.data.data ?? e.data;
|
|
447
457
|
return {
|
|
448
|
-
success: n.success
|
|
458
|
+
success: n.success,
|
|
449
459
|
message: n.message,
|
|
450
460
|
...n
|
|
451
461
|
};
|
|
@@ -459,26 +469,26 @@ class C {
|
|
|
459
469
|
otp: n
|
|
460
470
|
}) {
|
|
461
471
|
await g();
|
|
462
|
-
const t = await
|
|
472
|
+
const t = await k(
|
|
463
473
|
"POST",
|
|
464
474
|
`${this.getBaseUrl()}/otp/signup/verify`
|
|
465
|
-
),
|
|
475
|
+
), s = await this.request("POST", "/otp/signup/verify", {
|
|
466
476
|
body: { mobileNumber: e, otp: n },
|
|
467
477
|
headers: t ? { DPoP: t } : {}
|
|
468
|
-
}),
|
|
469
|
-
return
|
|
470
|
-
accessToken:
|
|
471
|
-
refreshToken:
|
|
472
|
-
idToken:
|
|
473
|
-
expiresIn:
|
|
478
|
+
}), r = s.data.data ?? s.data, o = r.AuthenticationResult ?? r, i = o.access_token ?? o.accessToken ?? o.AccessToken, u = o.refresh_token ?? o.refreshToken ?? o.RefreshToken, d = o.id_token ?? o.idToken ?? o.IdToken, c = o.expires_in ?? o.expiresIn ?? o.ExpiresIn ?? 3600, p = o.token_type ?? o.tokenType ?? o.TokenType ?? "Bearer";
|
|
479
|
+
return i && await this.storeTokens({
|
|
480
|
+
accessToken: i,
|
|
481
|
+
refreshToken: u ?? "",
|
|
482
|
+
idToken: d ?? "",
|
|
483
|
+
expiresIn: c ?? 3600,
|
|
474
484
|
tokenType: p ?? "Bearer"
|
|
475
485
|
}), {
|
|
476
|
-
access_token:
|
|
477
|
-
refresh_token:
|
|
478
|
-
id_token:
|
|
479
|
-
expires_in:
|
|
486
|
+
access_token: i,
|
|
487
|
+
refresh_token: u ?? "",
|
|
488
|
+
id_token: d ?? "",
|
|
489
|
+
expires_in: c,
|
|
480
490
|
token_type: p,
|
|
481
|
-
verified: o.verified
|
|
491
|
+
verified: o.verified,
|
|
482
492
|
email: o.email ?? o.Email ?? "",
|
|
483
493
|
...o
|
|
484
494
|
};
|
|
@@ -492,11 +502,11 @@ class C {
|
|
|
492
502
|
}) {
|
|
493
503
|
const t = await this.request("POST", "/otp/signup/resend", {
|
|
494
504
|
body: { email: n, mobileNumber: e }
|
|
495
|
-
}),
|
|
505
|
+
}), s = t.data.data ?? t.data;
|
|
496
506
|
return {
|
|
497
|
-
success:
|
|
498
|
-
message:
|
|
499
|
-
...
|
|
507
|
+
success: s.success,
|
|
508
|
+
message: s.message,
|
|
509
|
+
...s
|
|
500
510
|
};
|
|
501
511
|
}
|
|
502
512
|
/**
|
|
@@ -520,20 +530,20 @@ class C {
|
|
|
520
530
|
{
|
|
521
531
|
body: {}
|
|
522
532
|
}
|
|
523
|
-
), n = e.data.data ?? e.data, t = n.AuthenticationResult ?? n,
|
|
524
|
-
return
|
|
525
|
-
accessToken:
|
|
526
|
-
refreshToken:
|
|
533
|
+
), n = e.data.data ?? e.data, t = n.AuthenticationResult ?? n, s = t.access_token ?? t.accessToken ?? t.AccessToken, r = t.refresh_token ?? t.refreshToken ?? t.RefreshToken, o = t.id_token ?? t.idToken ?? t.IdToken, i = t.expires_in ?? t.expiresIn ?? t.ExpiresIn ?? 3600, u = t.token_type ?? t.tokenType ?? t.TokenType ?? "Bearer";
|
|
534
|
+
return s && await this.storeTokens({
|
|
535
|
+
accessToken: s,
|
|
536
|
+
refreshToken: r ?? "",
|
|
527
537
|
idToken: o ?? "",
|
|
528
|
-
expiresIn:
|
|
529
|
-
tokenType:
|
|
538
|
+
expiresIn: i ?? 3600,
|
|
539
|
+
tokenType: u ?? "Bearer"
|
|
530
540
|
}), {
|
|
531
|
-
access_token:
|
|
532
|
-
refresh_token:
|
|
541
|
+
access_token: s,
|
|
542
|
+
refresh_token: r ?? "",
|
|
533
543
|
id_token: o ?? "",
|
|
534
|
-
expires_in:
|
|
535
|
-
token_type:
|
|
536
|
-
verified: t.verified
|
|
544
|
+
expires_in: i,
|
|
545
|
+
token_type: u,
|
|
546
|
+
verified: t.verified,
|
|
537
547
|
email: t.email ?? t.Email ?? "",
|
|
538
548
|
...t
|
|
539
549
|
};
|
|
@@ -553,23 +563,23 @@ class C {
|
|
|
553
563
|
let t;
|
|
554
564
|
if (n?.user?.id)
|
|
555
565
|
try {
|
|
556
|
-
t =
|
|
566
|
+
t = m(n.user.id);
|
|
557
567
|
} catch {
|
|
558
568
|
t = _(n.user.id);
|
|
559
569
|
}
|
|
560
570
|
else
|
|
561
571
|
t = _(e);
|
|
562
|
-
const
|
|
572
|
+
const s = (n.pubKeyCredParams ?? [
|
|
563
573
|
{ type: "public-key", alg: -7 },
|
|
564
574
|
{ type: "public-key", alg: -257 }
|
|
565
575
|
]).map((f) => ({
|
|
566
576
|
type: "public-key",
|
|
567
577
|
alg: f.alg
|
|
568
|
-
})),
|
|
578
|
+
})), r = n.excludeCredentials?.map((f) => ({
|
|
569
579
|
type: "public-key",
|
|
570
|
-
id:
|
|
580
|
+
id: m(f)
|
|
571
581
|
})), o = {
|
|
572
|
-
challenge:
|
|
582
|
+
challenge: m(n.challenge),
|
|
573
583
|
rp: {
|
|
574
584
|
name: n.rp?.name ?? "XPay",
|
|
575
585
|
id: n.rp?.id ?? window.location.hostname
|
|
@@ -579,8 +589,8 @@ class C {
|
|
|
579
589
|
name: n.user?.name ?? e,
|
|
580
590
|
displayName: n.user?.displayName ?? e
|
|
581
591
|
},
|
|
582
|
-
pubKeyCredParams:
|
|
583
|
-
excludeCredentials:
|
|
592
|
+
pubKeyCredParams: s,
|
|
593
|
+
excludeCredentials: r,
|
|
584
594
|
timeout: n.timeout ?? 6e4,
|
|
585
595
|
attestation: "direct",
|
|
586
596
|
authenticatorSelection: {
|
|
@@ -588,26 +598,26 @@ class C {
|
|
|
588
598
|
userVerification: "required",
|
|
589
599
|
authenticatorAttachment: "platform"
|
|
590
600
|
}
|
|
591
|
-
},
|
|
601
|
+
}, i = await navigator.credentials.create({
|
|
592
602
|
publicKey: o
|
|
593
603
|
});
|
|
594
|
-
if (!
|
|
595
|
-
const
|
|
596
|
-
clientDataJSON: y(
|
|
597
|
-
attestationObject: y(
|
|
598
|
-
rawId: y(
|
|
604
|
+
if (!i) throw new Error("Credential creation failed");
|
|
605
|
+
const u = i.response, d = {
|
|
606
|
+
clientDataJSON: y(u.clientDataJSON),
|
|
607
|
+
attestationObject: y(u.attestationObject),
|
|
608
|
+
rawId: y(i.rawId)
|
|
599
609
|
};
|
|
600
|
-
if (!
|
|
610
|
+
if (!d.rawId) throw new Error("Raw ID is required");
|
|
601
611
|
await g();
|
|
602
|
-
const
|
|
612
|
+
const c = await k(
|
|
603
613
|
"POST",
|
|
604
614
|
`${this.getBaseUrl()}/webauthn/register/challenge`
|
|
605
615
|
), p = await this.request(
|
|
606
616
|
"POST",
|
|
607
617
|
"/webauthn/register/challenge",
|
|
608
618
|
{
|
|
609
|
-
body:
|
|
610
|
-
headers:
|
|
619
|
+
body: d,
|
|
620
|
+
headers: c ? { DPoP: c } : {}
|
|
611
621
|
}
|
|
612
622
|
);
|
|
613
623
|
return p.data.data ?? p.data;
|
|
@@ -620,65 +630,65 @@ class C {
|
|
|
620
630
|
rp: n,
|
|
621
631
|
credentialIds: t
|
|
622
632
|
}) {
|
|
623
|
-
const
|
|
633
|
+
const s = await navigator.credentials.get({
|
|
624
634
|
publicKey: {
|
|
625
|
-
challenge:
|
|
635
|
+
challenge: m(e),
|
|
626
636
|
rpId: n?.host ?? void 0,
|
|
627
637
|
allowCredentials: t.map((P) => ({
|
|
628
638
|
type: "public-key",
|
|
629
|
-
id:
|
|
639
|
+
id: m(P),
|
|
630
640
|
transports: ["internal"]
|
|
631
641
|
})),
|
|
632
642
|
timeout: 6e4,
|
|
633
643
|
userVerification: "required"
|
|
634
644
|
}
|
|
635
645
|
});
|
|
636
|
-
if (!
|
|
637
|
-
const
|
|
638
|
-
clientDataJSON: y(
|
|
646
|
+
if (!s) throw new Error("Authentication failed");
|
|
647
|
+
const r = s.response, o = {
|
|
648
|
+
clientDataJSON: y(r.clientDataJSON),
|
|
639
649
|
authenticatorData: y(
|
|
640
|
-
|
|
650
|
+
r.authenticatorData
|
|
641
651
|
),
|
|
642
|
-
signature: y(
|
|
643
|
-
rawId: y(
|
|
644
|
-
userHandle:
|
|
652
|
+
signature: y(r.signature),
|
|
653
|
+
rawId: y(s.rawId),
|
|
654
|
+
userHandle: r.userHandle ? y(r.userHandle) : ""
|
|
645
655
|
};
|
|
646
656
|
await g();
|
|
647
|
-
const
|
|
657
|
+
const i = await k(
|
|
648
658
|
"POST",
|
|
649
659
|
`${this.getBaseUrl()}/webauthn/authenticate/challenge`
|
|
650
|
-
),
|
|
660
|
+
), u = await this.request(
|
|
651
661
|
"POST",
|
|
652
662
|
"/webauthn/authenticate/challenge",
|
|
653
663
|
{
|
|
654
664
|
body: o,
|
|
655
|
-
headers:
|
|
665
|
+
headers: i ? { DPoP: i } : {}
|
|
656
666
|
}
|
|
657
|
-
),
|
|
667
|
+
), d = u.data.data ?? u.data, c = d.AuthenticationResult ?? d, p = c.AccessToken ?? c.accessToken ?? c.access_token, f = c.RefreshToken ?? c.refreshToken ?? c.refresh_token, b = c.IdToken ?? c.idToken ?? c.id_token;
|
|
658
668
|
return p && await this.storeTokens({
|
|
659
669
|
accessToken: p,
|
|
660
670
|
refreshToken: f ?? "",
|
|
661
671
|
idToken: b ?? "",
|
|
662
|
-
expiresIn:
|
|
663
|
-
tokenType:
|
|
672
|
+
expiresIn: c.expiresIn ?? c.ExpiresIn ?? 3600,
|
|
673
|
+
tokenType: c.tokenType ?? c.token_type ?? "Bearer"
|
|
664
674
|
}), {
|
|
665
675
|
access_token: p,
|
|
666
676
|
refresh_token: f ?? "",
|
|
667
677
|
id_token: b,
|
|
668
|
-
email:
|
|
669
|
-
name:
|
|
670
|
-
expiresIn:
|
|
671
|
-
tokenType:
|
|
672
|
-
...
|
|
678
|
+
email: c.email,
|
|
679
|
+
name: c.name ?? c.userName,
|
|
680
|
+
expiresIn: c.expiresIn ?? c.ExpiresIn,
|
|
681
|
+
tokenType: c.tokenType ?? c.token_type,
|
|
682
|
+
...c
|
|
673
683
|
};
|
|
674
684
|
}
|
|
675
685
|
/**
|
|
676
686
|
* GET /webauthn/credentials/:username - Get user's passkey status.
|
|
677
687
|
*/
|
|
678
688
|
async getPasskeyStatus(e) {
|
|
679
|
-
const t = `/webauthn/credentials/${encodeURIComponent(e)}`,
|
|
680
|
-
headers:
|
|
681
|
-
}), o =
|
|
689
|
+
const t = `/webauthn/credentials/${encodeURIComponent(e)}`, s = await this.signRequest("GET", t), r = await this.request("GET", t, {
|
|
690
|
+
headers: s.headers
|
|
691
|
+
}), o = r.data.data ?? r.data;
|
|
682
692
|
return {
|
|
683
693
|
...o,
|
|
684
694
|
hasCredentials: !!(o.hasCredentials ?? o.credentialId)
|
|
@@ -688,58 +698,58 @@ class C {
|
|
|
688
698
|
* DELETE /webauthn/credentials/:username - Remove passkey.
|
|
689
699
|
*/
|
|
690
700
|
async removePasskey(e) {
|
|
691
|
-
const t = `/webauthn/credentials/${encodeURIComponent(e)}`,
|
|
701
|
+
const t = `/webauthn/credentials/${encodeURIComponent(e)}`, s = await this.signRequest("DELETE", t);
|
|
692
702
|
await this.request("DELETE", t, {
|
|
693
|
-
headers:
|
|
703
|
+
headers: s.headers
|
|
694
704
|
});
|
|
695
705
|
}
|
|
696
706
|
/**
|
|
697
707
|
* Signs a request with DPoP and Authorization headers (internal use).
|
|
698
708
|
*/
|
|
699
709
|
async signRequest(e, n, t = {}) {
|
|
700
|
-
const
|
|
701
|
-
return { ...t, headers: { ...t.headers, ...
|
|
710
|
+
const s = n.startsWith("http") ? n : `${this.getBaseUrl()}${n}`, r = await this.getRequestAuthHeaders(e, s);
|
|
711
|
+
return { ...t, headers: { ...t.headers, ...r } };
|
|
702
712
|
}
|
|
703
713
|
/**
|
|
704
714
|
* Replaces native fetch or Axios with a DPoP-signed version.
|
|
705
715
|
*/
|
|
706
716
|
async authenticatedFetch(e, n) {
|
|
707
|
-
const t = typeof e == "string" ? e : e instanceof URL ? e.toString() : e.url,
|
|
717
|
+
const t = typeof e == "string" ? e : e instanceof URL ? e.toString() : e.url, s = n?.method || "GET", r = await this.signRequest(s, t, {
|
|
708
718
|
headers: n?.headers
|
|
709
719
|
});
|
|
710
|
-
return fetch(e, { ...n, headers:
|
|
720
|
+
return fetch(e, { ...n, headers: r.headers });
|
|
711
721
|
}
|
|
712
722
|
/**
|
|
713
723
|
* Store tokens from /webauthn/authenticate (per spec: sessionStorage preferred).
|
|
714
724
|
*/
|
|
715
725
|
async storeTokens(e) {
|
|
716
|
-
localStorage.setItem(T, e.accessToken), e.refreshToken && localStorage.setItem(
|
|
726
|
+
localStorage.setItem(T, e.accessToken), e.refreshToken && localStorage.setItem(O, e.refreshToken), e.idToken && localStorage.setItem(v, e.idToken);
|
|
717
727
|
}
|
|
718
728
|
/**
|
|
719
729
|
* Clear stored tokens (call on logout).
|
|
720
730
|
*/
|
|
721
731
|
async clearTokens() {
|
|
722
|
-
localStorage.removeItem(T), localStorage.removeItem(
|
|
732
|
+
localStorage.removeItem(T), localStorage.removeItem(v), localStorage.removeItem(O);
|
|
723
733
|
}
|
|
724
734
|
/**
|
|
725
735
|
* POST /auth/refresh - Refresh access token using server-stored refresh token.
|
|
726
736
|
* Requires trusted device cookie (td). Refresh token is stored server-side.
|
|
727
737
|
* Rate limit: 10 requests per minute.
|
|
728
738
|
*/
|
|
729
|
-
async refreshToken() {
|
|
730
|
-
const e = await this.request("POST", "/auth/refresh", {
|
|
731
|
-
body: {}
|
|
732
|
-
}),
|
|
733
|
-
return
|
|
734
|
-
accessToken:
|
|
735
|
-
idToken:
|
|
736
|
-
expiresIn:
|
|
737
|
-
tokenType:
|
|
739
|
+
async refreshToken(e) {
|
|
740
|
+
const n = this.extractRealm(void 0, e), t = await this.request("POST", "/auth/refresh", {
|
|
741
|
+
body: n ? { realm: n } : {}
|
|
742
|
+
}), s = t.data.data ?? t.data, r = s.access_token, o = s.id_token ?? "", i = s.token_type ?? "Bearer", u = s.expires_in ?? 3600;
|
|
743
|
+
return r && await this.storeTokens({
|
|
744
|
+
accessToken: r,
|
|
745
|
+
idToken: o,
|
|
746
|
+
expiresIn: u,
|
|
747
|
+
tokenType: i
|
|
738
748
|
}), {
|
|
739
|
-
access_token:
|
|
740
|
-
id_token:
|
|
741
|
-
token_type:
|
|
742
|
-
expires_in:
|
|
749
|
+
access_token: r,
|
|
750
|
+
id_token: o,
|
|
751
|
+
token_type: i,
|
|
752
|
+
expires_in: u
|
|
743
753
|
};
|
|
744
754
|
}
|
|
745
755
|
/**
|
|
@@ -765,23 +775,23 @@ export {
|
|
|
765
775
|
C as AuthSDK,
|
|
766
776
|
oe as AuthSDKFetchError,
|
|
767
777
|
y as arrayBufferToBase64,
|
|
768
|
-
|
|
769
|
-
|
|
778
|
+
w as arrayBufferToBase64url,
|
|
779
|
+
m as base64ToArrayBuffer,
|
|
770
780
|
M as base64urlToArrayBuffer,
|
|
771
781
|
q as calculateThumbprint,
|
|
772
782
|
N as clearDPoPKey,
|
|
773
|
-
|
|
783
|
+
G as clearPasskeyEmail,
|
|
774
784
|
Q as clearPasskeyMobileNumber,
|
|
775
785
|
g as generateDPoPKeyPair,
|
|
776
|
-
|
|
786
|
+
k as generateDPoPProof,
|
|
777
787
|
A as getDPoPKey,
|
|
778
788
|
R as getDPoPPublicKeyJWK,
|
|
779
|
-
|
|
780
|
-
|
|
789
|
+
z as getPasskeyEmail,
|
|
790
|
+
V as getPasskeyMobileNumber,
|
|
781
791
|
j as isConditionalUISupported,
|
|
782
792
|
ee as isDPoPEnabled,
|
|
783
793
|
K as isWebAuthnSupported,
|
|
784
|
-
|
|
794
|
+
F as setPasskeyEmail,
|
|
785
795
|
X as setPasskeyMobileNumber,
|
|
786
796
|
te as storeDPoPKey,
|
|
787
797
|
_ as stringToArrayBuffer,
|