@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.esm.js
CHANGED
|
@@ -1048,6 +1048,25 @@ class PasskeymeAuth {
|
|
|
1048
1048
|
});
|
|
1049
1049
|
}
|
|
1050
1050
|
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Internal helper: Redirect to login in hosted mode, or throw error in direct mode
|
|
1053
|
+
*/
|
|
1054
|
+
redirectOrThrow(userMessage, technicalMessage) {
|
|
1055
|
+
if (this.config.mode === "hosted") {
|
|
1056
|
+
this.redirectToLogin();
|
|
1057
|
+
return { method: "redirect" };
|
|
1058
|
+
}
|
|
1059
|
+
else {
|
|
1060
|
+
throw new PasskeymeError({
|
|
1061
|
+
code: PasskeymeErrorCode.PASSKEY_NOT_SUPPORTED,
|
|
1062
|
+
message: technicalMessage,
|
|
1063
|
+
userMessage: userMessage,
|
|
1064
|
+
recoverable: true,
|
|
1065
|
+
retryable: false,
|
|
1066
|
+
suggestedAction: "Use OAuth sign-in instead",
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1051
1070
|
/**
|
|
1052
1071
|
* Handle authentication callback from hosted auth page
|
|
1053
1072
|
*/
|
|
@@ -1429,6 +1448,19 @@ class PasskeymeAuth {
|
|
|
1429
1448
|
}
|
|
1430
1449
|
// Extract token and user info from response
|
|
1431
1450
|
const { token, user_uuid, success, message } = completeResponse.data;
|
|
1451
|
+
// Decode JWT to extract email and other user info
|
|
1452
|
+
let tokenEmail;
|
|
1453
|
+
try {
|
|
1454
|
+
const tokenParts = token.split(".");
|
|
1455
|
+
if (tokenParts.length === 3) {
|
|
1456
|
+
const payload = JSON.parse(atob(tokenParts[1]));
|
|
1457
|
+
tokenEmail = payload.email;
|
|
1458
|
+
logger.debug("Extracted email from JWT:", tokenEmail);
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
catch (decodeError) {
|
|
1462
|
+
logger.debug("Failed to decode JWT token:", decodeError);
|
|
1463
|
+
}
|
|
1432
1464
|
// Store tokens - use the JWT token as access token
|
|
1433
1465
|
const tokens = {
|
|
1434
1466
|
accessToken: token,
|
|
@@ -1437,11 +1469,13 @@ class PasskeymeAuth {
|
|
|
1437
1469
|
};
|
|
1438
1470
|
await this.tokenStorage.setTokens(tokens);
|
|
1439
1471
|
// Create user object with available information
|
|
1472
|
+
// Prefer email from JWT token, fallback to username
|
|
1473
|
+
const userEmail = tokenEmail || username;
|
|
1440
1474
|
const user = {
|
|
1441
1475
|
id: user_uuid,
|
|
1442
1476
|
uuid: user_uuid,
|
|
1443
1477
|
username: username,
|
|
1444
|
-
email:
|
|
1478
|
+
email: userEmail,
|
|
1445
1479
|
authenticated: true,
|
|
1446
1480
|
};
|
|
1447
1481
|
// Update state
|
|
@@ -1499,7 +1533,7 @@ class PasskeymeAuth {
|
|
|
1499
1533
|
* 1. Check app config for discoverable credentials support
|
|
1500
1534
|
* 2. If supported: attempt discoverable credentials first (no username)
|
|
1501
1535
|
* 3. If not supported or fails: use stored username or prompt for username
|
|
1502
|
-
* 4. Fallback to hosted auth if all passkey attempts fail
|
|
1536
|
+
* 4. Fallback to hosted auth if all passkey attempts fail (unless mode is 'direct')
|
|
1503
1537
|
*/
|
|
1504
1538
|
async smartLogin(username, apiKey) {
|
|
1505
1539
|
logger.debug("[DEBUG] smartLogin called with:", {
|
|
@@ -1514,8 +1548,9 @@ class PasskeymeAuth {
|
|
|
1514
1548
|
logger.debug("[DEBUG] Passkey support check:", isSupported);
|
|
1515
1549
|
if (!isSupported || !effectiveApiKey) {
|
|
1516
1550
|
logger.debug("Conditions not met, redirecting to hosted auth. isSupported:", isSupported, "hasApiKey:", !!effectiveApiKey);
|
|
1517
|
-
this.
|
|
1518
|
-
|
|
1551
|
+
return this.redirectOrThrow(isSupported
|
|
1552
|
+
? "API key is required for passkey authentication."
|
|
1553
|
+
: "Your device doesn't support passkeys.", "Passkey authentication not available");
|
|
1519
1554
|
}
|
|
1520
1555
|
try {
|
|
1521
1556
|
// Get app configuration to check discoverable credentials support
|
|
@@ -1538,8 +1573,7 @@ class PasskeymeAuth {
|
|
|
1538
1573
|
// If passkeys are disabled at the app level, fallback to hosted auth
|
|
1539
1574
|
if (!appConfig.passkeyEnabled) {
|
|
1540
1575
|
logger.debug("Passkeys disabled for this app, falling back to hosted auth");
|
|
1541
|
-
this.
|
|
1542
|
-
return { method: "redirect" };
|
|
1576
|
+
return this.redirectOrThrow("Passkey authentication is not available for this app.", "Passkeys are disabled for this application");
|
|
1543
1577
|
}
|
|
1544
1578
|
let authUsername = username;
|
|
1545
1579
|
// Smart username resolution following industry best practices
|
|
@@ -1561,15 +1595,13 @@ class PasskeymeAuth {
|
|
|
1561
1595
|
const storageKey = `last_username_${this.config.appId}`;
|
|
1562
1596
|
logger.debug("Looking for stored username with key:", storageKey);
|
|
1563
1597
|
const storedUsername = await this.storage.getItem(storageKey);
|
|
1564
|
-
logger.debug("Found stored username:", storedUsername);
|
|
1565
1598
|
if (storedUsername) {
|
|
1566
1599
|
logger.debug("Using stored username for targeted authentication:", storedUsername);
|
|
1567
1600
|
authUsername = storedUsername;
|
|
1568
1601
|
}
|
|
1569
1602
|
else {
|
|
1570
1603
|
logger.debug("No username available and discoverable auth failed/unsupported, falling back to hosted auth");
|
|
1571
|
-
this.
|
|
1572
|
-
return { method: "redirect" };
|
|
1604
|
+
return this.redirectOrThrow("Unable to authenticate with passkey. Please sign in with another method.", "No username available for passkey authentication");
|
|
1573
1605
|
}
|
|
1574
1606
|
}
|
|
1575
1607
|
// Attempt passkey authentication with username
|
|
@@ -1588,9 +1620,15 @@ class PasskeymeAuth {
|
|
|
1588
1620
|
if (this.config.debug) {
|
|
1589
1621
|
logger.error("[PasskeymeAuth] Passkey authentication error details:", error);
|
|
1590
1622
|
}
|
|
1591
|
-
// Fallback to hosted auth for any passkey failures
|
|
1592
|
-
|
|
1593
|
-
|
|
1623
|
+
// Fallback to hosted auth for any passkey failures (unless mode is 'direct')
|
|
1624
|
+
// In direct mode, re-throw the original error for the caller to handle
|
|
1625
|
+
if (this.config.mode === "hosted") {
|
|
1626
|
+
this.redirectToLogin();
|
|
1627
|
+
return { method: "redirect" };
|
|
1628
|
+
}
|
|
1629
|
+
else {
|
|
1630
|
+
throw error;
|
|
1631
|
+
}
|
|
1594
1632
|
}
|
|
1595
1633
|
}
|
|
1596
1634
|
/**
|