@gandalan/weblibs 1.5.36 → 2.0.1

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/index.d.ts CHANGED
@@ -1,6 +1,4 @@
1
1
  export * from "./index.js";
2
- export { IDASFactory } from "./api/IDAS.js";
3
- export { RESTClient } from "./api/RESTClient.js";
4
2
  export function createApi(): FluentApi;
5
3
  export function fluentApi(url: string, authManager: FluentAuthManager | null, serviceName: string): FluentApi;
6
4
  export function createIDASApi(): IDASFluentApi;
@@ -9,7 +7,6 @@ export function createAuthManager(): FluentAuthManager;
9
7
  export function fluentIdasAuthManager(appToken: string, authBaseUrl: string): FluentAuthManager;
10
8
  export function fetchEnvConfig(envConfig?: string): Promise<EnvironmentConfig>;
11
9
  export function restClient(): FluentRESTClient;
12
- export function initIDAS(appToken: string): Promise<Settings | null>;
13
10
 
14
11
  export type AblageApi = {
15
12
  get: (guid: string) => Promise<AblageDTO>;
@@ -856,8 +853,6 @@ export type CsvExportCombinationDTO = {
856
853
  ExportFarbArten: ExportFarbArt[];
857
854
  };
858
855
 
859
- export type DecodedToken = import("jwt-decode").JwtPayload & JwtUserInfo & { id?: string };
860
-
861
856
  export type DevOpsStatusDTO = {
862
857
  Env: string;
863
858
  DbInfo: string;
@@ -2657,13 +2652,6 @@ export type SetFakturaDTO = {
2657
2652
  Kennzeichen: string;
2658
2653
  };
2659
2654
 
2660
- export type Settings = {
2661
- appToken: string;
2662
- mandantGuid: string;
2663
- apiBaseurl: string;
2664
- authUrl: string;
2665
- };
2666
-
2667
2655
  export type SettingsApi = {
2668
2656
  getAllSettings: () => Promise<Record<string, object>>;
2669
2657
  saveSetting: (key: string, value: object) => Promise<void>;
package/index.js CHANGED
@@ -1,8 +1,3 @@
1
- import { IDASFactory } from "./api/IDAS";
2
- import { RESTClient } from "./api/RESTClient";
3
- import { initIDAS } from "./api/authUtils";
4
- export { IDASFactory, initIDAS, RESTClient };
5
-
6
1
  export { createApi, fluentApi } from "./api/fluentApi";
7
2
  export { createIDASApi, idasFluentApi } from "./api/idasFluentApi";
8
3
  export { createAuthManager, fluentIdasAuthManager } from "./api/fluentAuthManager";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gandalan/weblibs",
3
- "version": "1.5.36",
3
+ "version": "2.0.1",
4
4
  "description": "WebLibs for Gandalan JS/TS projects",
5
5
  "keywords": [
6
6
  "gandalan"
@@ -22,7 +22,6 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@mdi/js": "^7.4.47",
25
- "axios": "^1.8.2",
26
25
  "jwt-decode": "^4.0.0",
27
26
  "validator": "^13.12.0"
28
27
  },
@@ -34,6 +33,7 @@
34
33
  "globals": "^15.15.0"
35
34
  },
36
35
  "publishConfig": {
37
- "access": "public"
36
+ "access": "public",
37
+ "registry": "https://registry.npmjs.org/"
38
38
  }
39
39
  }
@@ -21,10 +21,7 @@ const dtoRootMarkerEnd = "// END GENERATED ROOT DTO TYPEDEFS";
21
21
  const businessRootMarkerStart = "// BEGIN GENERATED ROOT BUSINESS TYPEDEFS";
22
22
  const businessRootMarkerEnd = "// END GENERATED ROOT BUSINESS TYPEDEFS";
23
23
 
24
- const rootValueExportStatements = [
25
- "export { IDASFactory } from \"./api/IDAS.js\";",
26
- "export { RESTClient } from \"./api/RESTClient.js\";"
27
- ];
24
+ const rootValueExportStatements = [];
28
25
 
29
26
  const rootFunctionDeclarationStatements = [
30
27
  "export function createApi(): FluentApi;",
@@ -34,8 +31,7 @@ const rootFunctionDeclarationStatements = [
34
31
  "export function createAuthManager(): FluentAuthManager;",
35
32
  "export function fluentIdasAuthManager(appToken: string, authBaseUrl: string): FluentAuthManager;",
36
33
  "export function fetchEnvConfig(envConfig?: string): Promise<EnvironmentConfig>;",
37
- "export function restClient(): FluentRESTClient;",
38
- "export function initIDAS(appToken: string): Promise<Settings | null>;"
34
+ "export function restClient(): FluentRESTClient;"
39
35
  ];
40
36
 
41
37
  const simpleImportTypePattern = /^import\((?:"|').+(?:"|')\)\.[A-Za-z0-9_$]+$/;
package/api/IDAS.js DELETED
@@ -1,152 +0,0 @@
1
- import { isInvalid, currentToken} from "./authUtils";
2
- import { RESTClient } from "./RESTClient";
3
- import { jwtDecode } from "jwt-decode";
4
-
5
- /** @typedef {import("jwt-decode").JwtPayload & import("./fluentAuthManager.js").JwtUserInfo & { id?: string }} DecodedToken */
6
-
7
- export function IDASFactory(settings)
8
- {
9
- if (!isInvalid(settings))
10
- {
11
- return new IDAS(settings);
12
- }
13
-
14
- throw ("Invalid settings: call initIDAS() first to obtain a valid settings!");
15
- }
16
-
17
- class IDAS
18
- {
19
- restClient = undefined;
20
- mandantGuid = undefined;
21
-
22
- constructor(settings)
23
- {
24
- this.settings = settings;
25
- this.mandantGuid = settings.mandantGuid; // for backwards compatiblity only
26
- this.restClient = new RESTClient(settings);
27
- }
28
-
29
- auth = {
30
- _self: this,
31
- getCurrentAuthToken()
32
- {
33
- return currentToken;
34
- },
35
- getRights()
36
- {
37
- if (!currentToken)
38
- {
39
- return [];
40
- }
41
-
42
- const decoded = /** @type {DecodedToken} */ (jwtDecode(currentToken));
43
- if (!decoded.rights)
44
- {
45
- return [];
46
- }
47
-
48
- return Array.isArray(decoded.rights) ? decoded.rights : [decoded.rights];
49
- },
50
- getRoles()
51
- {
52
- if (!currentToken)
53
- {
54
- return [];
55
- }
56
-
57
- const decoded = /** @type {DecodedToken} */ (jwtDecode(currentToken));
58
- if (!decoded.role)
59
- {
60
- return [];
61
- }
62
-
63
- return Array.isArray(decoded.role) ? decoded.role : [decoded.role];
64
- },
65
- hasRight(code)
66
- {
67
- return this.getRights().some(r => r === code);
68
- },
69
- hasRole(code)
70
- {
71
- return this.getRoles().some(r => r === code);
72
- },
73
- getUsername()
74
- {
75
- if (!currentToken)
76
- {
77
- return undefined;
78
- }
79
-
80
- const decoded = /** @type {DecodedToken} */ (jwtDecode(currentToken));
81
- return decoded.id;
82
- },
83
- };
84
-
85
- mandanten = {
86
- _self: this,
87
- async getAll()
88
- {
89
- return await this._self.restClient.get("/Mandanten");
90
- },
91
- async get(guid)
92
- {
93
- return await this._self.restClient.get(`/Mandanten/${guid}`);
94
- },
95
- async save(m)
96
- {
97
- await this._self.restClient.put("/Mandanten", m);
98
- },
99
- };
100
-
101
- benutzer = {
102
- _self: this,
103
- async getAll(mandantGuid)
104
- {
105
- return await this._self.restClient.get(`/BenutzerListe/${mandantGuid}/?mitRollenUndRechten=true`);
106
- },
107
- async get(guid)
108
- {
109
- return await this._self.restClient.get(`/Benutzer/${guid}`);
110
- },
111
- async save(m)
112
- {
113
- await this._self.restClient.put("/Benutzer", m);
114
- },
115
- };
116
-
117
- rollen = {
118
- _self: this,
119
- async getAll()
120
- {
121
- return await this._self.restClient.get("/Rollen");
122
- },
123
- async save(m)
124
- {
125
- await this._self.restClient.put("/Rollen", m);
126
- },
127
- };
128
-
129
- vorgaenge = {
130
- _self: this,
131
- async getByVorgangsnummer(vorgangsNummer, jahr)
132
- {
133
- return await this._self.restClient.get(`/Vorgang/${vorgangsNummer}/${jahr}`);
134
- },
135
- async getByGuid(guid)
136
- {
137
- return await this._self.restClient.get(`/Vorgang/${guid}`);
138
- },
139
- };
140
-
141
- positionen = {
142
- _self: this,
143
- async getByPcode(pcode)
144
- {
145
- return await this._self.restClient.get(`/BelegPositionen/GetByPcode/${pcode}`);
146
- },
147
- async get(guid)
148
- {
149
- return await this._self.restClient.get(`/BelegPositionen/Get/${guid}`);
150
- },
151
- };
152
- }
package/api/RESTClient.js DELETED
@@ -1,179 +0,0 @@
1
- import axios from "axios";
2
- import { currentToken } from "./authUtils";
3
-
4
- export class RESTClient
5
- {
6
- lastError = "";
7
- settings = {};
8
- axiosInstance = null;
9
-
10
- constructor(settings)
11
- {
12
- this.settings = settings;
13
-
14
- this.axiosInstance = axios.create({
15
- baseURL: settings.apiBaseurl,
16
- headers: {
17
- "Authorization": `Bearer ${currentToken}`,
18
- },
19
- });
20
-
21
- /*this.axiosInstance.interceptors.request.use(async (config) =>
22
- {
23
- console.log("intercept", config.baseURL, config.url);
24
- await this.checkTokenBeforeRequest(config);
25
- return config;
26
- });*/
27
- }
28
-
29
- /*async checkTokenBeforeRequest(config)
30
- {
31
- if (currentToken && isInvalid(this.settings))
32
- { // ignore custom/different JWT tokens
33
- await tryRenew(this.settings);
34
- console.log(`Updating Header with new JWT Token: ${currentToken}`);
35
- this.axiosInstance.headers = {
36
- "Authorization": `Bearer ${currentToken}`,
37
- }
38
- }
39
- }*/
40
-
41
- getUrlOptions()
42
- {
43
- return { withCredentials: false };
44
- }
45
-
46
- async get(uri)
47
- {
48
- try
49
- {
50
- this.axiosInstance = this.getNewAxiosInstance();
51
- const response = await this.axiosInstance.get(uri, this.getUrlOptions());
52
- this.lastError = "";
53
- return response.data;
54
- }
55
- catch (error)
56
- {
57
- this.handleError(error);
58
- }
59
- }
60
-
61
- async getFile(uri)
62
- {
63
- try
64
- {
65
- this.axiosInstance = this.getNewAxiosInstance();
66
- const response = await this.axiosInstance.get(uri, { responseType: "blob" });
67
- let fileName = "1000.pdf";
68
- if (response.headers["content-disposition"])
69
- {
70
- fileName = response.headers["content-disposition"].split(";")[1];
71
- fileName = fileName.replace("filename=", "").trim();
72
- }
73
-
74
- this.lastError = "";
75
- return { data: response.data, filename: fileName, contentType: "application/pdf" };
76
- }
77
- catch (error)
78
- {
79
- this.handleError(error);
80
- }
81
- }
82
-
83
- async getRaw(uri)
84
- {
85
- let response = {};
86
- try
87
- {
88
- this.axiosInstance = this.getNewAxiosInstance();
89
- response = await this.axiosInstance.get(uri, this.getUrlOptions())
90
- this.lastError = "";
91
- }
92
- catch (error)
93
- {
94
- this.handleError(error);
95
- }
96
-
97
- return response;
98
- }
99
-
100
- async post(uri, formData)
101
- {
102
- try
103
- {
104
- this.axiosInstance = this.getNewAxiosInstance();
105
- const response = await this.axiosInstance.post(uri, formData, this.getUrlOptions());
106
- this.lastError = "";
107
- return response;
108
- }
109
- catch (error)
110
- {
111
- this.handleError(error);
112
- }
113
- }
114
-
115
- async put(uri, formData)
116
- {
117
- try
118
- {
119
- this.axiosInstance = this.getNewAxiosInstance();
120
- const response = await this.axiosInstance.put(uri, formData, this.getUrlOptions());
121
- this.lastError = "";
122
- return response;
123
- }
124
- catch (error)
125
- {
126
- this.handleError(error);
127
- }
128
- }
129
-
130
- async delete(uri)
131
- {
132
- try
133
- {
134
- this.axiosInstance = this.getNewAxiosInstance();
135
- const response = await this.axiosInstance.delete(uri, this.getUrlOptions());
136
- this.lastError = "";
137
- return response;
138
- }
139
- catch (error)
140
- {
141
- this.handleError(error);
142
- }
143
- }
144
-
145
- getNewAxiosInstance()
146
- {
147
- return axios.create({
148
- baseURL: this.settings.apiBaseurl,
149
- headers: {
150
- "Authorization": `Bearer ${currentToken}`,
151
- },
152
- });
153
- }
154
-
155
- handleError(error)
156
- {
157
- if (error.response)
158
- {
159
- // The request was made and the server responded with a status code
160
- // that falls out of the range of 2xx
161
- console.error(error.response.data, error.response.status, error.response.headers);
162
- }
163
- else if (error.request)
164
- {
165
- // The request was made but no response was received
166
- // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
167
- // http.ClientRequest in node.js
168
- console.error("Request", error.request);
169
- }
170
- else
171
- {
172
- // Something happened in setting up the request that triggered an Error
173
- console.error("Error", error.message);
174
- }
175
-
176
- console.info("Config", error.config);
177
- this.lastError = error;
178
- }
179
- }
package/api/authUtils.js DELETED
@@ -1,251 +0,0 @@
1
- import { jwtDecode } from "jwt-decode";
2
- import validator from "validator";
3
-
4
- /**
5
- * @typedef {Object} Settings
6
- * @property {string} appToken - The application token.
7
- * @property {string} mandantGuid - The mandant GUID.
8
- * @property {string} apiBaseurl - The base URL for the API.
9
- * @property {string} authUrl - The authentication URL.
10
- */
11
-
12
- /**
13
- * the current JWT token (encoded)
14
- *
15
- * @type {string}
16
- */
17
- export let currentToken = undefined;
18
-
19
- /**
20
- * the current refresh token (UUID v4)
21
- *
22
- * @type {string}
23
- */
24
- export let currentRefreshToken = undefined;
25
-
26
- /**
27
- * initializes the API client with the given appToken
28
- *
29
- * @export
30
- * @async
31
- * @param {string} appToken, UUID v4 format
32
- * @returns {Promise<Settings|null>} settings object
33
- */
34
- export async function initIDAS(appToken)
35
- {
36
- if (!validator.isUUID(appToken))
37
- {
38
- console.error("AppToken is not valid GUID");
39
- return null;
40
- }
41
-
42
- let jwtToken = "";
43
- let mandantGuid = "";
44
- let apiBaseurl = window.document.body.dataset.apiBaseUrl || "https://api.dev.idas-cloudservices.net/api/";
45
- let authUrl = apiBaseurl;
46
- let jwtRefreshToken = localStorage.getItem("IDAS_AuthJwtRefreshToken");
47
-
48
- let urlParams = new URLSearchParams(location.search);
49
- if (urlParams.has("m"))
50
- {
51
- mandantGuid = urlParams.get("m");
52
- }
53
-
54
- if (urlParams.has("a"))
55
- {
56
- apiBaseurl = urlParams.get("a");
57
- }
58
-
59
- if (urlParams.has("j"))
60
- {
61
- jwtToken = urlParams.get("j");
62
- }
63
-
64
- if (urlParams.has("t"))
65
- {
66
- jwtRefreshToken = urlParams.get("t");
67
- }
68
-
69
- authUrl = apiBaseurl;
70
- currentToken = jwtToken;
71
- currentRefreshToken = jwtRefreshToken;
72
- localStorage.setItem("IDAS_AuthJwtRefreshToken", jwtRefreshToken);
73
-
74
- let settings = { appToken, mandantGuid, apiBaseurl, authUrl };
75
- try
76
- {
77
- await setup(settings);
78
- if (isInvalid(settings))
79
- {
80
- redirectToLogin(settings, "/");
81
- }
82
- }
83
- catch
84
- {
85
- redirectToLogin(settings, "/");
86
- }
87
-
88
- return settings;
89
- }
90
-
91
- /**
92
- * sets up authentication
93
- *
94
- * @export
95
- * @async
96
- * @param {Settings} settings
97
- */
98
- export async function setup(settings)
99
- {
100
- console.log("Setup IDAS");
101
- if (!currentToken && !currentRefreshToken)
102
- {
103
- throw ("Either currentToken or currentRefreshToken must be set to authenticate");
104
- }
105
-
106
- if (currentRefreshToken && isInvalid(settings))
107
- {
108
- await tryRenew(settings);
109
- if (isInvalid(settings))
110
- {
111
- console.error("Refresh failed, invalid JWT token!");
112
- }
113
- }
114
- else
115
- {
116
- console.log("Settings already have a valid JWT token, nothing to do");
117
- let decoded = jwtDecode(currentToken);
118
- let refreshToken = decoded["refreshToken"] || "";
119
- if (refreshToken)
120
- {
121
- console.log("Got new refresh token:", refreshToken);
122
- localStorage.setItem("IDAS_AuthJwtRefreshToken", refreshToken);
123
- currentRefreshToken = refreshToken;
124
- startRefreshTimer(settings);
125
- }
126
-
127
- let mandantGuid = decoded["mandantGuid"] || "";
128
- if (mandantGuid)
129
- {
130
- settings.mandantGuid = mandantGuid;
131
- }
132
- }
133
-
134
- console.log("Setup finished", settings);
135
- }
136
-
137
- /**
138
- * starts a timer to refresh the JWT token before it expires
139
- *
140
- * @private
141
- * @type {*}
142
- */
143
- let timerRef = undefined;
144
- function startRefreshTimer(settings)
145
- {
146
- if (timerRef)
147
- {
148
- clearInterval(timerRef);
149
- }
150
-
151
- timerRef = setInterval(() =>
152
- {
153
- if (currentToken)
154
- {
155
- let decoded = jwtDecode(currentToken);
156
- const utcNow = Date.parse(new Date().toUTCString()) / 1000;
157
- if (decoded && utcNow > decoded.exp - 120)
158
- {
159
- tryRenew(settings); // fire & forget/don't await --pr
160
- }
161
- }
162
- }, 5000);
163
- }
164
-
165
- /**
166
- * checks if the current JWT token is invalid
167
- *
168
- * @export
169
- * @param {Settings} settings
170
- * @returns {boolean}
171
- */
172
- export function isInvalid(settings)
173
- {
174
- if (!currentToken)
175
- {
176
- return true;
177
- }
178
-
179
- let decoded = jwtDecode(currentToken);
180
- const utcNow = Date.parse(new Date().toUTCString()) / 1000;
181
- if (decoded && decoded.exp > utcNow)
182
- {
183
- return false;
184
- }
185
-
186
- return true;
187
- }
188
-
189
- /**
190
- * tries to renew the JWT token
191
- *
192
- * @export
193
- * @async
194
- * @param {Settings} settings
195
- */
196
- export async function tryRenew(settings)
197
- {
198
- console.log("Try to refresh");
199
-
200
- const url = settings.authUrl || settings.apiBaseurl;
201
- const payload = { "Token": currentRefreshToken };
202
- const response = await fetch(`${url}LoginJwt/Refresh`, {
203
- method: "PUT",
204
- body: JSON.stringify(payload),
205
- headers: { "Content-Type": "application/json" },
206
- });
207
- const token = await response.json();
208
- currentToken = token;
209
- //console.log("Got JWT token:", currentToken);
210
-
211
- let decoded = jwtDecode(currentToken);
212
- let refreshToken = decoded["refreshToken"] || "";
213
- if (refreshToken)
214
- {
215
- console.log("Got new refresh token:", refreshToken);
216
- currentRefreshToken = refreshToken;
217
- localStorage.setItem("IDAS_AuthJwtRefreshToken", refreshToken);
218
- startRefreshTimer(settings);
219
- }
220
-
221
- let mandantGuid = decoded["mandantGuid"] || "";
222
- if (mandantGuid)
223
- {
224
- settings.mandantGuid = mandantGuid;
225
- }
226
-
227
- if (isInvalid(settings))
228
- {
229
- console.warn("Token is already expired!");
230
- }
231
- }
232
-
233
- /**
234
- * redirects to the login page
235
- *
236
- * @export
237
- * @param {Settings} settings
238
- */
239
- export function redirectToLogin(settings, authPath)
240
- {
241
- const authEndpoint = (new URL(window.location.href).origin) + authPath;
242
- let authUrlCallback = `${authEndpoint}?r=%target%&j=%jwt%&m=%mandant%`;
243
- authUrlCallback = authUrlCallback.replace("%target%", encodeURIComponent(window.location.href));
244
-
245
- const url = new URL(settings.authUrl || settings.apiBaseurl);
246
- url.pathname = "/Session";
247
- url.search = `?a=${settings.appToken}&r=${encodeURIComponent(authUrlCallback)}`;
248
- let jwtUrl = url.toString();
249
-
250
- window.location.href = jwtUrl;
251
- }