@nauth-toolkit/client 0.1.18 → 0.1.21
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/angular/index.cjs +306 -163
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.d.mts +277 -127
- package/dist/angular/index.d.ts +277 -127
- package/dist/angular/index.mjs +305 -162
- package/dist/angular/index.mjs.map +1 -1
- package/dist/index.cjs +47 -108
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +54 -72
- package/dist/index.d.ts +54 -72
- package/dist/index.mjs +47 -108
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/angular/index.mjs
CHANGED
|
@@ -193,12 +193,12 @@ var defaultEndpoints = {
|
|
|
193
193
|
mfaPreferred: "/mfa/preferred-method",
|
|
194
194
|
mfaBackupCodes: "/mfa/backup-codes/generate",
|
|
195
195
|
mfaExemption: "/mfa/exemption",
|
|
196
|
-
socialAuthUrl: "/social/auth-url",
|
|
197
|
-
socialCallback: "/social/callback",
|
|
198
196
|
socialLinked: "/social/linked",
|
|
199
197
|
socialLink: "/social/link",
|
|
200
198
|
socialUnlink: "/social/unlink",
|
|
201
199
|
socialVerify: "/social/:provider/verify",
|
|
200
|
+
socialRedirectStart: "/social/:provider/redirect",
|
|
201
|
+
socialExchange: "/social/exchange",
|
|
202
202
|
trustDevice: "/trust-device",
|
|
203
203
|
isTrustedDevice: "/is-trusted-device",
|
|
204
204
|
auditHistory: "/audit/history",
|
|
@@ -350,6 +350,9 @@ var _BrowserStorage = class _BrowserStorage {
|
|
|
350
350
|
async removeItem(key) {
|
|
351
351
|
this.storage.removeItem(key);
|
|
352
352
|
}
|
|
353
|
+
async clear() {
|
|
354
|
+
this.storage.clear();
|
|
355
|
+
}
|
|
353
356
|
};
|
|
354
357
|
__name(_BrowserStorage, "BrowserStorage");
|
|
355
358
|
var BrowserStorage = _BrowserStorage;
|
|
@@ -368,6 +371,9 @@ var _InMemoryStorage = class _InMemoryStorage {
|
|
|
368
371
|
async removeItem(key) {
|
|
369
372
|
this.store.delete(key);
|
|
370
373
|
}
|
|
374
|
+
async clear() {
|
|
375
|
+
this.store.clear();
|
|
376
|
+
}
|
|
371
377
|
};
|
|
372
378
|
__name(_InMemoryStorage, "InMemoryStorage");
|
|
373
379
|
var InMemoryStorage = _InMemoryStorage;
|
|
@@ -492,9 +498,9 @@ var _FetchAdapter = class _FetchAdapter {
|
|
|
492
498
|
});
|
|
493
499
|
if (!response.ok) {
|
|
494
500
|
const errorData = typeof data === "object" && data !== null ? data : {};
|
|
495
|
-
const code = typeof errorData["code"] === "string" ? errorData
|
|
496
|
-
const message = typeof errorData["message"] === "string" ? errorData
|
|
497
|
-
const timestamp = typeof errorData["timestamp"] === "string" ? errorData
|
|
501
|
+
const code = typeof errorData["code"] === "string" ? errorData["code"] : "INTERNAL_ERROR" /* INTERNAL_ERROR */;
|
|
502
|
+
const message = typeof errorData["message"] === "string" ? errorData["message"] : `Request failed with status ${status}`;
|
|
503
|
+
const timestamp = typeof errorData["timestamp"] === "string" ? errorData["timestamp"] : void 0;
|
|
498
504
|
const details = errorData["details"];
|
|
499
505
|
throw new NAuthClientError(code, message, {
|
|
500
506
|
statusCode: status,
|
|
@@ -918,126 +924,59 @@ var _NAuthClient = class _NAuthClient {
|
|
|
918
924
|
// Social Authentication
|
|
919
925
|
// ============================================================================
|
|
920
926
|
/**
|
|
921
|
-
* Start social OAuth flow
|
|
927
|
+
* Start redirect-first social OAuth flow (web).
|
|
928
|
+
*
|
|
929
|
+
* This performs a browser navigation to:
|
|
930
|
+
* `GET {baseUrl}/social/:provider/redirect?returnTo=...&appState=...`
|
|
922
931
|
*
|
|
923
|
-
*
|
|
924
|
-
*
|
|
932
|
+
* The backend:
|
|
933
|
+
* - generates and stores CSRF state (cluster-safe)
|
|
934
|
+
* - redirects the user to the provider
|
|
935
|
+
* - completes OAuth on callback and sets cookies (or issues an exchange token)
|
|
936
|
+
* - redirects back to `returnTo` with `appState` (and `exchangeToken` for json/hybrid)
|
|
925
937
|
*
|
|
926
938
|
* @param provider - OAuth provider ('google', 'apple', 'facebook')
|
|
927
|
-
* @param options - Optional
|
|
939
|
+
* @param options - Optional redirect options
|
|
928
940
|
*
|
|
929
941
|
* @example
|
|
930
942
|
* ```typescript
|
|
931
|
-
*
|
|
932
|
-
* await client.loginWithSocial('google');
|
|
933
|
-
*
|
|
934
|
-
* // With custom redirect URI
|
|
935
|
-
* await client.loginWithSocial('apple', {
|
|
936
|
-
* redirectUri: 'https://example.com/auth/callback'
|
|
937
|
-
* });
|
|
943
|
+
* await client.loginWithSocial('google', { returnTo: '/auth/callback', appState: '12345' });
|
|
938
944
|
* ```
|
|
939
945
|
*/
|
|
940
|
-
async loginWithSocial(provider,
|
|
946
|
+
async loginWithSocial(provider, options) {
|
|
941
947
|
this.eventEmitter.emit({ type: "oauth:started", data: { provider }, timestamp: Date.now() });
|
|
942
|
-
const { url } = await this.getSocialAuthUrl({ provider });
|
|
943
948
|
if (hasWindow()) {
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
* The SDK validates the state token, completes authentication via backend,
|
|
954
|
-
* and emits appropriate events.
|
|
955
|
-
*
|
|
956
|
-
* @param urlOrParams - Optional URL string or URLSearchParams (auto-detects from window.location if not provided)
|
|
957
|
-
* @returns AuthResponse if OAuth callback detected, null otherwise
|
|
958
|
-
*
|
|
959
|
-
* @example
|
|
960
|
-
* ```typescript
|
|
961
|
-
* // Auto-detect on app init
|
|
962
|
-
* const response = await client.handleOAuthCallback();
|
|
963
|
-
* if (response) {
|
|
964
|
-
* if (response.challengeName) {
|
|
965
|
-
* router.navigate(['/challenge', response.challengeName]);
|
|
966
|
-
* } else {
|
|
967
|
-
* router.navigate(['/']); // Navigate to your app's home route
|
|
968
|
-
* }
|
|
969
|
-
* }
|
|
970
|
-
*
|
|
971
|
-
* // In callback route
|
|
972
|
-
* const response = await client.handleOAuthCallback(window.location.search);
|
|
973
|
-
* ```
|
|
974
|
-
*/
|
|
975
|
-
async handleOAuthCallback(urlOrParams) {
|
|
976
|
-
let params;
|
|
977
|
-
if (urlOrParams instanceof URLSearchParams) {
|
|
978
|
-
params = urlOrParams;
|
|
979
|
-
} else if (typeof urlOrParams === "string") {
|
|
980
|
-
params = new URLSearchParams(urlOrParams);
|
|
981
|
-
} else if (hasWindow()) {
|
|
982
|
-
params = new URLSearchParams(window.location.search);
|
|
983
|
-
} else {
|
|
984
|
-
return null;
|
|
985
|
-
}
|
|
986
|
-
const provider = params.get("provider");
|
|
987
|
-
const code = params.get("code");
|
|
988
|
-
const state = params.get("state");
|
|
989
|
-
const error = params.get("error");
|
|
990
|
-
if (!provider || !code && !error) {
|
|
991
|
-
return null;
|
|
992
|
-
}
|
|
993
|
-
this.eventEmitter.emit({ type: "oauth:callback", data: { provider }, timestamp: Date.now() });
|
|
994
|
-
try {
|
|
995
|
-
if (error) {
|
|
996
|
-
const authError = new NAuthClientError(
|
|
997
|
-
"SOCIAL_TOKEN_INVALID" /* SOCIAL_TOKEN_INVALID */,
|
|
998
|
-
params.get("error_description") || error,
|
|
999
|
-
{ details: { error, provider } }
|
|
1000
|
-
);
|
|
1001
|
-
this.eventEmitter.emit({ type: "oauth:error", data: authError, timestamp: Date.now() });
|
|
1002
|
-
throw authError;
|
|
1003
|
-
}
|
|
1004
|
-
if (!state) {
|
|
1005
|
-
throw new NAuthClientError("CHALLENGE_INVALID" /* CHALLENGE_INVALID */, "Missing OAuth state parameter");
|
|
949
|
+
const startPath = this.config.endpoints.socialRedirectStart.replace(":provider", provider);
|
|
950
|
+
const base = this.config.baseUrl.replace(/\/$/, "");
|
|
951
|
+
const startUrl = new URL(`${base}${startPath}`);
|
|
952
|
+
const returnTo = options?.returnTo ?? this.config.redirects?.success ?? "/";
|
|
953
|
+
const action = options?.action ?? "login";
|
|
954
|
+
startUrl.searchParams.set("returnTo", returnTo);
|
|
955
|
+
startUrl.searchParams.set("action", action);
|
|
956
|
+
if (options?.delivery === "cookies" || options?.delivery === "json") {
|
|
957
|
+
startUrl.searchParams.set("delivery", options.delivery);
|
|
1006
958
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
code,
|
|
1010
|
-
state
|
|
1011
|
-
});
|
|
1012
|
-
if (response.challengeName) {
|
|
1013
|
-
this.eventEmitter.emit({ type: "auth:challenge", data: response, timestamp: Date.now() });
|
|
1014
|
-
} else {
|
|
1015
|
-
this.eventEmitter.emit({ type: "auth:success", data: response, timestamp: Date.now() });
|
|
959
|
+
if (typeof options?.appState === "string" && options.appState.trim() !== "") {
|
|
960
|
+
startUrl.searchParams.set("appState", options.appState);
|
|
1016
961
|
}
|
|
1017
|
-
|
|
1018
|
-
return response;
|
|
1019
|
-
} catch (error2) {
|
|
1020
|
-
const authError = error2 instanceof NAuthClientError ? error2 : new NAuthClientError(
|
|
1021
|
-
"SOCIAL_TOKEN_INVALID" /* SOCIAL_TOKEN_INVALID */,
|
|
1022
|
-
error2.message || "OAuth callback failed"
|
|
1023
|
-
);
|
|
1024
|
-
this.eventEmitter.emit({ type: "oauth:error", data: authError, timestamp: Date.now() });
|
|
1025
|
-
throw authError;
|
|
962
|
+
window.location.href = startUrl.toString();
|
|
1026
963
|
}
|
|
1027
964
|
}
|
|
1028
965
|
/**
|
|
1029
|
-
*
|
|
966
|
+
* Exchange an `exchangeToken` (from redirect callback URL) into an AuthResponse.
|
|
1030
967
|
*
|
|
1031
|
-
*
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
/**
|
|
1037
|
-
* Handle social callback.
|
|
968
|
+
* Used for `tokenDelivery: 'json'` or hybrid flows where the backend redirects back
|
|
969
|
+
* with `exchangeToken` instead of setting cookies.
|
|
970
|
+
*
|
|
971
|
+
* @param exchangeToken - One-time exchange token from the callback URL
|
|
972
|
+
* @returns AuthResponse
|
|
1038
973
|
*/
|
|
1039
|
-
async
|
|
1040
|
-
const
|
|
974
|
+
async exchangeSocialRedirect(exchangeToken) {
|
|
975
|
+
const token = exchangeToken?.trim();
|
|
976
|
+
if (!token) {
|
|
977
|
+
throw new NAuthClientError("CHALLENGE_INVALID" /* CHALLENGE_INVALID */, "Missing exchangeToken");
|
|
978
|
+
}
|
|
979
|
+
const result = await this.post(this.config.endpoints.socialExchange, { exchangeToken: token });
|
|
1041
980
|
await this.handleAuthResponse(result);
|
|
1042
981
|
return result;
|
|
1043
982
|
}
|
|
@@ -1561,6 +1500,76 @@ var AuthService = class {
|
|
|
1561
1500
|
confirmForgotPassword(identifier, code, newPassword) {
|
|
1562
1501
|
return from(this.client.confirmForgotPassword(identifier, code, newPassword));
|
|
1563
1502
|
}
|
|
1503
|
+
/**
|
|
1504
|
+
* Change user password (requires current password).
|
|
1505
|
+
*
|
|
1506
|
+
* @param oldPassword - Current password
|
|
1507
|
+
* @param newPassword - New password (must meet requirements)
|
|
1508
|
+
* @returns Observable that completes when password is changed
|
|
1509
|
+
*
|
|
1510
|
+
* @example
|
|
1511
|
+
* ```typescript
|
|
1512
|
+
* this.auth.changePassword('oldPassword123', 'newSecurePassword456!').subscribe({
|
|
1513
|
+
* next: () => console.log('Password changed successfully'),
|
|
1514
|
+
* error: (err) => console.error('Failed to change password:', err)
|
|
1515
|
+
* });
|
|
1516
|
+
* ```
|
|
1517
|
+
*/
|
|
1518
|
+
changePassword(oldPassword, newPassword) {
|
|
1519
|
+
return from(this.client.changePassword(oldPassword, newPassword));
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Request password change (must change on next login).
|
|
1523
|
+
*
|
|
1524
|
+
* @returns Observable that completes when request is sent
|
|
1525
|
+
*/
|
|
1526
|
+
requestPasswordChange() {
|
|
1527
|
+
return from(this.client.requestPasswordChange());
|
|
1528
|
+
}
|
|
1529
|
+
// ============================================================================
|
|
1530
|
+
// Profile Management
|
|
1531
|
+
// ============================================================================
|
|
1532
|
+
/**
|
|
1533
|
+
* Get current user profile.
|
|
1534
|
+
*
|
|
1535
|
+
* @returns Observable of current user profile
|
|
1536
|
+
*
|
|
1537
|
+
* @example
|
|
1538
|
+
* ```typescript
|
|
1539
|
+
* this.auth.getProfile().subscribe(user => {
|
|
1540
|
+
* console.log('User profile:', user);
|
|
1541
|
+
* });
|
|
1542
|
+
* ```
|
|
1543
|
+
*/
|
|
1544
|
+
getProfile() {
|
|
1545
|
+
return from(
|
|
1546
|
+
this.client.getProfile().then((user) => {
|
|
1547
|
+
this.currentUserSubject.next(user);
|
|
1548
|
+
return user;
|
|
1549
|
+
})
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Update user profile.
|
|
1554
|
+
*
|
|
1555
|
+
* @param updates - Profile fields to update
|
|
1556
|
+
* @returns Observable of updated user profile
|
|
1557
|
+
*
|
|
1558
|
+
* @example
|
|
1559
|
+
* ```typescript
|
|
1560
|
+
* this.auth.updateProfile({ firstName: 'John', lastName: 'Doe' }).subscribe(user => {
|
|
1561
|
+
* console.log('Profile updated:', user);
|
|
1562
|
+
* });
|
|
1563
|
+
* ```
|
|
1564
|
+
*/
|
|
1565
|
+
updateProfile(updates) {
|
|
1566
|
+
return from(
|
|
1567
|
+
this.client.updateProfile(updates).then((user) => {
|
|
1568
|
+
this.currentUserSubject.next(user);
|
|
1569
|
+
return user;
|
|
1570
|
+
})
|
|
1571
|
+
);
|
|
1572
|
+
}
|
|
1564
1573
|
// ============================================================================
|
|
1565
1574
|
// Challenge Flow Methods (Essential for any auth flow)
|
|
1566
1575
|
// ============================================================================
|
|
@@ -1617,26 +1626,172 @@ var AuthService = class {
|
|
|
1617
1626
|
// ============================================================================
|
|
1618
1627
|
/**
|
|
1619
1628
|
* Initiate social OAuth login flow.
|
|
1620
|
-
* Redirects to
|
|
1629
|
+
* Redirects the browser to backend `/auth/social/:provider/redirect`.
|
|
1621
1630
|
*/
|
|
1622
1631
|
loginWithSocial(provider, options) {
|
|
1623
1632
|
return this.client.loginWithSocial(provider, options);
|
|
1624
1633
|
}
|
|
1625
1634
|
/**
|
|
1626
|
-
*
|
|
1635
|
+
* Exchange an exchangeToken (from redirect callback URL) into an AuthResponse.
|
|
1636
|
+
*
|
|
1637
|
+
* Used for `tokenDelivery: 'json'` or hybrid flows where the backend redirects back
|
|
1638
|
+
* with `exchangeToken` instead of setting cookies.
|
|
1639
|
+
*
|
|
1640
|
+
* @param exchangeToken - One-time exchange token from the callback URL
|
|
1641
|
+
* @returns Observable of AuthResponse
|
|
1627
1642
|
*/
|
|
1628
|
-
|
|
1629
|
-
return from(
|
|
1630
|
-
this.client.getSocialAuthUrl({ provider, redirectUri })
|
|
1631
|
-
);
|
|
1643
|
+
exchangeSocialRedirect(exchangeToken) {
|
|
1644
|
+
return from(this.client.exchangeSocialRedirect(exchangeToken).then((res) => this.updateChallengeState(res)));
|
|
1632
1645
|
}
|
|
1633
1646
|
/**
|
|
1634
|
-
*
|
|
1647
|
+
* Verify native social token (mobile).
|
|
1648
|
+
*
|
|
1649
|
+
* @param request - Social verification request with provider and token
|
|
1650
|
+
* @returns Observable of AuthResponse
|
|
1635
1651
|
*/
|
|
1636
|
-
|
|
1637
|
-
return from(
|
|
1638
|
-
|
|
1639
|
-
|
|
1652
|
+
verifyNativeSocial(request) {
|
|
1653
|
+
return from(this.client.verifyNativeSocial(request).then((res) => this.updateChallengeState(res)));
|
|
1654
|
+
}
|
|
1655
|
+
/**
|
|
1656
|
+
* Get linked social accounts.
|
|
1657
|
+
*
|
|
1658
|
+
* @returns Observable of linked accounts response
|
|
1659
|
+
*/
|
|
1660
|
+
getLinkedAccounts() {
|
|
1661
|
+
return from(this.client.getLinkedAccounts());
|
|
1662
|
+
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Link social account.
|
|
1665
|
+
*
|
|
1666
|
+
* @param provider - Social provider to link
|
|
1667
|
+
* @param code - OAuth authorization code
|
|
1668
|
+
* @param state - OAuth state parameter
|
|
1669
|
+
* @returns Observable with success message
|
|
1670
|
+
*/
|
|
1671
|
+
linkSocialAccount(provider, code, state) {
|
|
1672
|
+
return from(this.client.linkSocialAccount(provider, code, state));
|
|
1673
|
+
}
|
|
1674
|
+
/**
|
|
1675
|
+
* Unlink social account.
|
|
1676
|
+
*
|
|
1677
|
+
* @param provider - Social provider to unlink
|
|
1678
|
+
* @returns Observable with success message
|
|
1679
|
+
*/
|
|
1680
|
+
unlinkSocialAccount(provider) {
|
|
1681
|
+
return from(this.client.unlinkSocialAccount(provider));
|
|
1682
|
+
}
|
|
1683
|
+
// ============================================================================
|
|
1684
|
+
// MFA Management
|
|
1685
|
+
// ============================================================================
|
|
1686
|
+
/**
|
|
1687
|
+
* Get MFA status for the current user.
|
|
1688
|
+
*
|
|
1689
|
+
* @returns Observable of MFA status
|
|
1690
|
+
*/
|
|
1691
|
+
getMfaStatus() {
|
|
1692
|
+
return from(this.client.getMfaStatus());
|
|
1693
|
+
}
|
|
1694
|
+
/**
|
|
1695
|
+
* Get MFA devices for the current user.
|
|
1696
|
+
*
|
|
1697
|
+
* @returns Observable of MFA devices array
|
|
1698
|
+
*/
|
|
1699
|
+
getMfaDevices() {
|
|
1700
|
+
return from(this.client.getMfaDevices());
|
|
1701
|
+
}
|
|
1702
|
+
/**
|
|
1703
|
+
* Setup MFA device (authenticated user).
|
|
1704
|
+
*
|
|
1705
|
+
* @param method - MFA method to set up
|
|
1706
|
+
* @returns Observable of setup data
|
|
1707
|
+
*/
|
|
1708
|
+
setupMfaDevice(method) {
|
|
1709
|
+
return from(this.client.setupMfaDevice(method));
|
|
1710
|
+
}
|
|
1711
|
+
/**
|
|
1712
|
+
* Verify MFA setup (authenticated user).
|
|
1713
|
+
*
|
|
1714
|
+
* @param method - MFA method
|
|
1715
|
+
* @param setupData - Setup data from setupMfaDevice
|
|
1716
|
+
* @param deviceName - Optional device name
|
|
1717
|
+
* @returns Observable with device ID
|
|
1718
|
+
*/
|
|
1719
|
+
verifyMfaSetup(method, setupData, deviceName) {
|
|
1720
|
+
return from(this.client.verifyMfaSetup(method, setupData, deviceName));
|
|
1721
|
+
}
|
|
1722
|
+
/**
|
|
1723
|
+
* Remove MFA device.
|
|
1724
|
+
*
|
|
1725
|
+
* @param method - MFA method to remove
|
|
1726
|
+
* @returns Observable with success message
|
|
1727
|
+
*/
|
|
1728
|
+
removeMfaDevice(method) {
|
|
1729
|
+
return from(this.client.removeMfaDevice(method));
|
|
1730
|
+
}
|
|
1731
|
+
/**
|
|
1732
|
+
* Set preferred MFA method.
|
|
1733
|
+
*
|
|
1734
|
+
* @param method - Device method to set as preferred ('totp', 'sms', 'email', or 'passkey')
|
|
1735
|
+
* @returns Observable with success message
|
|
1736
|
+
*/
|
|
1737
|
+
setPreferredMfaMethod(method) {
|
|
1738
|
+
return from(this.client.setPreferredMfaMethod(method));
|
|
1739
|
+
}
|
|
1740
|
+
/**
|
|
1741
|
+
* Generate backup codes.
|
|
1742
|
+
*
|
|
1743
|
+
* @returns Observable of backup codes array
|
|
1744
|
+
*/
|
|
1745
|
+
generateBackupCodes() {
|
|
1746
|
+
return from(this.client.generateBackupCodes());
|
|
1747
|
+
}
|
|
1748
|
+
/**
|
|
1749
|
+
* Set MFA exemption (admin/test scenarios).
|
|
1750
|
+
*
|
|
1751
|
+
* @param exempt - Whether to exempt user from MFA
|
|
1752
|
+
* @param reason - Optional reason for exemption
|
|
1753
|
+
* @returns Observable that completes when exemption is set
|
|
1754
|
+
*/
|
|
1755
|
+
setMfaExemption(exempt, reason) {
|
|
1756
|
+
return from(this.client.setMfaExemption(exempt, reason));
|
|
1757
|
+
}
|
|
1758
|
+
// ============================================================================
|
|
1759
|
+
// Device Trust
|
|
1760
|
+
// ============================================================================
|
|
1761
|
+
/**
|
|
1762
|
+
* Trust current device.
|
|
1763
|
+
*
|
|
1764
|
+
* @returns Observable with device token
|
|
1765
|
+
*/
|
|
1766
|
+
trustDevice() {
|
|
1767
|
+
return from(this.client.trustDevice());
|
|
1768
|
+
}
|
|
1769
|
+
/**
|
|
1770
|
+
* Check if the current device is trusted.
|
|
1771
|
+
*
|
|
1772
|
+
* @returns Observable with trusted status
|
|
1773
|
+
*/
|
|
1774
|
+
isTrustedDevice() {
|
|
1775
|
+
return from(this.client.isTrustedDevice());
|
|
1776
|
+
}
|
|
1777
|
+
// ============================================================================
|
|
1778
|
+
// Audit History
|
|
1779
|
+
// ============================================================================
|
|
1780
|
+
/**
|
|
1781
|
+
* Get paginated audit history for the current user.
|
|
1782
|
+
*
|
|
1783
|
+
* @param params - Query parameters for filtering and pagination
|
|
1784
|
+
* @returns Observable of audit history response
|
|
1785
|
+
*
|
|
1786
|
+
* @example
|
|
1787
|
+
* ```typescript
|
|
1788
|
+
* this.auth.getAuditHistory({ page: 1, limit: 20, eventType: 'LOGIN_SUCCESS' }).subscribe(history => {
|
|
1789
|
+
* console.log('Audit history:', history);
|
|
1790
|
+
* });
|
|
1791
|
+
* ```
|
|
1792
|
+
*/
|
|
1793
|
+
getAuditHistory(params) {
|
|
1794
|
+
return from(this.client.getAuditHistory(params));
|
|
1640
1795
|
}
|
|
1641
1796
|
// ============================================================================
|
|
1642
1797
|
// Escape Hatch
|
|
@@ -1644,20 +1799,19 @@ var AuthService = class {
|
|
|
1644
1799
|
/**
|
|
1645
1800
|
* Expose underlying NAuthClient for advanced scenarios.
|
|
1646
1801
|
*
|
|
1647
|
-
*
|
|
1648
|
-
*
|
|
1649
|
-
*
|
|
1650
|
-
*
|
|
1651
|
-
*
|
|
1652
|
-
* - Device trust (trustDevice)
|
|
1802
|
+
* @deprecated All core functionality is now exposed directly on AuthService as Observables.
|
|
1803
|
+
* Use the direct methods on AuthService instead (e.g., `auth.changePassword()` instead of `auth.getClient().changePassword()`).
|
|
1804
|
+
* This method is kept for backward compatibility only and may be removed in a future version.
|
|
1805
|
+
*
|
|
1806
|
+
* @returns The underlying NAuthClient instance
|
|
1653
1807
|
*
|
|
1654
1808
|
* @example
|
|
1655
1809
|
* ```typescript
|
|
1656
|
-
* //
|
|
1810
|
+
* // Deprecated - use direct methods instead
|
|
1657
1811
|
* const status = await this.auth.getClient().getMfaStatus();
|
|
1658
1812
|
*
|
|
1659
|
-
* //
|
|
1660
|
-
*
|
|
1813
|
+
* // Preferred - use Observable-based methods
|
|
1814
|
+
* this.auth.getMfaStatus().subscribe(status => ...);
|
|
1661
1815
|
* ```
|
|
1662
1816
|
*/
|
|
1663
1817
|
getClient() {
|
|
@@ -1736,12 +1890,11 @@ var authInterceptor = /* @__PURE__ */ __name((req, next) => {
|
|
|
1736
1890
|
const refreshPath = endpoints.refresh ?? "/refresh";
|
|
1737
1891
|
const loginPath = endpoints.login ?? "/login";
|
|
1738
1892
|
const signupPath = endpoints.signup ?? "/signup";
|
|
1739
|
-
const
|
|
1740
|
-
const socialCallbackPath = endpoints.socialCallback ?? "/social/callback";
|
|
1893
|
+
const socialExchangePath = endpoints.socialExchange ?? "/social/exchange";
|
|
1741
1894
|
const refreshUrl = `${baseUrl}${refreshPath}`;
|
|
1742
1895
|
const isAuthApiRequest = req.url.includes(baseUrl);
|
|
1743
1896
|
const isRefreshEndpoint = req.url.includes(refreshPath);
|
|
1744
|
-
const isPublicEndpoint = req.url.includes(loginPath) || req.url.includes(signupPath) || req.url.includes(
|
|
1897
|
+
const isPublicEndpoint = req.url.includes(loginPath) || req.url.includes(signupPath) || req.url.includes(socialExchangePath);
|
|
1745
1898
|
let authReq = req;
|
|
1746
1899
|
if (tokenDelivery === "cookies") {
|
|
1747
1900
|
authReq = authReq.clone({ withCredentials: true });
|
|
@@ -1876,10 +2029,10 @@ var _AuthGuard = class _AuthGuard {
|
|
|
1876
2029
|
__name(_AuthGuard, "AuthGuard");
|
|
1877
2030
|
var AuthGuard = _AuthGuard;
|
|
1878
2031
|
|
|
1879
|
-
// src/angular/
|
|
2032
|
+
// src/angular/social-redirect-callback.guard.ts
|
|
1880
2033
|
import { inject as inject5, PLATFORM_ID as PLATFORM_ID2 } from "@angular/core";
|
|
1881
2034
|
import { isPlatformBrowser as isPlatformBrowser2 } from "@angular/common";
|
|
1882
|
-
var
|
|
2035
|
+
var socialRedirectCallbackGuard = /* @__PURE__ */ __name(async () => {
|
|
1883
2036
|
const auth = inject5(AuthService);
|
|
1884
2037
|
const config = inject5(NAUTH_CLIENT_CONFIG);
|
|
1885
2038
|
const platformId = inject5(PLATFORM_ID2);
|
|
@@ -1887,38 +2040,28 @@ var oauthCallbackGuard = /* @__PURE__ */ __name(async () => {
|
|
|
1887
2040
|
if (!isBrowser) {
|
|
1888
2041
|
return false;
|
|
1889
2042
|
}
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
window.location.replace(homeUrl);
|
|
1895
|
-
return false;
|
|
1896
|
-
}
|
|
1897
|
-
if (response.challengeName) {
|
|
1898
|
-
const challengeBase = config.redirects?.challengeBase || "/auth/challenge";
|
|
1899
|
-
const challengeRoute = response.challengeName.toLowerCase().replace(/_/g, "-");
|
|
1900
|
-
const challengePath = `${challengeBase}/${challengeRoute}`;
|
|
1901
|
-
if (config.debug) {
|
|
1902
|
-
console.warn("[oauth-callback-guard] Redirecting to challenge:", challengePath);
|
|
1903
|
-
}
|
|
1904
|
-
window.location.replace(challengePath);
|
|
1905
|
-
} else {
|
|
1906
|
-
const successUrl = config.redirects?.success || "/";
|
|
1907
|
-
if (config.debug) {
|
|
1908
|
-
console.warn("[oauth-callback-guard] Redirecting to success URL:", successUrl);
|
|
1909
|
-
}
|
|
1910
|
-
window.location.replace(successUrl);
|
|
1911
|
-
}
|
|
1912
|
-
} catch (error) {
|
|
1913
|
-
console.error("[oauth-callback-guard] OAuth callback failed:", error);
|
|
2043
|
+
const params = new URLSearchParams(window.location.search);
|
|
2044
|
+
const error = params.get("error");
|
|
2045
|
+
const exchangeToken = params.get("exchangeToken");
|
|
2046
|
+
if (error) {
|
|
1914
2047
|
const errorUrl = config.redirects?.oauthError || "/login";
|
|
1915
|
-
if (config.debug) {
|
|
1916
|
-
console.warn("[oauth-callback-guard] Redirecting to error URL:", errorUrl);
|
|
1917
|
-
}
|
|
1918
2048
|
window.location.replace(errorUrl);
|
|
2049
|
+
return false;
|
|
2050
|
+
}
|
|
2051
|
+
if (!exchangeToken) {
|
|
2052
|
+
return true;
|
|
2053
|
+
}
|
|
2054
|
+
const response = await auth.getClient().exchangeSocialRedirect(exchangeToken);
|
|
2055
|
+
if (response.challengeName) {
|
|
2056
|
+
const challengeBase = config.redirects?.challengeBase || "/auth/challenge";
|
|
2057
|
+
const challengeRoute = response.challengeName.toLowerCase().replace(/_/g, "-");
|
|
2058
|
+
window.location.replace(`${challengeBase}/${challengeRoute}`);
|
|
2059
|
+
return false;
|
|
1919
2060
|
}
|
|
2061
|
+
const successUrl = config.redirects?.success || "/";
|
|
2062
|
+
window.location.replace(successUrl);
|
|
1920
2063
|
return false;
|
|
1921
|
-
}, "
|
|
2064
|
+
}, "socialRedirectCallbackGuard");
|
|
1922
2065
|
|
|
1923
2066
|
// src/angular/auth.module.ts
|
|
1924
2067
|
import { NgModule } from "@angular/core";
|
|
@@ -1952,6 +2095,6 @@ export {
|
|
|
1952
2095
|
NAuthModule,
|
|
1953
2096
|
authGuard,
|
|
1954
2097
|
authInterceptor,
|
|
1955
|
-
|
|
2098
|
+
socialRedirectCallbackGuard
|
|
1956
2099
|
};
|
|
1957
2100
|
//# sourceMappingURL=index.mjs.map
|