@arsedizioni/ars-utils 20.2.1 → 20.2.3

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.
@@ -17,6 +17,7 @@ declare const ClipperMessages: {
17
17
  LOGIN_CHANGED: string;
18
18
  LOGIN_COMPLETED: string;
19
19
  LOGOUT_COMPLETED: string;
20
+ LOGIN_PENDING: string;
20
21
  LOGOUT: string;
21
22
  DOCUMENT_READ: string;
22
23
  DOCUMENT_NAVIGATE: string;
@@ -1053,6 +1054,10 @@ declare class ClipperService implements OnDestroy {
1053
1054
  * @param refresh: true to get the refresh token. Default is false.
1054
1055
  */
1055
1056
  getToken(refresh?: boolean): string;
1057
+ /**
1058
+ * Get the two form factor authentication token
1059
+ */
1060
+ getMFAToken(): string | null;
1056
1061
  /**
1057
1062
  * Store login info
1058
1063
  */
@@ -1082,6 +1087,16 @@ declare class ClipperService implements OnDestroy {
1082
1087
  * @returns: the login result
1083
1088
  */
1084
1089
  login(email?: string, password?: string, remember?: boolean, oauth?: LoginOAuthType, oauthAccessToken?: string | undefined): rxjs.Observable<ApiResult<ClipperLoginResult>>;
1090
+ /**
1091
+ * Complete login
1092
+ * @param result : the login result
1093
+ */
1094
+ private completeLogin;
1095
+ /**
1096
+ * Confirm MFA procedure
1097
+ * @param code: the confirm code
1098
+ */
1099
+ confirmIdentity(code: string): rxjs.Observable<ApiResult<ClipperLoginResult>>;
1085
1100
  /**
1086
1101
  * Perform logout
1087
1102
  */
@@ -1039,7 +1039,7 @@ declare class ClipperDocumentMenuComponent implements OnInit, OnDestroy {
1039
1039
  private changeDetector;
1040
1040
  private clipperService;
1041
1041
  readonly useSelections: _angular_core.InputSignal<boolean>;
1042
- readonly selectionSource: _angular_core.InputSignal<"none" | "selection" | "bag">;
1042
+ readonly selectionSource: _angular_core.InputSignal<"selection" | "bag" | "none">;
1043
1043
  protected selection: () => ClipperDocumentInfo[];
1044
1044
  readonly parent: _angular_core.InputSignal<ClipperSearchResultManager>;
1045
1045
  readonly item: _angular_core.InputSignal<ClipperDocumentInfo>;
package/core/index.d.ts CHANGED
@@ -566,6 +566,8 @@ interface LoginResult<T> extends ApiResult<boolean> {
566
566
  context: T;
567
567
  token: string;
568
568
  refreshToken?: string;
569
+ requiresMFA?: boolean;
570
+ MFAToken?: string;
569
571
  }
570
572
 
571
573
  declare class DateIntervalChangeDirective implements OnInit, OnDestroy {
@@ -16,6 +16,7 @@ const ClipperMessages = {
16
16
  LOGIN_CHANGED: '§clipper-login-changed',
17
17
  LOGIN_COMPLETED: '§clipper-login-completed',
18
18
  LOGOUT_COMPLETED: '§clipper-logout-completed',
19
+ LOGIN_PENDING: '§clipper-login-pending',
19
20
  LOGOUT: '§clipper-logout',
20
21
  // Document
21
22
  DOCUMENT_READ: '$clipper-document-read',
@@ -2116,6 +2117,7 @@ class ClipperService {
2116
2117
  if (!tokenExpired || this.loggedIn()) {
2117
2118
  // Auto login
2118
2119
  this.loggedIn.set(true);
2120
+ this.loggingIn.set(false);
2119
2121
  // Should refresh
2120
2122
  this.shouldRefreshToken.set(!!tokenExpirationDate);
2121
2123
  // Keep alive
@@ -2181,6 +2183,7 @@ class ClipperService {
2181
2183
  setToken(value) {
2182
2184
  sessionStorage.setItem('clipper_jwt', value.token);
2183
2185
  sessionStorage.setItem('clipper_jwt_refresh', value.refreshToken ?? '');
2186
+ localStorage.setItem('clipper_mfa', value.MFAToken ?? '');
2184
2187
  }
2185
2188
  /**
2186
2189
  * Return current JWT token
@@ -2193,6 +2196,12 @@ class ClipperService {
2193
2196
  }
2194
2197
  return token ?? '';
2195
2198
  }
2199
+ /**
2200
+ * Get the two form factor authentication token
2201
+ */
2202
+ getMFAToken() {
2203
+ return localStorage.getItem("clipper_mfa");
2204
+ }
2196
2205
  /**
2197
2206
  * Store login info
2198
2207
  */
@@ -2270,18 +2279,18 @@ class ClipperService {
2270
2279
  }, {
2271
2280
  headers: !oauth || !oauthAccessToken
2272
2281
  ? new HttpHeaders()
2282
+ .set("X-MFA", this.getMFAToken() ?? '')
2273
2283
  : new HttpHeaders()
2274
2284
  .set("Authorization", oauthAccessToken)
2275
2285
  })
2276
2286
  .pipe(catchError(err => {
2277
2287
  this.loggingIn.set(false);
2278
2288
  localStorage.removeItem('clipper_login');
2289
+ localStorage.removeItem('clipper_mfa');
2279
2290
  return throwError(() => err);
2280
2291
  }), map((r) => {
2281
- this.loggingIn.set(false);
2282
2292
  if (r.success) {
2283
2293
  // Store access token
2284
- this.setToken(r.value);
2285
2294
  const loginInfo = {
2286
2295
  context: r.value.context,
2287
2296
  channels: r.value.settings,
@@ -2294,17 +2303,52 @@ class ClipperService {
2294
2303
  password: password,
2295
2304
  remember: remember,
2296
2305
  }), loginInfo.context.userId.toString());
2306
+ this.storeLogin();
2307
+ }
2308
+ if (!oauth && r.value.requiresMFA) {
2309
+ // Notify login is pending
2310
+ this.broadcastService.sendMessage(ClipperMessages.LOGIN_PENDING);
2311
+ }
2312
+ else {
2313
+ // Complete login
2314
+ this.completeLogin(r.value);
2297
2315
  }
2298
- // Update info
2299
- this._loginInfo = loginInfo;
2300
- this.storeLogin();
2301
- this.loggedIn.set(true);
2302
- // Keep alive
2303
- this.setKeepAlive();
2304
- // Initialize channels
2305
- this.initializeChannels();
2306
- // Notify
2307
- this.broadcastService.sendMessage(ClipperMessages.LOGIN_COMPLETED);
2316
+ }
2317
+ return r;
2318
+ }));
2319
+ }
2320
+ /**
2321
+ * Complete login
2322
+ * @param result : the login result
2323
+ */
2324
+ completeLogin(result) {
2325
+ // Update info
2326
+ this.setToken(result);
2327
+ this.loggedIn.set(true);
2328
+ this.loggingIn.set(false);
2329
+ // Keep alive
2330
+ this.setKeepAlive();
2331
+ // Initialize channels
2332
+ this.initializeChannels();
2333
+ // Notify
2334
+ this.broadcastService.sendMessage(ClipperMessages.LOGIN_COMPLETED);
2335
+ }
2336
+ /**
2337
+ * Confirm MFA procedure
2338
+ * @param code: the confirm code
2339
+ */
2340
+ confirmIdentity(code) {
2341
+ return this.httpClient
2342
+ .post(this._serviceUri + '/login/confirm/' + code, {})
2343
+ .pipe(catchError((err) => {
2344
+ localStorage.removeItem('clipper_login');
2345
+ localStorage.removeItem('clipper_mfa');
2346
+ this.loggingIn.set(false);
2347
+ return throwError(() => err);
2348
+ }), map((r) => {
2349
+ if (r.success) {
2350
+ // Complete login
2351
+ this.completeLogin(r.value);
2308
2352
  }
2309
2353
  return r;
2310
2354
  }));
@@ -2318,6 +2362,7 @@ class ClipperService {
2318
2362
  this.clear(true);
2319
2363
  // Remove credentials
2320
2364
  localStorage.removeItem('clipper_login');
2365
+ localStorage.removeItem('clipper_mfa');
2321
2366
  }), catchError((_e) => {
2322
2367
  return of([]);
2323
2368
  }));
@@ -2330,10 +2375,11 @@ class ClipperService {
2330
2375
  this._loginInfo = undefined;
2331
2376
  // Logged out
2332
2377
  this.loggedIn.set(false);
2333
- // Notify
2334
- this.broadcastService.sendMessage(ClipperMessages.LOGOUT_COMPLETED);
2378
+ this.loggingIn.set(false);
2335
2379
  // Reset channels
2336
2380
  this.availableChannels.set([]);
2381
+ // Notify
2382
+ this.broadcastService.sendMessage(ClipperMessages.LOGOUT_COMPLETED);
2337
2383
  }
2338
2384
  /**
2339
2385
  * Clear login data
@@ -3079,10 +3125,10 @@ class ClipperService {
3079
3125
  downloadArchiveFile(id, otp) {
3080
3126
  return this.httpClient.get(this._serviceUri + '/archive/files/download/?id=' + id + '&otp=' + (otp ?? ''), { responseType: 'blob' });
3081
3127
  }
3082
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ClipperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3083
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ClipperService, providedIn: 'root' }); }
3128
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ClipperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3129
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ClipperService, providedIn: 'root' }); }
3084
3130
  }
3085
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ClipperService, decorators: [{
3131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ClipperService, decorators: [{
3086
3132
  type: Injectable,
3087
3133
  args: [{
3088
3134
  providedIn: 'root',
@@ -3175,19 +3221,19 @@ class ClipperAuthInterceptor {
3175
3221
  }
3176
3222
  return request;
3177
3223
  }
3178
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ClipperAuthInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3179
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ClipperAuthInterceptor }); }
3224
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ClipperAuthInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3225
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ClipperAuthInterceptor }); }
3180
3226
  }
3181
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ClipperAuthInterceptor, decorators: [{
3227
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ClipperAuthInterceptor, decorators: [{
3182
3228
  type: Injectable
3183
3229
  }] });
3184
3230
 
3185
3231
  class ArsClipperCommonModule {
3186
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ArsClipperCommonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3187
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.2.1", ngImport: i0, type: ArsClipperCommonModule }); }
3188
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ArsClipperCommonModule }); }
3232
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ArsClipperCommonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3233
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.2.3", ngImport: i0, type: ArsClipperCommonModule }); }
3234
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ArsClipperCommonModule }); }
3189
3235
  }
3190
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ArsClipperCommonModule, decorators: [{
3236
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.3", ngImport: i0, type: ArsClipperCommonModule, decorators: [{
3191
3237
  type: NgModule
3192
3238
  }] });
3193
3239