@passkeyme/auth 2.0.11 → 2.0.13
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/index.esm.js +50 -12
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +50 -12
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +50 -12
- package/dist/index.umd.js.map +1 -1
- package/dist/src/passkeyme-auth.d.ts +5 -1
- package/dist/src/passkeyme-auth.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1052,6 +1052,25 @@ class PasskeymeAuth {
|
|
|
1052
1052
|
});
|
|
1053
1053
|
}
|
|
1054
1054
|
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Internal helper: Redirect to login in hosted mode, or throw error in direct mode
|
|
1057
|
+
*/
|
|
1058
|
+
redirectOrThrow(userMessage, technicalMessage) {
|
|
1059
|
+
if (this.config.mode === "hosted") {
|
|
1060
|
+
this.redirectToLogin();
|
|
1061
|
+
return { method: "redirect" };
|
|
1062
|
+
}
|
|
1063
|
+
else {
|
|
1064
|
+
throw new PasskeymeError({
|
|
1065
|
+
code: exports.PasskeymeErrorCode.PASSKEY_NOT_SUPPORTED,
|
|
1066
|
+
message: technicalMessage,
|
|
1067
|
+
userMessage: userMessage,
|
|
1068
|
+
recoverable: true,
|
|
1069
|
+
retryable: false,
|
|
1070
|
+
suggestedAction: "Use OAuth sign-in instead",
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1055
1074
|
/**
|
|
1056
1075
|
* Handle authentication callback from hosted auth page
|
|
1057
1076
|
*/
|
|
@@ -1433,6 +1452,19 @@ class PasskeymeAuth {
|
|
|
1433
1452
|
}
|
|
1434
1453
|
// Extract token and user info from response
|
|
1435
1454
|
const { token, user_uuid, success, message } = completeResponse.data;
|
|
1455
|
+
// Decode JWT to extract email and other user info
|
|
1456
|
+
let tokenEmail;
|
|
1457
|
+
try {
|
|
1458
|
+
const tokenParts = token.split(".");
|
|
1459
|
+
if (tokenParts.length === 3) {
|
|
1460
|
+
const payload = JSON.parse(atob(tokenParts[1]));
|
|
1461
|
+
tokenEmail = payload.email;
|
|
1462
|
+
logger.debug("Extracted email from JWT:", tokenEmail);
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
catch (decodeError) {
|
|
1466
|
+
logger.debug("Failed to decode JWT token:", decodeError);
|
|
1467
|
+
}
|
|
1436
1468
|
// Store tokens - use the JWT token as access token
|
|
1437
1469
|
const tokens = {
|
|
1438
1470
|
accessToken: token,
|
|
@@ -1441,11 +1473,13 @@ class PasskeymeAuth {
|
|
|
1441
1473
|
};
|
|
1442
1474
|
await this.tokenStorage.setTokens(tokens);
|
|
1443
1475
|
// Create user object with available information
|
|
1476
|
+
// Prefer email from JWT token, fallback to username
|
|
1477
|
+
const userEmail = tokenEmail || username;
|
|
1444
1478
|
const user = {
|
|
1445
1479
|
id: user_uuid,
|
|
1446
1480
|
uuid: user_uuid,
|
|
1447
1481
|
username: username,
|
|
1448
|
-
email:
|
|
1482
|
+
email: userEmail,
|
|
1449
1483
|
authenticated: true,
|
|
1450
1484
|
};
|
|
1451
1485
|
// Update state
|
|
@@ -1503,7 +1537,7 @@ class PasskeymeAuth {
|
|
|
1503
1537
|
* 1. Check app config for discoverable credentials support
|
|
1504
1538
|
* 2. If supported: attempt discoverable credentials first (no username)
|
|
1505
1539
|
* 3. If not supported or fails: use stored username or prompt for username
|
|
1506
|
-
* 4. Fallback to hosted auth if all passkey attempts fail
|
|
1540
|
+
* 4. Fallback to hosted auth if all passkey attempts fail (unless mode is 'direct')
|
|
1507
1541
|
*/
|
|
1508
1542
|
async smartLogin(username, apiKey) {
|
|
1509
1543
|
logger.debug("[DEBUG] smartLogin called with:", {
|
|
@@ -1518,8 +1552,9 @@ class PasskeymeAuth {
|
|
|
1518
1552
|
logger.debug("[DEBUG] Passkey support check:", isSupported);
|
|
1519
1553
|
if (!isSupported || !effectiveApiKey) {
|
|
1520
1554
|
logger.debug("Conditions not met, redirecting to hosted auth. isSupported:", isSupported, "hasApiKey:", !!effectiveApiKey);
|
|
1521
|
-
this.
|
|
1522
|
-
|
|
1555
|
+
return this.redirectOrThrow(isSupported
|
|
1556
|
+
? "API key is required for passkey authentication."
|
|
1557
|
+
: "Your device doesn't support passkeys.", "Passkey authentication not available");
|
|
1523
1558
|
}
|
|
1524
1559
|
try {
|
|
1525
1560
|
// Get app configuration to check discoverable credentials support
|
|
@@ -1542,8 +1577,7 @@ class PasskeymeAuth {
|
|
|
1542
1577
|
// If passkeys are disabled at the app level, fallback to hosted auth
|
|
1543
1578
|
if (!appConfig.passkeyEnabled) {
|
|
1544
1579
|
logger.debug("Passkeys disabled for this app, falling back to hosted auth");
|
|
1545
|
-
this.
|
|
1546
|
-
return { method: "redirect" };
|
|
1580
|
+
return this.redirectOrThrow("Passkey authentication is not available for this app.", "Passkeys are disabled for this application");
|
|
1547
1581
|
}
|
|
1548
1582
|
let authUsername = username;
|
|
1549
1583
|
// Smart username resolution following industry best practices
|
|
@@ -1565,15 +1599,13 @@ class PasskeymeAuth {
|
|
|
1565
1599
|
const storageKey = `last_username_${this.config.appId}`;
|
|
1566
1600
|
logger.debug("Looking for stored username with key:", storageKey);
|
|
1567
1601
|
const storedUsername = await this.storage.getItem(storageKey);
|
|
1568
|
-
logger.debug("Found stored username:", storedUsername);
|
|
1569
1602
|
if (storedUsername) {
|
|
1570
1603
|
logger.debug("Using stored username for targeted authentication:", storedUsername);
|
|
1571
1604
|
authUsername = storedUsername;
|
|
1572
1605
|
}
|
|
1573
1606
|
else {
|
|
1574
1607
|
logger.debug("No username available and discoverable auth failed/unsupported, falling back to hosted auth");
|
|
1575
|
-
this.
|
|
1576
|
-
return { method: "redirect" };
|
|
1608
|
+
return this.redirectOrThrow("Unable to authenticate with passkey. Please sign in with another method.", "No username available for passkey authentication");
|
|
1577
1609
|
}
|
|
1578
1610
|
}
|
|
1579
1611
|
// Attempt passkey authentication with username
|
|
@@ -1592,9 +1624,15 @@ class PasskeymeAuth {
|
|
|
1592
1624
|
if (this.config.debug) {
|
|
1593
1625
|
logger.error("[PasskeymeAuth] Passkey authentication error details:", error);
|
|
1594
1626
|
}
|
|
1595
|
-
// Fallback to hosted auth for any passkey failures
|
|
1596
|
-
|
|
1597
|
-
|
|
1627
|
+
// Fallback to hosted auth for any passkey failures (unless mode is 'direct')
|
|
1628
|
+
// In direct mode, re-throw the original error for the caller to handle
|
|
1629
|
+
if (this.config.mode === "hosted") {
|
|
1630
|
+
this.redirectToLogin();
|
|
1631
|
+
return { method: "redirect" };
|
|
1632
|
+
}
|
|
1633
|
+
else {
|
|
1634
|
+
throw error;
|
|
1635
|
+
}
|
|
1598
1636
|
}
|
|
1599
1637
|
}
|
|
1600
1638
|
/**
|