@nauth-toolkit/client-angular 0.1.57 → 0.1.59
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/esm2022/lib/auth.guard.mjs +58 -23
- package/esm2022/lib/social-redirect-callback.guard.mjs +28 -24
- package/esm2022/ngmodule/auth.service.mjs +16 -1
- package/esm2022/ngmodule/http-adapter.mjs +62 -16
- package/esm2022/ngmodule/nauth.module.mjs +4 -1
- package/esm2022/standalone/auth.guard.mjs +32 -13
- package/esm2022/standalone/auth.service.mjs +16 -1
- package/esm2022/standalone/http-adapter.mjs +62 -16
- package/esm2022/standalone/social-redirect-callback.guard.mjs +28 -24
- package/fesm2022/nauth-toolkit-client-angular-standalone.mjs +131 -49
- package/fesm2022/nauth-toolkit-client-angular-standalone.mjs.map +1 -1
- package/fesm2022/nauth-toolkit-client-angular.mjs +218 -118
- package/fesm2022/nauth-toolkit-client-angular.mjs.map +1 -1
- package/lib/auth.guard.d.ts +39 -16
- package/lib/social-redirect-callback.guard.d.ts +2 -2
- package/ngmodule/auth.service.d.ts +13 -0
- package/ngmodule/http-adapter.d.ts +16 -0
- package/package.json +2 -2
- package/standalone/auth.guard.d.ts +13 -6
- package/standalone/auth.service.d.ts +13 -0
- package/standalone/http-adapter.d.ts +16 -0
- package/standalone/social-redirect-callback.guard.d.ts +2 -2
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { NAuthErrorCode, NAuthClientError, NAuthClient } from '@nauth-toolkit/client';
|
|
2
2
|
export * from '@nauth-toolkit/client';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { InjectionToken, Injectable, Inject,
|
|
4
|
+
import { InjectionToken, Injectable, Inject, inject, Optional, NgModule, PLATFORM_ID } from '@angular/core';
|
|
5
5
|
import { firstValueFrom, BehaviorSubject, Subject, catchError, from, switchMap, throwError, filter as filter$1, take } from 'rxjs';
|
|
6
6
|
import { filter } from 'rxjs/operators';
|
|
7
7
|
import * as i1 from '@angular/common/http';
|
|
8
8
|
import { HttpErrorResponse, HTTP_INTERCEPTORS, HttpClientModule, HttpClient } from '@angular/common/http';
|
|
9
9
|
import * as i3 from '@angular/router';
|
|
10
10
|
import { Router } from '@angular/router';
|
|
11
|
+
import { __decorate, __param } from 'tslib';
|
|
11
12
|
import { isPlatformBrowser } from '@angular/common';
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -40,6 +41,37 @@ class AngularHttpAdapter {
|
|
|
40
41
|
constructor(http) {
|
|
41
42
|
this.http = http;
|
|
42
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Safely parse a JSON response body.
|
|
46
|
+
*
|
|
47
|
+
* Angular's fetch backend (`withFetch()`) will throw a raw `SyntaxError` if
|
|
48
|
+
* `responseType: 'json'` is used and the backend returns HTML (common for
|
|
49
|
+
* proxies, 502 pages, SSR fallbacks, or misrouted requests).
|
|
50
|
+
*
|
|
51
|
+
* To avoid crashing consumer apps, we always request as text and then parse
|
|
52
|
+
* JSON only when the response actually looks like JSON.
|
|
53
|
+
*
|
|
54
|
+
* @param bodyText - Raw response body as text
|
|
55
|
+
* @param contentType - Content-Type header value (if available)
|
|
56
|
+
* @returns Parsed JSON value (unknown)
|
|
57
|
+
* @throws {SyntaxError} When body is non-empty but not valid JSON
|
|
58
|
+
*/
|
|
59
|
+
parseJsonBody(bodyText, contentType) {
|
|
60
|
+
const trimmed = bodyText.trim();
|
|
61
|
+
if (!trimmed)
|
|
62
|
+
return null;
|
|
63
|
+
// If it's clearly HTML, never attempt JSON.parse (some proxies mislabel Content-Type).
|
|
64
|
+
if (trimmed.startsWith('<')) {
|
|
65
|
+
return bodyText;
|
|
66
|
+
}
|
|
67
|
+
const looksLikeJson = trimmed.startsWith('{') || trimmed.startsWith('[');
|
|
68
|
+
const isJsonContentType = typeof contentType === 'string' && contentType.toLowerCase().includes('application/json');
|
|
69
|
+
if (!looksLikeJson && !isJsonContentType) {
|
|
70
|
+
// Return raw text when it doesn't look like JSON (e.g., HTML error pages).
|
|
71
|
+
return bodyText;
|
|
72
|
+
}
|
|
73
|
+
return JSON.parse(trimmed);
|
|
74
|
+
}
|
|
43
75
|
/**
|
|
44
76
|
* Execute HTTP request using Angular's HttpClient.
|
|
45
77
|
*
|
|
@@ -49,29 +81,40 @@ class AngularHttpAdapter {
|
|
|
49
81
|
*/
|
|
50
82
|
async request(config) {
|
|
51
83
|
try {
|
|
52
|
-
// Use Angular's HttpClient - goes through ALL interceptors
|
|
53
|
-
|
|
84
|
+
// Use Angular's HttpClient - goes through ALL interceptors.
|
|
85
|
+
// IMPORTANT: Use responseType 'text' to avoid raw JSON.parse crashes when
|
|
86
|
+
// the backend returns HTML (seen in some proxy/SSR/misroute setups).
|
|
87
|
+
const res = await firstValueFrom(this.http.request(config.method, config.url, {
|
|
54
88
|
body: config.body,
|
|
55
89
|
headers: config.headers,
|
|
56
90
|
withCredentials: config.credentials === 'include',
|
|
57
|
-
observe: '
|
|
91
|
+
observe: 'response',
|
|
92
|
+
responseType: 'text',
|
|
58
93
|
}));
|
|
94
|
+
const contentType = res.headers?.get('content-type');
|
|
95
|
+
const parsed = this.parseJsonBody(res.body ?? '', contentType);
|
|
59
96
|
return {
|
|
60
|
-
data,
|
|
61
|
-
status:
|
|
62
|
-
headers: {}, //
|
|
97
|
+
data: parsed,
|
|
98
|
+
status: res.status,
|
|
99
|
+
headers: {}, // Reserved for future header passthrough if needed
|
|
63
100
|
};
|
|
64
101
|
}
|
|
65
102
|
catch (error) {
|
|
66
103
|
if (error instanceof HttpErrorResponse) {
|
|
67
|
-
// Convert Angular's HttpErrorResponse to NAuthClientError
|
|
68
|
-
|
|
69
|
-
const
|
|
104
|
+
// Convert Angular's HttpErrorResponse to NAuthClientError.
|
|
105
|
+
// When using responseType 'text', `error.error` is typically a string.
|
|
106
|
+
const contentType = error.headers?.get('content-type') ?? null;
|
|
107
|
+
const rawBody = typeof error.error === 'string' ? error.error : '';
|
|
108
|
+
const parsedError = this.parseJsonBody(rawBody, contentType);
|
|
109
|
+
const errorData = typeof parsedError === 'object' && parsedError !== null ? parsedError : {};
|
|
110
|
+
const code = typeof errorData['code'] === 'string' ? errorData['code'] : NAuthErrorCode.INTERNAL_ERROR;
|
|
70
111
|
const message = typeof errorData['message'] === 'string'
|
|
71
|
-
? errorData
|
|
72
|
-
:
|
|
73
|
-
|
|
74
|
-
|
|
112
|
+
? errorData['message']
|
|
113
|
+
: typeof parsedError === 'string' && parsedError.trim()
|
|
114
|
+
? parsedError
|
|
115
|
+
: error.message || `Request failed with status ${error.status}`;
|
|
116
|
+
const timestamp = typeof errorData['timestamp'] === 'string' ? errorData['timestamp'] : undefined;
|
|
117
|
+
const details = typeof errorData['details'] === 'object' ? errorData['details'] : undefined;
|
|
75
118
|
throw new NAuthClientError(code, message, {
|
|
76
119
|
statusCode: error.status,
|
|
77
120
|
timestamp,
|
|
@@ -79,8 +122,12 @@ class AngularHttpAdapter {
|
|
|
79
122
|
isNetworkError: error.status === 0, // Network error (no response from server)
|
|
80
123
|
});
|
|
81
124
|
}
|
|
82
|
-
// Re-throw non-HTTP errors
|
|
83
|
-
|
|
125
|
+
// Re-throw non-HTTP errors as an SDK error so consumers don't see raw parser crashes.
|
|
126
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
127
|
+
throw new NAuthClientError(NAuthErrorCode.INTERNAL_ERROR, message, {
|
|
128
|
+
statusCode: 0,
|
|
129
|
+
isNetworkError: true,
|
|
130
|
+
});
|
|
84
131
|
}
|
|
85
132
|
}
|
|
86
133
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AngularHttpAdapter, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -220,6 +267,21 @@ class AuthService {
|
|
|
220
267
|
getCurrentChallenge() {
|
|
221
268
|
return this.challengeSubject.value;
|
|
222
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Get challenge router for manual navigation control.
|
|
272
|
+
* Useful for guards that need to handle errors or build custom URLs.
|
|
273
|
+
*
|
|
274
|
+
* @returns ChallengeRouter instance
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```typescript
|
|
278
|
+
* const router = this.auth.getChallengeRouter();
|
|
279
|
+
* await router.navigateToError('oauth');
|
|
280
|
+
* ```
|
|
281
|
+
*/
|
|
282
|
+
getChallengeRouter() {
|
|
283
|
+
return this.client.getChallengeRouter();
|
|
284
|
+
}
|
|
223
285
|
// ============================================================================
|
|
224
286
|
// Core Auth Methods
|
|
225
287
|
// ============================================================================
|
|
@@ -962,6 +1024,118 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
962
1024
|
args: [NAUTH_CLIENT_CONFIG]
|
|
963
1025
|
}] }, { type: i1.HttpClient }, { type: AuthService }, { type: i3.Router }] });
|
|
964
1026
|
|
|
1027
|
+
/**
|
|
1028
|
+
* Functional route guard for authentication (Angular 17+).
|
|
1029
|
+
*
|
|
1030
|
+
* Protects routes by checking if user is authenticated.
|
|
1031
|
+
* Redirects to configured session expired route (or login) if not authenticated.
|
|
1032
|
+
*
|
|
1033
|
+
* @param redirectTo - Optional path to redirect to if not authenticated. If not provided, uses `redirects.sessionExpired` from config (defaults to '/login')
|
|
1034
|
+
* @returns CanActivateFn guard function
|
|
1035
|
+
*
|
|
1036
|
+
* @example
|
|
1037
|
+
* ```typescript
|
|
1038
|
+
* // In route configuration - uses config.redirects.sessionExpired
|
|
1039
|
+
* const routes: Routes = [
|
|
1040
|
+
* {
|
|
1041
|
+
* path: 'home',
|
|
1042
|
+
* component: HomeComponent,
|
|
1043
|
+
* canActivate: [authGuard()]
|
|
1044
|
+
* }
|
|
1045
|
+
* ];
|
|
1046
|
+
*
|
|
1047
|
+
* // Override with custom route
|
|
1048
|
+
* const routes: Routes = [
|
|
1049
|
+
* {
|
|
1050
|
+
* path: 'admin',
|
|
1051
|
+
* component: AdminComponent,
|
|
1052
|
+
* canActivate: [authGuard('/admin/login')]
|
|
1053
|
+
* }
|
|
1054
|
+
* ];
|
|
1055
|
+
* ```
|
|
1056
|
+
*/
|
|
1057
|
+
function authGuard(redirectTo) {
|
|
1058
|
+
return () => {
|
|
1059
|
+
const auth = inject(AuthService);
|
|
1060
|
+
const router = inject(Router);
|
|
1061
|
+
const config = inject(NAUTH_CLIENT_CONFIG, { optional: true });
|
|
1062
|
+
if (auth.isAuthenticated()) {
|
|
1063
|
+
return true;
|
|
1064
|
+
}
|
|
1065
|
+
// Use provided redirectTo, or config.redirects.sessionExpired, or default to '/login'
|
|
1066
|
+
const redirectPath = redirectTo ?? config?.redirects?.sessionExpired ?? '/login';
|
|
1067
|
+
return router.createUrlTree([redirectPath]);
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Class-based authentication guard for NgModule compatibility.
|
|
1072
|
+
*
|
|
1073
|
+
* **Note:** When using `NAuthModule.forRoot()`, `AuthGuard` is automatically provided
|
|
1074
|
+
* and has access to the configuration. You don't need to add it to your module's providers.
|
|
1075
|
+
*
|
|
1076
|
+
* @example
|
|
1077
|
+
* ```typescript
|
|
1078
|
+
* // app.module.ts - AuthGuard is automatically provided by NAuthModule.forRoot()
|
|
1079
|
+
* @NgModule({
|
|
1080
|
+
* imports: [
|
|
1081
|
+
* NAuthModule.forRoot({
|
|
1082
|
+
* baseUrl: 'https://api.example.com/auth',
|
|
1083
|
+
* tokenDelivery: 'cookies',
|
|
1084
|
+
* redirects: {
|
|
1085
|
+
* sessionExpired: '/login?expired=true',
|
|
1086
|
+
* },
|
|
1087
|
+
* }),
|
|
1088
|
+
* RouterModule.forRoot([
|
|
1089
|
+
* {
|
|
1090
|
+
* path: 'home',
|
|
1091
|
+
* component: HomeComponent,
|
|
1092
|
+
* canActivate: [AuthGuard], // Uses config.redirects.sessionExpired
|
|
1093
|
+
* },
|
|
1094
|
+
* ]),
|
|
1095
|
+
* ],
|
|
1096
|
+
* })
|
|
1097
|
+
* export class AppModule {}
|
|
1098
|
+
*
|
|
1099
|
+
* // Or provide manually in a feature module (still has access to root config)
|
|
1100
|
+
* @NgModule({
|
|
1101
|
+
* providers: [AuthGuard],
|
|
1102
|
+
* })
|
|
1103
|
+
* export class FeatureModule {}
|
|
1104
|
+
* ```
|
|
1105
|
+
*/
|
|
1106
|
+
let AuthGuard = class AuthGuard {
|
|
1107
|
+
auth;
|
|
1108
|
+
router;
|
|
1109
|
+
config;
|
|
1110
|
+
/**
|
|
1111
|
+
* @param auth - Authentication service
|
|
1112
|
+
* @param router - Angular router
|
|
1113
|
+
* @param config - Optional client configuration (injected automatically)
|
|
1114
|
+
*/
|
|
1115
|
+
constructor(auth, router, config) {
|
|
1116
|
+
this.auth = auth;
|
|
1117
|
+
this.router = router;
|
|
1118
|
+
this.config = config;
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Check if route can be activated.
|
|
1122
|
+
*
|
|
1123
|
+
* @returns True if authenticated, otherwise redirects to configured session expired route (or '/login')
|
|
1124
|
+
*/
|
|
1125
|
+
canActivate() {
|
|
1126
|
+
if (this.auth.isAuthenticated()) {
|
|
1127
|
+
return true;
|
|
1128
|
+
}
|
|
1129
|
+
// Use config.redirects.sessionExpired or default to '/login'
|
|
1130
|
+
const redirectPath = this.config?.redirects?.sessionExpired ?? '/login';
|
|
1131
|
+
return this.router.createUrlTree([redirectPath]);
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1134
|
+
AuthGuard = __decorate([
|
|
1135
|
+
__param(2, Optional()),
|
|
1136
|
+
__param(2, Inject(NAUTH_CLIENT_CONFIG))
|
|
1137
|
+
], AuthGuard);
|
|
1138
|
+
|
|
965
1139
|
/**
|
|
966
1140
|
* NgModule for nauth-toolkit Angular integration.
|
|
967
1141
|
*
|
|
@@ -1005,6 +1179,8 @@ class NAuthModule {
|
|
|
1005
1179
|
useClass: AuthInterceptorClass,
|
|
1006
1180
|
multi: true,
|
|
1007
1181
|
},
|
|
1182
|
+
// Provide AuthGuard so it has access to NAUTH_CLIENT_CONFIG
|
|
1183
|
+
AuthGuard,
|
|
1008
1184
|
],
|
|
1009
1185
|
};
|
|
1010
1186
|
}
|
|
@@ -1171,86 +1347,6 @@ class AuthInterceptor {
|
|
|
1171
1347
|
}
|
|
1172
1348
|
}
|
|
1173
1349
|
|
|
1174
|
-
/**
|
|
1175
|
-
* Functional route guard for authentication (Angular 17+).
|
|
1176
|
-
*
|
|
1177
|
-
* Protects routes by checking if user is authenticated.
|
|
1178
|
-
* Redirects to login page if not authenticated.
|
|
1179
|
-
*
|
|
1180
|
-
* @param redirectTo - Path to redirect to if not authenticated (default: '/login')
|
|
1181
|
-
* @returns CanActivateFn guard function
|
|
1182
|
-
*
|
|
1183
|
-
* @example
|
|
1184
|
-
* ```typescript
|
|
1185
|
-
* // In route configuration
|
|
1186
|
-
* const routes: Routes = [
|
|
1187
|
-
* {
|
|
1188
|
-
* path: 'home',
|
|
1189
|
-
* component: HomeComponent,
|
|
1190
|
-
* canActivate: [authGuard()]
|
|
1191
|
-
* },
|
|
1192
|
-
* {
|
|
1193
|
-
* path: 'admin',
|
|
1194
|
-
* component: AdminComponent,
|
|
1195
|
-
* canActivate: [authGuard('/admin/login')]
|
|
1196
|
-
* }
|
|
1197
|
-
* ];
|
|
1198
|
-
* ```
|
|
1199
|
-
*/
|
|
1200
|
-
function authGuard(redirectTo = '/login') {
|
|
1201
|
-
return () => {
|
|
1202
|
-
const auth = inject(AuthService);
|
|
1203
|
-
const router = inject(Router);
|
|
1204
|
-
if (auth.isAuthenticated()) {
|
|
1205
|
-
return true;
|
|
1206
|
-
}
|
|
1207
|
-
return router.createUrlTree([redirectTo]);
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
/**
|
|
1211
|
-
* Class-based authentication guard for NgModule compatibility.
|
|
1212
|
-
*
|
|
1213
|
-
* @example
|
|
1214
|
-
* ```typescript
|
|
1215
|
-
* // In route configuration (NgModule)
|
|
1216
|
-
* const routes: Routes = [
|
|
1217
|
-
* {
|
|
1218
|
-
* path: 'home',
|
|
1219
|
-
* component: HomeComponent,
|
|
1220
|
-
* canActivate: [AuthGuard]
|
|
1221
|
-
* }
|
|
1222
|
-
* ];
|
|
1223
|
-
*
|
|
1224
|
-
* // In module providers
|
|
1225
|
-
* @NgModule({
|
|
1226
|
-
* providers: [AuthGuard]
|
|
1227
|
-
* })
|
|
1228
|
-
* ```
|
|
1229
|
-
*/
|
|
1230
|
-
class AuthGuard {
|
|
1231
|
-
auth;
|
|
1232
|
-
router;
|
|
1233
|
-
/**
|
|
1234
|
-
* @param auth - Authentication service
|
|
1235
|
-
* @param router - Angular router
|
|
1236
|
-
*/
|
|
1237
|
-
constructor(auth, router) {
|
|
1238
|
-
this.auth = auth;
|
|
1239
|
-
this.router = router;
|
|
1240
|
-
}
|
|
1241
|
-
/**
|
|
1242
|
-
* Check if route can be activated.
|
|
1243
|
-
*
|
|
1244
|
-
* @returns True if authenticated, otherwise redirects to login
|
|
1245
|
-
*/
|
|
1246
|
-
canActivate() {
|
|
1247
|
-
if (this.auth.isAuthenticated()) {
|
|
1248
|
-
return true;
|
|
1249
|
-
}
|
|
1250
|
-
return this.router.createUrlTree(['/login']);
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
1350
|
/**
|
|
1255
1351
|
* Social redirect callback route guard.
|
|
1256
1352
|
*
|
|
@@ -1261,8 +1357,8 @@ class AuthGuard {
|
|
|
1261
1357
|
* - `error` / `error_description` (provider errors)
|
|
1262
1358
|
*
|
|
1263
1359
|
* Behavior:
|
|
1264
|
-
* - If `exchangeToken` exists: exchanges it via backend
|
|
1265
|
-
* - If no `exchangeToken`: treat as cookie-success path
|
|
1360
|
+
* - If `exchangeToken` exists: exchanges it via backend (SDK handles navigation automatically).
|
|
1361
|
+
* - If no `exchangeToken`: treat as cookie-success path (SDK handles navigation automatically).
|
|
1266
1362
|
* - If `error` exists: redirects to oauthError route.
|
|
1267
1363
|
*
|
|
1268
1364
|
* @example
|
|
@@ -1276,7 +1372,6 @@ class AuthGuard {
|
|
|
1276
1372
|
*/
|
|
1277
1373
|
const socialRedirectCallbackGuard = async () => {
|
|
1278
1374
|
const auth = inject(AuthService);
|
|
1279
|
-
const config = inject(NAUTH_CLIENT_CONFIG);
|
|
1280
1375
|
const platformId = inject(PLATFORM_ID);
|
|
1281
1376
|
const isBrowser = isPlatformBrowser(platformId);
|
|
1282
1377
|
if (!isBrowser) {
|
|
@@ -1285,13 +1380,13 @@ const socialRedirectCallbackGuard = async () => {
|
|
|
1285
1380
|
const params = new URLSearchParams(window.location.search);
|
|
1286
1381
|
const error = params.get('error');
|
|
1287
1382
|
const exchangeToken = params.get('exchangeToken');
|
|
1383
|
+
const router = auth.getChallengeRouter();
|
|
1288
1384
|
// Provider error: redirect to oauthError
|
|
1289
1385
|
if (error) {
|
|
1290
|
-
|
|
1291
|
-
window.location.replace(errorUrl);
|
|
1386
|
+
await router.navigateToError('oauth');
|
|
1292
1387
|
return false;
|
|
1293
1388
|
}
|
|
1294
|
-
// No exchangeToken: cookie success path;
|
|
1389
|
+
// No exchangeToken: cookie success path; hydrate then navigate to success.
|
|
1295
1390
|
//
|
|
1296
1391
|
// Note: we do not "activate" the callback route to avoid consumers needing to render a page.
|
|
1297
1392
|
if (!exchangeToken) {
|
|
@@ -1305,26 +1400,31 @@ const socialRedirectCallbackGuard = async () => {
|
|
|
1305
1400
|
// `currentUser` is still null even though cookies were set successfully.
|
|
1306
1401
|
try {
|
|
1307
1402
|
await auth.getProfile();
|
|
1403
|
+
await router.navigateToSuccess();
|
|
1308
1404
|
}
|
|
1309
|
-
catch {
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1405
|
+
catch (err) {
|
|
1406
|
+
// Only treat auth failures (401/403) as OAuth errors
|
|
1407
|
+
// Network errors or other issues might be temporary - still try success route
|
|
1408
|
+
const isAuthError = err instanceof NAuthClientError &&
|
|
1409
|
+
(err.statusCode === 401 ||
|
|
1410
|
+
err.statusCode === 403 ||
|
|
1411
|
+
err.code === NAuthErrorCode.AUTH_TOKEN_INVALID ||
|
|
1412
|
+
err.code === NAuthErrorCode.AUTH_SESSION_EXPIRED ||
|
|
1413
|
+
err.code === NAuthErrorCode.AUTH_SESSION_NOT_FOUND);
|
|
1414
|
+
if (isAuthError) {
|
|
1415
|
+
// Cookies weren't set properly - OAuth failed
|
|
1416
|
+
await router.navigateToError('oauth');
|
|
1417
|
+
}
|
|
1418
|
+
else {
|
|
1419
|
+
// For network errors or other issues, proceed to success route
|
|
1420
|
+
// The auth guard will handle authentication state on the next route
|
|
1421
|
+
await router.navigateToSuccess();
|
|
1422
|
+
}
|
|
1313
1423
|
}
|
|
1314
|
-
const successUrl = config.redirects?.success || '/';
|
|
1315
|
-
window.location.replace(successUrl);
|
|
1316
|
-
return false;
|
|
1317
|
-
}
|
|
1318
|
-
// Exchange token and route accordingly
|
|
1319
|
-
const response = await auth.exchangeSocialRedirect(exchangeToken);
|
|
1320
|
-
if (response.challengeName) {
|
|
1321
|
-
const challengeBase = config.redirects?.challengeBase || '/auth/challenge';
|
|
1322
|
-
const challengeRoute = response.challengeName.toLowerCase().replace(/_/g, '-');
|
|
1323
|
-
window.location.replace(`${challengeBase}/${challengeRoute}`);
|
|
1324
1424
|
return false;
|
|
1325
1425
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1426
|
+
// Exchange token - SDK handles navigation automatically
|
|
1427
|
+
await auth.exchangeSocialRedirect(exchangeToken);
|
|
1328
1428
|
return false;
|
|
1329
1429
|
};
|
|
1330
1430
|
|