@gandalan/weblibs 1.5.37 → 2.0.2
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/api/fluentApi.js +36 -31
- package/api/fluentRestClient.js +13 -8
- package/index.d.ts +0 -12
- package/index.js +0 -5
- package/package.json +1 -2
- package/scripts/generate-dts.mjs +2 -6
- package/api/IDAS.js +0 -152
- package/api/RESTClient.js +0 -179
- package/api/authUtils.js +0 -251
package/api/fluentApi.js
CHANGED
|
@@ -73,44 +73,47 @@ export function createApi() {
|
|
|
73
73
|
},
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
76
|
+
* Sends a GET request, ensuring authentication if needed.
|
|
77
|
+
*
|
|
78
|
+
* @async
|
|
79
|
+
* @param {string} [url=""]
|
|
80
|
+
* @param {boolean} [auth=true]
|
|
81
|
+
* @param {boolean} [skipResponseParsing=false]
|
|
82
|
+
* @returns {Promise<Object>}
|
|
83
|
+
*/
|
|
84
|
+
async get(url = "", auth = true, skipResponseParsing = false) {
|
|
84
85
|
await this.preCheck(auth);
|
|
85
|
-
return await this.createRestClient().get(url);
|
|
86
|
+
return await this.createRestClient().get(url, auth, skipResponseParsing);
|
|
86
87
|
},
|
|
87
88
|
|
|
88
89
|
/**
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
90
|
+
* Sends a PUT request with a payload, ensuring authentication if needed.
|
|
91
|
+
*
|
|
92
|
+
* @async
|
|
93
|
+
* @param {string} [url=""]
|
|
94
|
+
* @param {Object} [payload={}]
|
|
95
|
+
* @param {boolean} [auth=true]
|
|
96
|
+
* @param {boolean} [skipResponseParsing=false]
|
|
97
|
+
* @returns {Promise<Object>}
|
|
98
|
+
*/
|
|
99
|
+
async put(url = "", payload = {}, auth = true, skipResponseParsing = false) {
|
|
98
100
|
await this.preCheck(auth);
|
|
99
|
-
return await this.createRestClient().put(url, payload);
|
|
101
|
+
return await this.createRestClient().put(url, payload, skipResponseParsing);
|
|
100
102
|
},
|
|
101
103
|
|
|
102
104
|
/**
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
* Sends a POST request with a payload, ensuring authentication if needed.
|
|
106
|
+
*
|
|
107
|
+
* @async
|
|
108
|
+
* @param {string} [url=""]
|
|
109
|
+
* @param {Object} [payload={}]
|
|
110
|
+
* @param {boolean} [auth=true]
|
|
111
|
+
* @param {boolean} [skipResponseParsing=false]
|
|
112
|
+
* @returns {Promise<Object>}
|
|
113
|
+
*/
|
|
114
|
+
async post(url = "", payload = {}, auth = true, skipResponseParsing = false) {
|
|
112
115
|
await this.preCheck(auth);
|
|
113
|
-
return await this.createRestClient().post(url, payload);
|
|
116
|
+
return await this.createRestClient().post(url, payload, skipResponseParsing);
|
|
114
117
|
},
|
|
115
118
|
|
|
116
119
|
/**
|
|
@@ -118,12 +121,14 @@ export function createApi() {
|
|
|
118
121
|
*
|
|
119
122
|
* @async
|
|
120
123
|
* @param {string} [url=""]
|
|
124
|
+
* @param {Object|FormData} [payload=null]
|
|
121
125
|
* @param {boolean} [auth=true]
|
|
126
|
+
* @param {boolean} [skipResponseParsing=false]
|
|
122
127
|
* @returns {Promise<Object>}
|
|
123
128
|
*/
|
|
124
|
-
async delete(url = "", payload = null, auth = true) {
|
|
129
|
+
async delete(url = "", payload = null, auth = true, skipResponseParsing = false) {
|
|
125
130
|
await this.preCheck(auth);
|
|
126
|
-
return await this.createRestClient().delete(url, payload);
|
|
131
|
+
return await this.createRestClient().delete(url, payload, skipResponseParsing);
|
|
127
132
|
},
|
|
128
133
|
|
|
129
134
|
/**
|
package/api/fluentRestClient.js
CHANGED
|
@@ -60,14 +60,15 @@ export function restClient() {
|
|
|
60
60
|
* @async
|
|
61
61
|
* @param {string} [url=""]
|
|
62
62
|
* @param {boolean} [auth=true]
|
|
63
|
+
* @param {boolean} [skipResponseParsing=false]
|
|
63
64
|
* @returns {Promise<any>}
|
|
64
65
|
*/
|
|
65
|
-
async get(url = "", auth = true) {
|
|
66
|
+
async get(url = "", auth = true, skipResponseParsing = false) {
|
|
66
67
|
const finalUrl = `${this.baseUrl}${url}`;
|
|
67
68
|
const headers = this._createHeaders();
|
|
68
69
|
const res = await fetch(finalUrl, { method: "GET", headers });
|
|
69
70
|
if (res.ok) {
|
|
70
|
-
return await this._parseReponse(res);
|
|
71
|
+
return skipResponseParsing ? res : await this._parseReponse(res);
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
throw new Error(`GET ${finalUrl} failed: ${res.status} ${res.statusText}`);
|
|
@@ -79,14 +80,15 @@ export function restClient() {
|
|
|
79
80
|
* @async
|
|
80
81
|
* @param {string} [url=""]
|
|
81
82
|
* @param {Object} [payload={}]
|
|
83
|
+
* @param {boolean} [skipResponseParsing=false]
|
|
82
84
|
* @returns {Promise<any>}
|
|
83
85
|
*/
|
|
84
|
-
async put(url = "", payload = {}) {
|
|
86
|
+
async put(url = "", payload = {}, skipResponseParsing = false) {
|
|
85
87
|
const finalUrl = `${this.baseUrl}${url}`;
|
|
86
88
|
const headers = this._createHeaders("application/json");
|
|
87
89
|
const res = await fetch(finalUrl, { method: "PUT", body: JSON.stringify(payload), headers });
|
|
88
90
|
if (res.ok) {
|
|
89
|
-
return await this._parseReponse(res);
|
|
91
|
+
return skipResponseParsing ? res : await this._parseReponse(res);
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
throw new Error(`PUT ${finalUrl} failed: ${res.status} ${res.statusText}`);
|
|
@@ -98,9 +100,10 @@ export function restClient() {
|
|
|
98
100
|
* @async
|
|
99
101
|
* @param {string} [url=""]
|
|
100
102
|
* @param {Object|FormData} [payload={}]
|
|
103
|
+
* @param {boolean} [skipResponseParsing=false]
|
|
101
104
|
* @returns {Promise<any>}
|
|
102
105
|
*/
|
|
103
|
-
async post(url = "", payload = {}) {
|
|
106
|
+
async post(url = "", payload = {}, skipResponseParsing = false) {
|
|
104
107
|
const finalUrl = `${this.baseUrl}${url}`;
|
|
105
108
|
let headers;
|
|
106
109
|
|
|
@@ -116,7 +119,7 @@ export function restClient() {
|
|
|
116
119
|
|
|
117
120
|
const res = await fetch(finalUrl, { method: "POST", body, headers });
|
|
118
121
|
if (res.ok) {
|
|
119
|
-
return await this._parseReponse(res);
|
|
122
|
+
return skipResponseParsing ? res : await this._parseReponse(res);
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
throw new Error(`POST ${finalUrl} failed: ${res.status} ${res.statusText}`);
|
|
@@ -127,9 +130,11 @@ export function restClient() {
|
|
|
127
130
|
*
|
|
128
131
|
* @async
|
|
129
132
|
* @param {string} [url=""]
|
|
133
|
+
* @param {Object|FormData} [payload=null]
|
|
134
|
+
* @param {boolean} [skipResponseParsing=false]
|
|
130
135
|
* @returns {Promise<any>}
|
|
131
136
|
*/
|
|
132
|
-
async delete(url = "", payload = null) {
|
|
137
|
+
async delete(url = "", payload = null, skipResponseParsing = false) {
|
|
133
138
|
const finalUrl = `${this.baseUrl}${url}`;
|
|
134
139
|
const hasBody = payload !== null && payload !== undefined;
|
|
135
140
|
const isFormData = payload instanceof FormData;
|
|
@@ -137,7 +142,7 @@ export function restClient() {
|
|
|
137
142
|
const body = !hasBody ? undefined : isFormData ? payload : JSON.stringify(payload);
|
|
138
143
|
const res = await fetch(finalUrl, { method: "DELETE", headers, body });
|
|
139
144
|
if (res.ok) {
|
|
140
|
-
return await this._parseReponse(res);
|
|
145
|
+
return skipResponseParsing ? res : await this._parseReponse(res);
|
|
141
146
|
}
|
|
142
147
|
|
|
143
148
|
throw new Error(`DELETE ${finalUrl} failed: ${res.status} ${res.statusText}`);
|
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": "
|
|
3
|
+
"version": "2.0.2",
|
|
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
|
},
|
package/scripts/generate-dts.mjs
CHANGED
|
@@ -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
|
-
}
|