@sisense/sdk-rest-client 1.2.0 → 1.4.0

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.
@@ -1,2 +1,2 @@
1
1
  import { Authenticator } from './interfaces.js';
2
- export declare function getAuthenticator(url: string, username: string | undefined, password: string | undefined, token: string | undefined, wat: string | undefined, ssoEnabled: boolean | undefined): Authenticator | null;
2
+ export declare function getAuthenticator(url: string, username: string | undefined, password: string | undefined, token: string | undefined, wat: string | undefined, ssoEnabled: boolean | undefined, enableSilentPreAuth?: boolean): Authenticator | null;
@@ -2,10 +2,10 @@ import { PasswordAuthenticator } from './password-authenticator.js';
2
2
  import { BearerAuthenticator } from './bearer-authenticator.js';
3
3
  import { WatAuthenticator } from './wat-authenticator.js';
4
4
  import { SsoAuthenticator } from './sso-authenticator.js';
5
- export function getAuthenticator(url, username, password, token, wat, ssoEnabled) {
5
+ export function getAuthenticator(url, username, password, token, wat, ssoEnabled, enableSilentPreAuth = false) {
6
6
  // sso overrides all other auth methods
7
7
  if (ssoEnabled) {
8
- return new SsoAuthenticator(url);
8
+ return new SsoAuthenticator(url, enableSilentPreAuth);
9
9
  }
10
10
  // username/password or tokens are chosen relative to priority
11
11
  if (username && password) {
@@ -1,5 +1,6 @@
1
1
  import { Authenticator } from './interfaces.js';
2
2
  export declare class BearerAuthenticator implements Authenticator {
3
+ readonly type = "bearer";
3
4
  readonly bearer: string;
4
5
  readonly url: string;
5
6
  private _valid;
@@ -10,3 +11,10 @@ export declare class BearerAuthenticator implements Authenticator {
10
11
  applyHeader(headers: HeadersInit): void;
11
12
  authenticate(): Promise<boolean>;
12
13
  }
14
+ /**
15
+ * Checks if an authenticator is a BearerAuthenticator.
16
+ *
17
+ * @param authenticator - The authenticator to check.
18
+ * @internal
19
+ */
20
+ export declare function isBearerAuthenticator(authenticator: Authenticator): authenticator is BearerAuthenticator;
@@ -12,6 +12,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
12
12
  import { appendHeaders } from './helpers.js';
13
13
  export class BearerAuthenticator {
14
14
  constructor(url, bearer) {
15
+ this.type = 'bearer';
15
16
  this._valid = true;
16
17
  this.bearer = bearer;
17
18
  this.url = url;
@@ -36,3 +37,12 @@ export class BearerAuthenticator {
36
37
  });
37
38
  }
38
39
  }
40
+ /**
41
+ * Checks if an authenticator is a BearerAuthenticator.
42
+ *
43
+ * @param authenticator - The authenticator to check.
44
+ * @internal
45
+ */
46
+ export function isBearerAuthenticator(authenticator) {
47
+ return authenticator.type === 'bearer';
48
+ }
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import fetchIntercept from 'fetch-intercept';
11
- import { handleNetworkError, handleErrorResponse, handleUnauthorizedResponse, isNetworkError, } from './interceptors.js';
11
+ import { getResponseInterceptor, errorInterceptor } from './interceptors.js';
12
12
  import { SsoAuthenticator } from './sso-authenticator.js';
13
13
  import { addQueryParamsToUrl } from './helpers.js';
14
14
  export class HttpClient {
@@ -20,21 +20,8 @@ export class HttpClient {
20
20
  this.auth = auth;
21
21
  this.env = env;
22
22
  fetchIntercept.register({
23
- response: (response) => {
24
- if (response.status === 401) {
25
- return handleUnauthorizedResponse(response, auth);
26
- }
27
- if (!response.ok) {
28
- return handleErrorResponse(response);
29
- }
30
- return response;
31
- },
32
- responseError: (error) => {
33
- if (isNetworkError(error)) {
34
- return handleNetworkError();
35
- }
36
- return Promise.reject(error);
37
- },
23
+ response: getResponseInterceptor(auth),
24
+ responseError: errorInterceptor,
38
25
  });
39
26
  }
40
27
  login() {
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import './translation/initialize-i18n.js';
2
2
  export * from './interfaces.js';
3
3
  export { PasswordAuthenticator } from './password-authenticator.js';
4
- export { SsoAuthenticator } from './sso-authenticator.js';
5
- export { BearerAuthenticator } from './bearer-authenticator.js';
6
- export { WatAuthenticator } from './wat-authenticator.js';
4
+ export { SsoAuthenticator, isSsoAuthenticator } from './sso-authenticator.js';
5
+ export { BearerAuthenticator, isBearerAuthenticator } from './bearer-authenticator.js';
6
+ export { WatAuthenticator, isWatAuthenticator } from './wat-authenticator.js';
7
7
  export { getAuthenticator } from './authenticator.js';
8
8
  export { HttpClient } from './http-client.js';
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import './translation/initialize-i18n.js';
2
2
  export * from './interfaces.js';
3
3
  export { PasswordAuthenticator } from './password-authenticator.js';
4
- export { SsoAuthenticator } from './sso-authenticator.js';
5
- export { BearerAuthenticator } from './bearer-authenticator.js';
6
- export { WatAuthenticator } from './wat-authenticator.js';
4
+ export { SsoAuthenticator, isSsoAuthenticator } from './sso-authenticator.js';
5
+ export { BearerAuthenticator, isBearerAuthenticator } from './bearer-authenticator.js';
6
+ export { WatAuthenticator, isWatAuthenticator } from './wat-authenticator.js';
7
7
  export { getAuthenticator } from './authenticator.js';
8
8
  export { HttpClient } from './http-client.js';
@@ -1,19 +1,4 @@
1
1
  import { FetchInterceptorResponse } from 'fetch-intercept';
2
2
  import { Authenticator } from './interfaces.js';
3
- export declare function handleErrorResponse(response: FetchInterceptorResponse): FetchInterceptorResponse;
4
- export declare function handleUnauthorizedResponse(response: FetchInterceptorResponse, auth: Authenticator): FetchInterceptorResponse;
5
- /**
6
- * Checks if the given response error indicates a Network error.
7
- *
8
- * It is impossible to distinguish between a CORS error and other network errors, such as
9
- * 'net::ERR_SSL_PROTOCOL_ERROR' and 'net::ERR_EMPTY_RESPONSE'. This information is hidden by the browser.
10
- *
11
- * @param responseError - The error object received from the failed response.
12
- */
13
- export declare function isNetworkError(responseError: Error): boolean;
14
- /**
15
- * Handles a Network error.
16
- *
17
- * @returns A promise that rejects with an error message.
18
- */
19
- export declare function handleNetworkError(): Promise<never>;
3
+ export declare const getResponseInterceptor: (auth: Authenticator) => (response: FetchInterceptorResponse) => FetchInterceptorResponse;
4
+ export declare const errorInterceptor: (error: Error) => Promise<never>;
@@ -3,7 +3,7 @@ import { WatAuthenticator } from './wat-authenticator.js';
3
3
  import { PasswordAuthenticator } from './password-authenticator.js';
4
4
  import { SsoAuthenticator } from './sso-authenticator.js';
5
5
  import { TranslatableError } from './translation/translatable-error.js';
6
- export function handleErrorResponse(response) {
6
+ function handleErrorResponse(response) {
7
7
  if (!response.ok) {
8
8
  throw new TranslatableError('errors.responseError', {
9
9
  status: response.status.toString(),
@@ -13,7 +13,7 @@ export function handleErrorResponse(response) {
13
13
  }
14
14
  return response;
15
15
  }
16
- export function handleUnauthorizedResponse(response, auth) {
16
+ function handleUnauthorizedResponse(response, auth) {
17
17
  auth.invalidate();
18
18
  // skip login redirect for token auth
19
19
  if (auth instanceof PasswordAuthenticator) {
@@ -36,7 +36,7 @@ export function handleUnauthorizedResponse(response, auth) {
36
36
  *
37
37
  * @param responseError - The error object received from the failed response.
38
38
  */
39
- export function isNetworkError(responseError) {
39
+ function isNetworkError(responseError) {
40
40
  return !!(responseError.message === 'Failed to fetch' && responseError.name === 'TypeError');
41
41
  }
42
42
  /**
@@ -44,6 +44,21 @@ export function isNetworkError(responseError) {
44
44
  *
45
45
  * @returns A promise that rejects with an error message.
46
46
  */
47
- export function handleNetworkError() {
47
+ function handleNetworkError() {
48
48
  return Promise.reject(new TranslatableError('errors.networkError'));
49
49
  }
50
+ export const getResponseInterceptor = (auth) => (response) => {
51
+ if (response.status === 401) {
52
+ return handleUnauthorizedResponse(response, auth);
53
+ }
54
+ if (!response.ok) {
55
+ return handleErrorResponse(response);
56
+ }
57
+ return response;
58
+ };
59
+ export const errorInterceptor = (error) => {
60
+ if (isNetworkError(error)) {
61
+ return handleNetworkError();
62
+ }
63
+ return Promise.reject(error);
64
+ };
@@ -1,4 +1,5 @@
1
1
  export interface Authenticator {
2
+ readonly type: 'password' | 'bearer' | 'wat' | 'sso';
2
3
  isValid: () => boolean;
3
4
  invalidate: () => void;
4
5
  authenticate: () => Promise<boolean>;
@@ -1,6 +1,7 @@
1
1
  /// <reference lib="dom" />
2
2
  import { Authenticator } from './interfaces.js';
3
3
  export declare class PasswordAuthenticator implements Authenticator {
4
+ readonly type = "password";
4
5
  private _authheader;
5
6
  readonly user: string;
6
7
  readonly pass: string;
@@ -14,3 +15,10 @@ export declare class PasswordAuthenticator implements Authenticator {
14
15
  applyHeader(headers: HeadersInit): void;
15
16
  authenticate(): Promise<boolean>;
16
17
  }
18
+ /**
19
+ * Checks if an authenticator is a PasswordAuthenticator.
20
+ *
21
+ * @param authenticator - the authenticator to check
22
+ * @internal
23
+ */
24
+ export declare function isPasswordAuthenticator(authenticator: Authenticator): authenticator is PasswordAuthenticator;
@@ -16,6 +16,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
16
16
  import { appendHeaders } from './helpers.js';
17
17
  export class PasswordAuthenticator {
18
18
  constructor(url, user, pass) {
19
+ this.type = 'password';
19
20
  this._authenticating = false;
20
21
  this._valid = true;
21
22
  this._authheader = undefined;
@@ -59,3 +60,12 @@ export class PasswordAuthenticator {
59
60
  });
60
61
  }
61
62
  }
63
+ /**
64
+ * Checks if an authenticator is a PasswordAuthenticator.
65
+ *
66
+ * @param authenticator - the authenticator to check
67
+ * @internal
68
+ */
69
+ export function isPasswordAuthenticator(authenticator) {
70
+ return authenticator.type === 'password';
71
+ }
@@ -1,13 +1,24 @@
1
1
  /// <reference lib="dom" />
2
2
  import { Authenticator } from './interfaces.js';
3
3
  export declare class SsoAuthenticator implements Authenticator {
4
+ readonly type = "sso";
4
5
  readonly url: string;
6
+ private _enableSilentPreAuth;
5
7
  private _valid;
6
8
  private _authenticating;
7
- constructor(url: string);
9
+ constructor(url: string, enableSilentPreAuth?: boolean);
8
10
  isValid(): boolean;
9
11
  invalidate(): void;
10
12
  isAuthenticating(): boolean;
11
13
  applyHeader(headers: HeadersInit): HeadersInit;
12
- authenticate(): Promise<boolean>;
14
+ private authenticateSilent;
15
+ private checkAuthentication;
16
+ authenticate(silent?: boolean): Promise<boolean>;
13
17
  }
18
+ /**
19
+ * Checks if the authenticator is SSO authenticator
20
+ *
21
+ * @param authenticator - authenticator to check
22
+ * @internal
23
+ */
24
+ export declare function isSsoAuthenticator(authenticator: Authenticator): authenticator is SsoAuthenticator;
@@ -10,10 +10,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  import { TranslatableError } from './translation/translatable-error.js';
12
12
  export class SsoAuthenticator {
13
- constructor(url) {
13
+ constructor(url, enableSilentPreAuth = false) {
14
+ this.type = 'sso';
14
15
  this._valid = true;
15
16
  this._authenticating = false;
16
17
  this.url = url;
18
+ this._enableSilentPreAuth = enableSilentPreAuth;
17
19
  }
18
20
  isValid() {
19
21
  return this._valid;
@@ -27,31 +29,69 @@ export class SsoAuthenticator {
27
29
  applyHeader(headers) {
28
30
  return headers;
29
31
  }
30
- authenticate() {
32
+ authenticateSilent(loginUrl) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ const iframe = document.createElement('iframe');
35
+ iframe.style.display = 'none';
36
+ document.body.appendChild(iframe);
37
+ iframe.src = `${loginUrl}?return_to=${window.location.href}`;
38
+ yield new Promise((resolve) => {
39
+ iframe.onload = () => {
40
+ resolve(true);
41
+ };
42
+ });
43
+ document.body.removeChild(iframe);
44
+ });
45
+ }
46
+ checkAuthentication() {
31
47
  return __awaiter(this, void 0, void 0, function* () {
32
- this._authenticating = true;
33
48
  const fetchUrl = `${this.url}${!this.url.endsWith('/') ? '/' : ''}api/auth/isauth`;
34
- return fetch(fetchUrl, {
49
+ const response = yield fetch(fetchUrl, {
35
50
  headers: { Internal: 'true' },
36
51
  credentials: 'include',
37
- })
38
- .then((res) => res.json())
39
- .then((res) => {
40
- var _a;
41
- if (!res.isAuthenticated) {
42
- // SSO is disabled on instance, do not proceed
43
- if (!res.ssoEnabled)
44
- throw new TranslatableError('errors.ssoNotEnabled');
45
- // redirect to login page
46
- (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.assign(`${res.loginUrl}?return_to=${window.location.href}`);
47
- return false;
52
+ });
53
+ const result = yield response.json();
54
+ if (!result.isAuthenticated) {
55
+ if (!result.ssoEnabled) {
56
+ throw new TranslatableError('errors.ssoNotEnabled');
48
57
  }
49
- else {
50
- // no authentication needed, indicate success
51
- this._authenticating = false;
52
- return true;
58
+ if (!result.loginUrl) {
59
+ throw new TranslatableError('errors.ssoNoLoginUrl');
53
60
  }
54
- });
61
+ }
62
+ return {
63
+ isAuthenticated: result.isAuthenticated,
64
+ loginUrl: `${result.loginUrl}?return_to=${window.location.href}`,
65
+ };
55
66
  });
56
67
  }
68
+ authenticate(silent = true) {
69
+ var _a;
70
+ return __awaiter(this, void 0, void 0, function* () {
71
+ this._authenticating = true;
72
+ const { isAuthenticated, loginUrl } = yield this.checkAuthentication();
73
+ if (!isAuthenticated) {
74
+ if (this._enableSilentPreAuth && silent) {
75
+ yield this.authenticateSilent(loginUrl);
76
+ return this.authenticate(false);
77
+ }
78
+ (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.assign(loginUrl);
79
+ return false;
80
+ }
81
+ else {
82
+ // no authentication needed, indicate success
83
+ this._authenticating = false;
84
+ return true;
85
+ }
86
+ });
87
+ }
88
+ }
89
+ /**
90
+ * Checks if the authenticator is SSO authenticator
91
+ *
92
+ * @param authenticator - authenticator to check
93
+ * @internal
94
+ */
95
+ export function isSsoAuthenticator(authenticator) {
96
+ return authenticator.type === 'sso';
57
97
  }
@@ -6,6 +6,7 @@ export declare const translation: {
6
6
  errors: {
7
7
  networkError: string;
8
8
  ssoNotEnabled: string;
9
+ ssoNoLoginUrl: string;
9
10
  passwordAuthFailed: string;
10
11
  tokenAuthFailed: string;
11
12
  responseError_onlyStatus: string;
@@ -5,7 +5,8 @@ export const translation = {
5
5
  errorPrefix: '[request-error]',
6
6
  errors: {
7
7
  networkError: "Network error. Probably you forgot to add your domain to 'CORS Allowed Origins' in Sisense Admin Panel -> Security Settings.",
8
- ssoNotEnabled: 'SSO is not enabled on target instance, please choose another authentication method',
8
+ ssoNotEnabled: 'SSO is not enabled on target instance, please choose another authentication method.',
9
+ ssoNoLoginUrl: 'Can not fetch login URL on target instance. Check SSO settings.',
9
10
  passwordAuthFailed: '$t(errorPrefix) Username and password authentication was not successful. Check credentials.',
10
11
  tokenAuthFailed: '$t(errorPrefix) Token authentication was not successful. Check credentials.',
11
12
  responseError_onlyStatus: '$t(errorPrefix) Status: {{status}}',
@@ -7,6 +7,7 @@ export declare const resources: {
7
7
  errors: {
8
8
  networkError: string;
9
9
  ssoNotEnabled: string;
10
+ ssoNoLoginUrl: string;
10
11
  passwordAuthFailed: string;
11
12
  tokenAuthFailed: string;
12
13
  responseError_onlyStatus: string;
@@ -18,6 +19,7 @@ export declare const resources: {
18
19
  errors: {
19
20
  networkError: string;
20
21
  ssoNotEnabled: string;
22
+ ssoNoLoginUrl: string;
21
23
  passwordAuthFailed: string;
22
24
  tokenAuthFailed: string;
23
25
  responseError_onlyStatus: string;
@@ -6,6 +6,7 @@ export const translation = {
6
6
  errors: {
7
7
  networkError: 'Помилка мережі. Можливо ви забули додати свій домен до «CORS Allowed Origins» в панелі адміністратора Sisense -> Security Settings.',
8
8
  ssoNotEnabled: 'SSO не ввімкнено на цьому сервері, будь ласка, виберіть інший метод аутентифікації',
9
+ ssoNoLoginUrl: 'Неможливо отримати loginUrl з сервера. Перевірте налаштування SSO.',
9
10
  passwordAuthFailed: '$t(errorPrefix) Помилка автентифікації за допомогою імені користувача та пароля. Перевірте дані для входу.',
10
11
  tokenAuthFailed: '$t(errorPrefix) Помилка автентифікації за допомогою токена. Перевірте дані для входу.',
11
12
  responseError_onlyStatus: '$t(errorPrefix) Статус: {{status}}',
@@ -1,6 +1,7 @@
1
1
  /// <reference lib="dom" />
2
2
  import { Authenticator } from './interfaces.js';
3
3
  export declare class WatAuthenticator implements Authenticator {
4
+ readonly type = "wat";
4
5
  private _initialiser;
5
6
  private _webSessionToken;
6
7
  readonly wat: string;
@@ -14,3 +15,10 @@ export declare class WatAuthenticator implements Authenticator {
14
15
  applyHeader(headers: HeadersInit): void;
15
16
  authenticate(): Promise<boolean>;
16
17
  }
18
+ /**
19
+ * Checks if an authenticator is a WatAuthenticator.
20
+ *
21
+ * @param authenticator - the authenticator to check
22
+ * @internal
23
+ */
24
+ export declare function isWatAuthenticator(authenticator: Authenticator): authenticator is WatAuthenticator;
@@ -12,6 +12,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
12
12
  import { appendHeaders } from './helpers.js';
13
13
  export class WatAuthenticator {
14
14
  constructor(url, wat) {
15
+ this.type = 'wat';
15
16
  this._authenticating = false;
16
17
  this._valid = true;
17
18
  this._initialiser = undefined;
@@ -67,3 +68,12 @@ export class WatAuthenticator {
67
68
  });
68
69
  }
69
70
  }
71
+ /**
72
+ * Checks if an authenticator is a WatAuthenticator.
73
+ *
74
+ * @param authenticator - the authenticator to check
75
+ * @internal
76
+ */
77
+ export function isWatAuthenticator(authenticator) {
78
+ return authenticator.type === 'wat';
79
+ }
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "Sisense",
12
12
  "Compose SDK"
13
13
  ],
14
- "version": "1.2.0",
14
+ "version": "1.4.0",
15
15
  "type": "module",
16
16
  "exports": "./dist/index.js",
17
17
  "main": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  "author": "Sisense",
21
21
  "license": "SEE LICENSE IN LICENSE.md",
22
22
  "dependencies": {
23
- "@sisense/sdk-common": "^1.2.0",
23
+ "@sisense/sdk-common": "^1.4.0",
24
24
  "fetch-intercept": "^2.4.0"
25
25
  },
26
26
  "scripts": {