@gandalan/weblibs 0.0.40 → 1.0.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.
- package/api/IDAS.js +81 -59
- package/api/RESTClient.js +79 -2
- package/package.json +2 -1
package/api/IDAS.js
CHANGED
|
@@ -2,133 +2,155 @@ import { RESTClient } from './RESTClient';
|
|
|
2
2
|
|
|
3
3
|
let appToken = localStorage.getItem('IDAS_AppToken') || '66B70E0B-F7C4-4829-B12A-18AD309E3970';
|
|
4
4
|
let authToken = localStorage.getItem('IDAS_AuthToken');
|
|
5
|
-
let authJwtToken = localStorage.getItem('IDAS_AuthJwtToken');
|
|
6
5
|
let apiBaseUrl = localStorage.getItem('IDAS_ApiBaseUrl') || 'https://api.dev.idas-cloudservices.net/api/';
|
|
6
|
+
let authJwtCallbackPath = localStorage.getItem('IDAS_AuthJwtCallbackPath') || '';
|
|
7
|
+
let authJwtToken;
|
|
7
8
|
|
|
8
|
-
let
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
}
|
|
9
|
+
export let IDASFactory = {
|
|
10
|
+
async create() {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
let idas = new IDAS();
|
|
13
|
+
resolve(idas.authenticateWithJwt(authJwtCallbackPath));
|
|
14
|
+
});
|
|
15
|
+
},
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
authorize() {
|
|
18
|
+
var urlParams = new URLSearchParams(location.search);
|
|
19
|
+
if (urlParams.has('t')) {
|
|
20
|
+
let idas = new IDAS();
|
|
21
|
+
idas.authorizeWithJwt(urlParams.get('t'));
|
|
22
|
+
}
|
|
23
|
+
if (urlParams.has("m")) {
|
|
24
|
+
localStorage.setItem("IDAS_MandantGuid", urlParams.get("m"));
|
|
25
|
+
}
|
|
26
|
+
if (urlParams.has("a")) {
|
|
27
|
+
localStorage.setItem("IDAS_ApiBaseUrl", urlParams.get("a"));
|
|
25
28
|
}
|
|
26
|
-
|
|
29
|
+
window.location.search = "";
|
|
27
30
|
}
|
|
31
|
+
}
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
{
|
|
32
|
-
const url = new URL(apiBaseUrl);
|
|
33
|
-
url.pathname = "/SSO";
|
|
34
|
-
url.search = "?a=" + appToken;
|
|
35
|
-
if (forceRenew)
|
|
36
|
-
url.search = url.search + "&forceRenew=true";
|
|
37
|
-
url.search = url.search + "&r=%target%%3Ft=%token%%26m=%mandant%";
|
|
38
|
-
let ssoAuthUrl = url.toString();
|
|
33
|
+
class IDAS {
|
|
34
|
+
restClient = undefined;
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
authorizeWithJwt(jwtToken, mandant = '') {
|
|
37
|
+
authJwtToken = jwtToken;
|
|
38
|
+
mandant && localStorage.setItem('IDAS_MandantGuid', mandant);
|
|
39
|
+
this.restClient = new RESTClient(apiBaseUrl, jwtToken, true);
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
async authenticateWithJwt() {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
async authenticateWithJwt(authPath) {
|
|
43
|
+
return new Promise(async (resolve, reject) => {
|
|
44
|
+
// no valid JWT, but try to use "refresh token" first to retrive new JWT
|
|
45
|
+
var refreshClient = new RESTClient(apiBaseUrl, '');
|
|
46
|
+
await refreshClient.checkRefreshToken(authJwtToken, () => {
|
|
47
|
+
authJwtToken = undefined;
|
|
48
|
+
// ... so repeat authenticate (should lead to /Session login page)
|
|
49
|
+
new IDAS().authenticateWithJwt(authPath);
|
|
50
|
+
});
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
// still not valid JWT -> authenticate
|
|
53
|
+
if (!refreshClient.token) {
|
|
54
|
+
localStorage.setItem('IDAS_AuthJwtCallbackPath', authPath);
|
|
55
|
+
const authEndpoint = (new URL(window.location.href).origin) + authPath;
|
|
56
|
+
let authUrlCallback = `${authEndpoint}?r=%target%&t=%jwt%&m=%mandant%`;
|
|
57
|
+
authUrlCallback = authUrlCallback.replace('%target%', encodeURIComponent(window.location.href));
|
|
58
|
+
|
|
59
|
+
const url = new URL(apiBaseUrl);
|
|
60
|
+
url.pathname = "/Session";
|
|
61
|
+
url.search = `?a=${appToken}&r=${encodeURIComponent(authUrlCallback)}`;
|
|
62
|
+
let jwtUrl = url.toString();
|
|
63
|
+
|
|
64
|
+
window.location = jwtUrl;
|
|
65
|
+
reject('not authenticated yet');
|
|
66
|
+
} else {
|
|
67
|
+
this.authorizeWithJwt(refreshClient.token);
|
|
68
|
+
resolve(this);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
56
71
|
}
|
|
57
72
|
|
|
58
73
|
mandantGuid = localStorage.getItem('IDAS_MandantGuid');
|
|
59
74
|
|
|
60
75
|
auth = {
|
|
76
|
+
_self: this,
|
|
61
77
|
async getCurrentAuthToken() {
|
|
62
|
-
return await restClient.put('/Login/Update/', { Token: authToken })
|
|
78
|
+
return await this._self.restClient.put('/Login/Update/', { Token: authToken })
|
|
63
79
|
},
|
|
64
80
|
};
|
|
65
81
|
|
|
66
82
|
mandanten = {
|
|
83
|
+
_self: this,
|
|
67
84
|
async getAll() {
|
|
68
|
-
return await restClient.get('/Mandanten');
|
|
85
|
+
return await this._self.restClient.get('/Mandanten');
|
|
69
86
|
},
|
|
70
87
|
async get(guid) {
|
|
71
|
-
return await restClient.get(`/Mandanten/${guid}`);
|
|
88
|
+
return await this._self.restClient.get(`/Mandanten/${guid}`);
|
|
72
89
|
},
|
|
73
90
|
async save(m) {
|
|
74
|
-
await restClient.put('/Mandanten', m);
|
|
91
|
+
await this._self.restClient.put('/Mandanten', m);
|
|
75
92
|
},
|
|
76
93
|
};
|
|
77
94
|
|
|
78
95
|
benutzer = {
|
|
96
|
+
_self: this,
|
|
79
97
|
async getAll(mandantGuid) {
|
|
80
|
-
return await restClient.get(`/BenutzerListe/${mandantGuid }/?mitRollenUndRechten=true`);
|
|
98
|
+
return await this._self.restClient.get(`/BenutzerListe/${mandantGuid }/?mitRollenUndRechten=true`);
|
|
81
99
|
},
|
|
82
100
|
async get(guid) {
|
|
83
|
-
return await restClient.get(`/Benutzer/${guid}`);
|
|
101
|
+
return await this._self.restClient.get(`/Benutzer/${guid}`);
|
|
84
102
|
},
|
|
85
103
|
async save(m) {
|
|
86
|
-
await restClient.put('/Benutzer', m);
|
|
104
|
+
await this._self.restClient.put('/Benutzer', m);
|
|
87
105
|
},
|
|
88
106
|
};
|
|
89
107
|
|
|
90
108
|
feedback = {
|
|
109
|
+
_self: this,
|
|
91
110
|
async getAll() {
|
|
92
|
-
return await restClient.get('/Feedback/');
|
|
111
|
+
return await this._self.restClient.get('/Feedback/');
|
|
93
112
|
},
|
|
94
113
|
async get(guid) {
|
|
95
|
-
return await restClient.get(`/Feedback/${guid}`);
|
|
114
|
+
return await this._self.restClient.get(`/Feedback/${guid}`);
|
|
96
115
|
},
|
|
97
116
|
async save(m) {
|
|
98
|
-
await restClient.put('/Feedback', m);
|
|
117
|
+
await this._self.restClient.put('/Feedback', m);
|
|
99
118
|
},
|
|
100
119
|
async comment(guid, commentData) {
|
|
101
|
-
await restClient.put(`/FeedbackKommentar/${guid}`, commentData);
|
|
120
|
+
await this._self.restClient.put(`/FeedbackKommentar/${guid}`, commentData);
|
|
102
121
|
},
|
|
103
122
|
async attachFile(guid, filename, data) {
|
|
104
|
-
await restClient.put(`/FeedbackAttachment/?feedbackGuid=${guid}&filename=${filename}`, data);
|
|
123
|
+
await this._self.restClient.put(`/FeedbackAttachment/?feedbackGuid=${guid}&filename=${filename}`, data);
|
|
105
124
|
},
|
|
106
125
|
async deleteFile(guid) {
|
|
107
|
-
await restClient.delete(`/FeedbackAttachment/${guid}`);
|
|
126
|
+
await this._self.restClient.delete(`/FeedbackAttachment/${guid}`);
|
|
108
127
|
},
|
|
109
128
|
};
|
|
110
129
|
|
|
111
130
|
rollen = {
|
|
131
|
+
_self: this,
|
|
112
132
|
async getAll() {
|
|
113
|
-
return await restClient.get('/Rollen');
|
|
133
|
+
return await this._self.restClient.get('/Rollen');
|
|
114
134
|
},
|
|
115
135
|
async save(m) {
|
|
116
|
-
await restClient.put('/Rollen', m);
|
|
136
|
+
await this._self.restClient.put('/Rollen', m);
|
|
117
137
|
},
|
|
118
138
|
};
|
|
119
139
|
|
|
120
140
|
vorgaenge = {
|
|
141
|
+
_self: this,
|
|
121
142
|
async getByVorgangsnummer(vorgangsNummer, jahr) {
|
|
122
|
-
return await restClient.get(`/Vorgang/${vorgangsNummer}/${jahr}`);
|
|
143
|
+
return await this._self.restClient.get(`/Vorgang/${vorgangsNummer}/${jahr}`);
|
|
123
144
|
},
|
|
124
145
|
};
|
|
125
146
|
|
|
126
147
|
positionen = {
|
|
148
|
+
_self: this,
|
|
127
149
|
async getByPcode(pcode) {
|
|
128
|
-
return await restClient.get(`/BelegPositionen/GetByPcode/${pcode}`);
|
|
150
|
+
return await this._self.restClient.get(`/BelegPositionen/GetByPcode/${pcode}`);
|
|
129
151
|
},
|
|
130
152
|
async get(guid) {
|
|
131
|
-
return await restClient.get(`/BelegPositionen/Get/${guid}`);
|
|
153
|
+
return await this._self.restClient.get(`/BelegPositionen/Get/${guid}`);
|
|
132
154
|
},
|
|
133
155
|
};
|
|
134
156
|
}
|
package/api/RESTClient.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
+
import jwt_decode from 'jwt-decode';
|
|
2
3
|
|
|
3
4
|
/*export let AppToken = "66B70E0B-F7C4-4829-B12A-18AD309E3970";
|
|
4
5
|
export let AuthToken = localStorage.getItem("AuthToken");
|
|
@@ -7,6 +8,8 @@ export let ApiBaseUrl = localStorage.getItem("ApiBaseUrl") || "https://api.dev.i
|
|
|
7
8
|
export let SiteBaseUrl = window.location.origin;
|
|
8
9
|
export let SSOAuthUrl = ApiBaseUrl.replace("/api", '') + "/SSO?a=" + AppToken + "&r=%target%?t=%token%%26m=%mandant%";*/
|
|
9
10
|
|
|
11
|
+
let authJwtRefreshToken = localStorage.getItem('IDAS_AuthJwtRefreshToken');
|
|
12
|
+
|
|
10
13
|
export class RESTClient {
|
|
11
14
|
lastError = '';
|
|
12
15
|
token = '';
|
|
@@ -22,11 +25,85 @@ export class RESTClient {
|
|
|
22
25
|
axios.defaults.headers.common['X-Gdl-AuthToken'] = this.token;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
if (this.token && isJWT) {
|
|
29
|
+
this.updateJwtToken(token);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
axios.interceptors.request.use(async (config) => {
|
|
33
|
+
await this.checkAuthorizationHeader(config);
|
|
34
|
+
return config;
|
|
27
35
|
});
|
|
28
36
|
}
|
|
29
37
|
|
|
38
|
+
async checkAuthorizationHeader(config) {
|
|
39
|
+
let authHeader = config.headers['Authorization'];
|
|
40
|
+
if (authHeader && authHeader.toString().startsWith('Bearer ')) {
|
|
41
|
+
let parts = authHeader.toString().split(' ');
|
|
42
|
+
let jwt = parts[1];
|
|
43
|
+
if (!this.isJwtTokenExpired(jwt)) {
|
|
44
|
+
// JWT token is not expired
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// expired token - refresh
|
|
49
|
+
await this.checkRefreshToken(jwt);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async checkRefreshToken(jwt, authCallback) {
|
|
54
|
+
if (!jwt && authJwtRefreshToken) {
|
|
55
|
+
this.onError = (error, message) => {
|
|
56
|
+
// LoginJwt/Refresh failed, which means "refresh token" is expired/invalid...
|
|
57
|
+
if (message.indexOf("401") != -1 || message.indexOf("403") != -1) {
|
|
58
|
+
authJwtRefreshToken = undefined;
|
|
59
|
+
localStorage.removeItem('IDAS_AuthJwtRefreshToken');
|
|
60
|
+
// ... so repeat authenticate
|
|
61
|
+
authCallback && authCallback();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
// fetch fresh JWT
|
|
65
|
+
await this.refreshToken();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.token = jwt;
|
|
69
|
+
this.isJWT = true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
isJwtTokenExpired(jwt) {
|
|
73
|
+
if (!jwt) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let decoded = jwt_decode(jwt);
|
|
78
|
+
const utcNow = Date.parse(new Date().toUTCString()) / 1000;
|
|
79
|
+
|
|
80
|
+
if (decoded && decoded.exp >= utcNow) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
updateJwtToken(jwt) {
|
|
88
|
+
let decoded = jwt_decode(jwt);
|
|
89
|
+
let refreshToken = decoded['refreshToken'];
|
|
90
|
+
localStorage.setItem('IDAS_AuthJwtRefreshToken', refreshToken);
|
|
91
|
+
authJwtRefreshToken = refreshToken;
|
|
92
|
+
this.token = jwt;
|
|
93
|
+
this.isJWT = true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async refreshToken() {
|
|
97
|
+
try {
|
|
98
|
+
await axios.put(this.baseurl + '/LoginJwt/Refresh', { token: localStorage.getItem('IDAS_AuthJwtRefreshToken') })
|
|
99
|
+
.then(resp => {
|
|
100
|
+
this.updateJwtToken(resp.data);
|
|
101
|
+
});
|
|
102
|
+
} catch (error) {
|
|
103
|
+
this.handleError(error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
30
107
|
updateToken(token) {
|
|
31
108
|
this.token = token;
|
|
32
109
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gandalan/weblibs",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "WebLibs for Gandalan JS/TS/Svelte projects",
|
|
5
5
|
"author": "Philipp Reif",
|
|
6
6
|
"license": "ISC",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@mdi/js": "^7.0.96",
|
|
25
25
|
"axios": "^0.27.2",
|
|
26
|
+
"jwt-decode": "^3.1.2",
|
|
26
27
|
"svelte-table": "^0.5.1"
|
|
27
28
|
},
|
|
28
29
|
"peerDependencies": {
|