@hahnpro/hpc-api 5.2.7 → 5.3.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/dist/api.d.ts +3 -1
- package/dist/api.js +2 -2
- package/dist/http.service.d.ts +6 -2
- package/dist/http.service.js +35 -12
- package/dist/resource.interface.d.ts +13 -0
- package/package.json +3 -3
package/dist/api.d.ts
CHANGED
package/dist/api.js
CHANGED
|
@@ -20,7 +20,7 @@ const label_service_1 = require("./label.service");
|
|
|
20
20
|
const vault_service_1 = require("./vault.service");
|
|
21
21
|
const notification_service_1 = require("./notification.service");
|
|
22
22
|
class API {
|
|
23
|
-
constructor(httpClient) {
|
|
23
|
+
constructor(httpClient, context) {
|
|
24
24
|
this.httpClient = httpClient;
|
|
25
25
|
if (!httpClient) {
|
|
26
26
|
const normalizePath = (value = '', defaultValue = '') => value.replace(/(?:^\/+)|(?:\/+$)/g, '') || defaultValue;
|
|
@@ -38,7 +38,7 @@ class API {
|
|
|
38
38
|
if (!secret) {
|
|
39
39
|
throw new Error('"API_BASE_URL", "API_USER", "AUTH_REALM" and "AUTH_SECRET" environment variables must be set');
|
|
40
40
|
}
|
|
41
|
-
this.httpClient = new http_service_1.HttpClient(apiUrl, authUrl, realm, client, secret);
|
|
41
|
+
this.httpClient = new http_service_1.HttpClient(apiUrl, authUrl, realm, client, secret, context === null || context === void 0 ? void 0 : context.tokenSubject);
|
|
42
42
|
}
|
|
43
43
|
this.assets = new asset_service_1.AssetService(this.httpClient);
|
|
44
44
|
this.assetTypes = new assettypes_service_1.AssetTypesService(this.httpClient);
|
package/dist/http.service.d.ts
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
import { AxiosInstance, AxiosRequestConfig, Method } from 'axios';
|
|
2
2
|
import EventSource from 'eventsource';
|
|
3
3
|
import { Queue } from './Queue';
|
|
4
|
+
import { TokenSet } from './token-set';
|
|
4
5
|
export declare class HttpClient {
|
|
5
6
|
protected readonly baseURL: string;
|
|
6
7
|
protected readonly authBaseURL: string;
|
|
7
8
|
protected readonly realm: string;
|
|
8
9
|
protected readonly clientId: string;
|
|
9
10
|
protected readonly clientSecret: string;
|
|
11
|
+
protected readonly tokenSubject?: string;
|
|
10
12
|
protected readonly axiosInstance: AxiosInstance;
|
|
11
13
|
protected readonly authAxiosInstance: AxiosInstance;
|
|
12
14
|
protected readonly requestQueue: Queue;
|
|
13
15
|
private tokenSet;
|
|
16
|
+
private exchangedTokenSet;
|
|
14
17
|
eventSourcesMap: Map<string, {
|
|
15
18
|
eventSource: EventSource;
|
|
16
19
|
listener: (event: MessageEvent) => void;
|
|
17
20
|
errListener: (event: MessageEvent) => void;
|
|
18
21
|
}>;
|
|
19
|
-
constructor(baseURL: string, authBaseURL: string, realm: string, clientId: string, clientSecret: string);
|
|
22
|
+
constructor(baseURL: string, authBaseURL: string, realm: string, clientId: string, clientSecret: string, tokenSubject?: string);
|
|
20
23
|
getQueueStats: () => {
|
|
21
24
|
peak: number;
|
|
22
25
|
pending: number;
|
|
@@ -34,7 +37,8 @@ export declare class HttpClient {
|
|
|
34
37
|
getAccessToken: (forceRefresh?: boolean) => Promise<string>;
|
|
35
38
|
protected validateIssuer(issuer: Issuer): Issuer;
|
|
36
39
|
protected discoverIssuer(uri: string): Promise<Issuer>;
|
|
37
|
-
protected requestAccessToken(): Promise<
|
|
40
|
+
protected requestAccessToken(additionalOpts?: {}): Promise<TokenSet>;
|
|
41
|
+
protected exchangeAccessToken(accessToken: string): Promise<TokenSet>;
|
|
38
42
|
}
|
|
39
43
|
interface Issuer {
|
|
40
44
|
issuer: string;
|
package/dist/http.service.js
CHANGED
|
@@ -10,12 +10,13 @@ const uuid_1 = require("uuid");
|
|
|
10
10
|
const Queue_1 = require("./Queue");
|
|
11
11
|
const token_set_1 = require("./token-set");
|
|
12
12
|
class HttpClient {
|
|
13
|
-
constructor(baseURL, authBaseURL, realm, clientId, clientSecret) {
|
|
13
|
+
constructor(baseURL, authBaseURL, realm, clientId, clientSecret, tokenSubject) {
|
|
14
14
|
this.baseURL = baseURL;
|
|
15
15
|
this.authBaseURL = authBaseURL;
|
|
16
16
|
this.realm = realm;
|
|
17
17
|
this.clientId = clientId;
|
|
18
18
|
this.clientSecret = clientSecret;
|
|
19
|
+
this.tokenSubject = tokenSubject;
|
|
19
20
|
this.eventSourcesMap = new Map();
|
|
20
21
|
this.getQueueStats = () => { var _a; return (_a = this.requestQueue) === null || _a === void 0 ? void 0 : _a.getStats(); };
|
|
21
22
|
this.delete = (url, config) => this.request('DELETE', url, config);
|
|
@@ -34,10 +35,23 @@ class HttpClient {
|
|
|
34
35
|
}));
|
|
35
36
|
};
|
|
36
37
|
this.getAccessToken = (...args_1) => tslib_1.__awaiter(this, [...args_1], void 0, function* (forceRefresh = false) {
|
|
38
|
+
let accessToken;
|
|
37
39
|
if (forceRefresh || !this.tokenSet || this.tokenSet.isExpired()) {
|
|
38
|
-
|
|
40
|
+
this.tokenSet = yield this.requestAccessToken();
|
|
41
|
+
accessToken = this.tokenSet.accessToken;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
accessToken = this.tokenSet.accessToken;
|
|
45
|
+
}
|
|
46
|
+
if (this.tokenSubject) {
|
|
47
|
+
if (forceRefresh || !this.exchangedTokenSet || this.exchangedTokenSet.isExpired()) {
|
|
48
|
+
this.exchangedTokenSet = yield this.exchangeAccessToken(accessToken);
|
|
49
|
+
}
|
|
50
|
+
return this.exchangedTokenSet.accessToken;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
return accessToken;
|
|
39
54
|
}
|
|
40
|
-
return this.tokenSet.accessToken;
|
|
41
55
|
});
|
|
42
56
|
this.axiosInstance = axios_1.default.create({ baseURL, timeout: 60000 });
|
|
43
57
|
this.authAxiosInstance = axios_1.default.create({ baseURL: authBaseURL || baseURL, timeout: 10000 });
|
|
@@ -95,7 +109,7 @@ class HttpClient {
|
|
|
95
109
|
});
|
|
96
110
|
}
|
|
97
111
|
requestAccessToken() {
|
|
98
|
-
return tslib_1.__awaiter(this,
|
|
112
|
+
return tslib_1.__awaiter(this, arguments, void 0, function* (additionalOpts = {}) {
|
|
99
113
|
var _a, _b;
|
|
100
114
|
const issuer = yield this.discoverIssuer(`${this.authBaseURL}/realms/${this.realm}`);
|
|
101
115
|
const timestamp = Date.now() / 1000;
|
|
@@ -116,23 +130,32 @@ class HttpClient {
|
|
|
116
130
|
const assertion = yield new jose_1.CompactSign(Buffer.from(JSON.stringify(assertionPayload)))
|
|
117
131
|
.setProtectedHeader({ alg })
|
|
118
132
|
.sign(new TextEncoder().encode(this.clientSecret));
|
|
119
|
-
const opts = {
|
|
120
|
-
client_id: this.clientId,
|
|
121
|
-
client_assertion: assertion,
|
|
122
|
-
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
|
|
123
|
-
grant_type: 'client_credentials',
|
|
124
|
-
};
|
|
133
|
+
const opts = Object.assign({ client_id: this.clientId, client_assertion: assertion, client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer', grant_type: 'client_credentials' }, additionalOpts);
|
|
125
134
|
const authResponse = yield this.authAxiosInstance.post(issuer.token_endpoint, (0, querystring_1.stringify)(opts), {
|
|
126
135
|
headers: { Accept: 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
127
136
|
});
|
|
128
137
|
if (((_b = authResponse === null || authResponse === void 0 ? void 0 : authResponse.data) === null || _b === void 0 ? void 0 : _b.access_token) && authResponse.data.expires_in) {
|
|
129
|
-
|
|
130
|
-
return authResponse.data.access_token;
|
|
138
|
+
return new token_set_1.TokenSet(authResponse.data.access_token, authResponse.data.expires_in);
|
|
131
139
|
}
|
|
132
140
|
else {
|
|
133
141
|
throw new Error('Invalid access token received');
|
|
134
142
|
}
|
|
135
143
|
});
|
|
136
144
|
}
|
|
145
|
+
exchangeAccessToken(accessToken) {
|
|
146
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
147
|
+
if (!accessToken || !this.tokenSubject) {
|
|
148
|
+
throw new Error('Could not exchange access token');
|
|
149
|
+
}
|
|
150
|
+
const opts = {
|
|
151
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',
|
|
152
|
+
subject_token: accessToken,
|
|
153
|
+
audience: this.clientId,
|
|
154
|
+
requested_token_type: 'urn:ietf:params:oauth:token-type:access_token',
|
|
155
|
+
requested_subject: this.tokenSubject,
|
|
156
|
+
};
|
|
157
|
+
return this.requestAccessToken(opts);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
137
160
|
}
|
|
138
161
|
exports.HttpClient = HttpClient;
|
|
@@ -5,6 +5,7 @@ export interface ResourceReference {
|
|
|
5
5
|
}
|
|
6
6
|
export interface Resource {
|
|
7
7
|
id: string;
|
|
8
|
+
owner?: Owner;
|
|
8
9
|
name: string;
|
|
9
10
|
readPermissions: string[];
|
|
10
11
|
readWritePermissions: string[];
|
|
@@ -16,4 +17,16 @@ export interface Resource {
|
|
|
16
17
|
updatedAt?: string | Date;
|
|
17
18
|
deletedAt?: string | Date;
|
|
18
19
|
revision?: string;
|
|
20
|
+
createdBy?: Author;
|
|
21
|
+
updatedBy?: Author;
|
|
22
|
+
}
|
|
23
|
+
export interface Author {
|
|
24
|
+
id: string;
|
|
25
|
+
username: string;
|
|
26
|
+
impersonatorId?: string;
|
|
27
|
+
impersonatorUsername?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface Owner {
|
|
30
|
+
id: string;
|
|
31
|
+
type: 'org' | 'user';
|
|
19
32
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hahnpro/hpc-api",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "Module for easy access to the HahnPRO API",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"axios": "1.7.
|
|
27
|
+
"axios": "1.7.4",
|
|
28
28
|
"eventsource": "2.0.2",
|
|
29
29
|
"form-data": "4.0.0",
|
|
30
|
-
"jose": "5.
|
|
30
|
+
"jose": "5.7.0",
|
|
31
31
|
"jwt-decode": "4.0.0",
|
|
32
32
|
"p-queue": "6.6.2",
|
|
33
33
|
"ts-mixer": "6.0.4",
|