@go-mondo/identity-sdk 0.0.2-beta.82 → 0.0.2-beta.83
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/.release-please-manifest.json +1 -1
- package/.tsbuildinfo/cjs.json +1 -1
- package/.tsbuildinfo/esm.json +1 -1
- package/CHANGELOG.md +7 -0
- package/dist/cjs/activity/resources.js +1 -1
- package/dist/cjs/activity/resources.test.js +5 -5
- package/dist/cjs/app/authorization/resources.js +2 -2
- package/dist/cjs/app/oauth/resources.js +2 -2
- package/dist/cjs/app/oidc/resources.js +4 -4
- package/dist/cjs/app/registration/resources.js +2 -2
- package/dist/cjs/app/registration/resources.test.js +5 -5
- package/dist/cjs/app/resources.js +5 -5
- package/dist/cjs/app/resources.test.js +5 -5
- package/dist/cjs/app/saml/resources.js +4 -4
- package/dist/cjs/association/resources.js +3 -3
- package/dist/cjs/authentication/sessions/resources.js +2 -2
- package/dist/cjs/authentication/settings/resources.js +2 -2
- package/dist/cjs/authentication/strategies/resources.js +5 -5
- package/dist/cjs/authorization/permissions/resources.js +5 -5
- package/dist/cjs/authorization/roles/resources.js +5 -5
- package/dist/cjs/common/index.d.ts +1 -0
- package/dist/cjs/common/index.d.ts.map +1 -1
- package/dist/cjs/common/resources/authorization.d.ts +18 -1
- package/dist/cjs/common/resources/authorization.d.ts.map +1 -1
- package/dist/cjs/common/resources/authorization.js +6 -0
- package/dist/cjs/common/resources/init.d.ts +5 -5
- package/dist/cjs/common/resources/init.d.ts.map +1 -1
- package/dist/cjs/common/resources/init.js +20 -14
- package/dist/cjs/common/resources/init.test.js +55 -31
- package/dist/cjs/common/resources/operations.d.ts +7 -7
- package/dist/cjs/common/resources/operations.d.ts.map +1 -1
- package/dist/cjs/common/resources/operations.js +35 -19
- package/dist/cjs/common/resources/operations.test.js +32 -2
- package/dist/cjs/customer/users/resources.js +5 -5
- package/dist/esm/activity/resources.js +1 -1
- package/dist/esm/activity/resources.test.js +5 -5
- package/dist/esm/app/authorization/resources.js +2 -2
- package/dist/esm/app/oauth/resources.js +2 -2
- package/dist/esm/app/oidc/resources.js +4 -4
- package/dist/esm/app/registration/resources.js +2 -2
- package/dist/esm/app/registration/resources.test.js +5 -5
- package/dist/esm/app/resources.js +5 -5
- package/dist/esm/app/resources.test.js +5 -5
- package/dist/esm/app/saml/resources.js +4 -4
- package/dist/esm/association/resources.js +3 -3
- package/dist/esm/authentication/sessions/resources.js +2 -2
- package/dist/esm/authentication/settings/resources.js +2 -2
- package/dist/esm/authentication/strategies/resources.js +5 -5
- package/dist/esm/authorization/permissions/resources.js +5 -5
- package/dist/esm/authorization/roles/resources.js +5 -5
- package/dist/esm/common/index.d.ts +1 -0
- package/dist/esm/common/index.d.ts.map +1 -1
- package/dist/esm/common/resources/authorization.d.ts +18 -1
- package/dist/esm/common/resources/authorization.d.ts.map +1 -1
- package/dist/esm/common/resources/authorization.js +5 -1
- package/dist/esm/common/resources/init.d.ts +5 -5
- package/dist/esm/common/resources/init.d.ts.map +1 -1
- package/dist/esm/common/resources/init.js +20 -14
- package/dist/esm/common/resources/init.test.js +56 -32
- package/dist/esm/common/resources/operations.d.ts +7 -7
- package/dist/esm/common/resources/operations.d.ts.map +1 -1
- package/dist/esm/common/resources/operations.js +35 -19
- package/dist/esm/common/resources/operations.test.js +32 -2
- package/dist/esm/customer/users/resources.js +5 -5
- package/package.json +1 -1
|
@@ -20,7 +20,7 @@ const init_js_1 = require("./init.js");
|
|
|
20
20
|
};
|
|
21
21
|
const mondoIdentity = new init_js_1.MondoIdentity(config);
|
|
22
22
|
(0, vitest_1.expect)(mondoIdentity.config.accessToken).toBe('test-access-token');
|
|
23
|
-
(0, vitest_1.expect)(mondoIdentity.config.host.toString()).toBe('https://
|
|
23
|
+
(0, vitest_1.expect)(mondoIdentity.config.host.toString()).toBe('https://api.mondoidentity.com/');
|
|
24
24
|
});
|
|
25
25
|
(0, vitest_1.test)('should parse URL host correctly', () => {
|
|
26
26
|
const config = {
|
|
@@ -64,6 +64,11 @@ const init_js_1 = require("./init.js");
|
|
|
64
64
|
};
|
|
65
65
|
(0, vitest_1.expect)(() => new init_js_1.MondoIdentity(config)).toThrow('Invalid configuration');
|
|
66
66
|
});
|
|
67
|
+
(0, vitest_1.test)('should initialize with an access token provider', () => {
|
|
68
|
+
const accessToken = vitest_1.vi.fn(() => 'provided-token');
|
|
69
|
+
const mondoIdentity = new init_js_1.MondoIdentity({ accessToken });
|
|
70
|
+
(0, vitest_1.expect)(mondoIdentity.config.accessToken).toBe(accessToken);
|
|
71
|
+
});
|
|
67
72
|
});
|
|
68
73
|
(0, vitest_1.describe)('config property', () => {
|
|
69
74
|
(0, vitest_1.test)('should be readonly', () => {
|
|
@@ -87,29 +92,29 @@ const init_js_1 = require("./init.js");
|
|
|
87
92
|
(0, vitest_1.expect)(mondoIdentity.config.host.toString()).toBe(`${config.host}/`);
|
|
88
93
|
});
|
|
89
94
|
});
|
|
90
|
-
(0, vitest_1.describe)('
|
|
91
|
-
(0, vitest_1.test)('should return function that adds authorization header when access token is provided', () => {
|
|
95
|
+
(0, vitest_1.describe)('authorize property', () => {
|
|
96
|
+
(0, vitest_1.test)('should return function that adds authorization header when access token is provided', async () => {
|
|
92
97
|
const config = {
|
|
93
98
|
accessToken: 'bearer-token-123',
|
|
94
99
|
};
|
|
95
100
|
const mondoIdentity = new init_js_1.MondoIdentity(config);
|
|
96
|
-
const
|
|
97
|
-
(0, vitest_1.expect)(typeof
|
|
101
|
+
const authorize = mondoIdentity.authorize;
|
|
102
|
+
(0, vitest_1.expect)(typeof authorize).toBe('function');
|
|
98
103
|
const mockRequest = {
|
|
99
104
|
method: 'GET',
|
|
100
105
|
headers: {},
|
|
101
106
|
};
|
|
102
|
-
const authorizedRequest =
|
|
107
|
+
const authorizedRequest = await authorize(mockRequest);
|
|
103
108
|
(0, vitest_1.expect)(authorizedRequest.headers).toBeInstanceOf(Headers);
|
|
104
109
|
const headers = authorizedRequest.headers;
|
|
105
110
|
(0, vitest_1.expect)(headers.get('authorization')).toBe('bearer-token-123');
|
|
106
111
|
});
|
|
107
|
-
(0, vitest_1.test)('should preserve existing headers when adding authorization', () => {
|
|
112
|
+
(0, vitest_1.test)('should preserve existing headers when adding authorization', async () => {
|
|
108
113
|
const config = {
|
|
109
114
|
accessToken: 'test-token',
|
|
110
115
|
};
|
|
111
116
|
const mondoIdentity = new init_js_1.MondoIdentity(config);
|
|
112
|
-
const
|
|
117
|
+
const authorize = mondoIdentity.authorize;
|
|
113
118
|
const mockRequest = {
|
|
114
119
|
method: 'POST',
|
|
115
120
|
headers: {
|
|
@@ -117,18 +122,18 @@ const init_js_1 = require("./init.js");
|
|
|
117
122
|
'user-agent': 'test-client',
|
|
118
123
|
},
|
|
119
124
|
};
|
|
120
|
-
const authorizedRequest =
|
|
125
|
+
const authorizedRequest = await authorize(mockRequest);
|
|
121
126
|
const headers = authorizedRequest.headers;
|
|
122
127
|
(0, vitest_1.expect)(headers.get('authorization')).toBe('test-token');
|
|
123
128
|
(0, vitest_1.expect)(headers.get('content-type')).toBe('application/json');
|
|
124
129
|
(0, vitest_1.expect)(headers.get('user-agent')).toBe('test-client');
|
|
125
130
|
});
|
|
126
|
-
(0, vitest_1.test)('should handle Headers object as input', () => {
|
|
131
|
+
(0, vitest_1.test)('should handle Headers object as input', async () => {
|
|
127
132
|
const config = {
|
|
128
133
|
accessToken: 'header-token',
|
|
129
134
|
};
|
|
130
135
|
const mondoIdentity = new init_js_1.MondoIdentity(config);
|
|
131
|
-
const
|
|
136
|
+
const authorize = mondoIdentity.authorize;
|
|
132
137
|
const existingHeaders = new Headers({
|
|
133
138
|
accept: 'application/json',
|
|
134
139
|
});
|
|
@@ -136,67 +141,87 @@ const init_js_1 = require("./init.js");
|
|
|
136
141
|
method: 'GET',
|
|
137
142
|
headers: existingHeaders,
|
|
138
143
|
};
|
|
139
|
-
const authorizedRequest =
|
|
144
|
+
const authorizedRequest = await authorize(mockRequest);
|
|
140
145
|
const headers = authorizedRequest.headers;
|
|
141
146
|
(0, vitest_1.expect)(headers.get('authorization')).toBe('header-token');
|
|
142
147
|
(0, vitest_1.expect)(headers.get('accept')).toBe('application/json');
|
|
143
148
|
});
|
|
144
|
-
(0, vitest_1.test)('should handle undefined headers', () => {
|
|
149
|
+
(0, vitest_1.test)('should handle undefined headers', async () => {
|
|
145
150
|
const config = {
|
|
146
151
|
accessToken: 'undefined-headers-token',
|
|
147
152
|
};
|
|
148
153
|
const mondoIdentity = new init_js_1.MondoIdentity(config);
|
|
149
|
-
const
|
|
154
|
+
const authorize = mondoIdentity.authorize;
|
|
150
155
|
const mockRequest = {
|
|
151
156
|
method: 'GET',
|
|
152
157
|
// headers intentionally undefined
|
|
153
158
|
};
|
|
154
|
-
const authorizedRequest =
|
|
159
|
+
const authorizedRequest = await authorize(mockRequest);
|
|
155
160
|
const headers = authorizedRequest.headers;
|
|
156
161
|
(0, vitest_1.expect)(headers.get('authorization')).toBe('undefined-headers-token');
|
|
157
162
|
});
|
|
158
|
-
(0, vitest_1.test)('should return same request reference with modified headers', () => {
|
|
163
|
+
(0, vitest_1.test)('should return same request reference with modified headers', async () => {
|
|
159
164
|
const config = {
|
|
160
165
|
accessToken: 'reference-token',
|
|
161
166
|
};
|
|
162
167
|
const mondoIdentity = new init_js_1.MondoIdentity(config);
|
|
163
|
-
const
|
|
168
|
+
const authorize = mondoIdentity.authorize;
|
|
164
169
|
const mockRequest = {
|
|
165
170
|
method: 'PUT',
|
|
166
171
|
body: 'test-body',
|
|
167
172
|
};
|
|
168
|
-
const authorizedRequest =
|
|
173
|
+
const authorizedRequest = await authorize(mockRequest);
|
|
169
174
|
// Should be the same object reference
|
|
170
175
|
(0, vitest_1.expect)(authorizedRequest).toBe(mockRequest);
|
|
171
176
|
(0, vitest_1.expect)(authorizedRequest.method).toBe('PUT');
|
|
172
177
|
(0, vitest_1.expect)(authorizedRequest.body).toBe('test-body');
|
|
173
178
|
});
|
|
174
|
-
(0, vitest_1.test)('should
|
|
179
|
+
(0, vitest_1.test)('should expose a consistent function', async () => {
|
|
175
180
|
const config = {
|
|
176
181
|
accessToken: 'consistent-token',
|
|
177
182
|
};
|
|
178
183
|
const mondoIdentity = new init_js_1.MondoIdentity(config);
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
const authorizer2 = mondoIdentity.authorizer;
|
|
184
|
+
const authorize1 = mondoIdentity.authorize;
|
|
185
|
+
const authorize2 = mondoIdentity.authorize;
|
|
182
186
|
const mockRequest1 = { method: 'GET' };
|
|
183
187
|
const mockRequest2 = { method: 'POST' };
|
|
184
|
-
const result1 =
|
|
185
|
-
const result2 =
|
|
188
|
+
const result1 = await authorize1(mockRequest1);
|
|
189
|
+
const result2 = await authorize2(mockRequest2);
|
|
186
190
|
const headers1 = result1.headers;
|
|
187
191
|
const headers2 = result2.headers;
|
|
188
192
|
(0, vitest_1.expect)(headers1.get('authorization')).toBe('consistent-token');
|
|
189
193
|
(0, vitest_1.expect)(headers2.get('authorization')).toBe('consistent-token');
|
|
190
194
|
});
|
|
195
|
+
(0, vitest_1.test)('should resolve access token providers with authorize options', async () => {
|
|
196
|
+
const accessToken = vitest_1.vi.fn((options) => options?.refresh ? 'refreshed-token' : 'cached-token');
|
|
197
|
+
const mondoIdentity = new init_js_1.MondoIdentity({ accessToken });
|
|
198
|
+
const cachedRequest = await mondoIdentity.authorize({ method: 'GET' });
|
|
199
|
+
const refreshedRequest = await mondoIdentity.authorize({ method: 'GET' }, { refresh: true });
|
|
200
|
+
(0, vitest_1.expect)(accessToken).toHaveBeenNthCalledWith(1, undefined);
|
|
201
|
+
(0, vitest_1.expect)(accessToken).toHaveBeenNthCalledWith(2, { refresh: true });
|
|
202
|
+
(0, vitest_1.expect)(cachedRequest.headers.get('authorization')).toBe('cached-token');
|
|
203
|
+
(0, vitest_1.expect)(refreshedRequest.headers.get('authorization')).toBe('refreshed-token');
|
|
204
|
+
});
|
|
205
|
+
(0, vitest_1.test)('should use the accessToken value from provider token objects', async () => {
|
|
206
|
+
const accessToken = vitest_1.vi.fn(() => ({
|
|
207
|
+
accessToken: 'object-token',
|
|
208
|
+
expiresAt: Date.now() + 60_000,
|
|
209
|
+
scope: 'workspace:read',
|
|
210
|
+
type: 'Bearer',
|
|
211
|
+
}));
|
|
212
|
+
const mondoIdentity = new init_js_1.MondoIdentity({ accessToken });
|
|
213
|
+
const request = await mondoIdentity.authorize({ method: 'GET' });
|
|
214
|
+
(0, vitest_1.expect)(request.headers.get('authorization')).toBe('object-token');
|
|
215
|
+
});
|
|
191
216
|
});
|
|
192
217
|
(0, vitest_1.describe)('integration tests', () => {
|
|
193
|
-
(0, vitest_1.test)('should work with real-world configuration', () => {
|
|
218
|
+
(0, vitest_1.test)('should work with real-world configuration', async () => {
|
|
194
219
|
const config = {
|
|
195
220
|
accessToken: 'prod_12345abcdef67890',
|
|
196
221
|
host: 'https://api.mondoidentity.com/v1',
|
|
197
222
|
};
|
|
198
223
|
const mondoIdentity = new init_js_1.MondoIdentity(config);
|
|
199
|
-
const
|
|
224
|
+
const authorize = mondoIdentity.authorize;
|
|
200
225
|
// Test configuration
|
|
201
226
|
(0, vitest_1.expect)(mondoIdentity.config.accessToken).toBe('prod_12345abcdef67890');
|
|
202
227
|
(0, vitest_1.expect)(mondoIdentity.config.host).instanceOf(URL);
|
|
@@ -209,21 +234,20 @@ const init_js_1 = require("./init.js");
|
|
|
209
234
|
'user-agent': 'mondo-identity-sdk/1.0.0',
|
|
210
235
|
},
|
|
211
236
|
};
|
|
212
|
-
const authorizedRequest =
|
|
237
|
+
const authorizedRequest = await authorize(apiRequest);
|
|
213
238
|
const headers = authorizedRequest.headers;
|
|
214
239
|
(0, vitest_1.expect)(headers.get('authorization')).toBe('prod_12345abcdef67890');
|
|
215
240
|
(0, vitest_1.expect)(headers.get('accept')).toBe('application/json');
|
|
216
241
|
(0, vitest_1.expect)(headers.get('user-agent')).toBe('mondo-identity-sdk/1.0.0');
|
|
217
242
|
});
|
|
218
|
-
(0, vitest_1.test)('should handle edge cases gracefully', () => {
|
|
243
|
+
(0, vitest_1.test)('should handle edge cases gracefully', async () => {
|
|
219
244
|
const config = {
|
|
220
245
|
accessToken: 'edge-case-token-with-special-chars!@#$%^&*()',
|
|
221
246
|
host: 'https://localhost:3000',
|
|
222
247
|
};
|
|
223
248
|
const mondoIdentity = new init_js_1.MondoIdentity(config);
|
|
224
|
-
(0, vitest_1.expect)(() => {
|
|
225
|
-
const
|
|
226
|
-
const request = authorizer({ method: 'OPTIONS' });
|
|
249
|
+
await (0, vitest_1.expect)(async () => {
|
|
250
|
+
const request = await mondoIdentity.authorize({ method: 'OPTIONS' });
|
|
227
251
|
const headers = request.headers;
|
|
228
252
|
headers.get('authorization');
|
|
229
253
|
}).not.toThrow();
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function listItemsWithAuthorization<Result>(url: URL,
|
|
3
|
-
export declare function getItemWithAuthorization<Result>(url: URL,
|
|
4
|
-
export declare function patchItemWithAuthorization<Result, Mutation>(url: URL,
|
|
5
|
-
export declare function putItemWithAuthorization<Result, Mutation>(url: URL,
|
|
6
|
-
export declare function postItemWithAuthorization<Result, Mutation>(url: URL,
|
|
7
|
-
export declare function deleteItemWithAuthorization<Result>(url: URL,
|
|
1
|
+
import type { Authorizer } from './authorization.js';
|
|
2
|
+
export declare function listItemsWithAuthorization<Result>(url: URL, authorizer: Authorizer): Promise<Result>;
|
|
3
|
+
export declare function getItemWithAuthorization<Result>(url: URL, authorizer: Authorizer): Promise<Result>;
|
|
4
|
+
export declare function patchItemWithAuthorization<Result, Mutation>(url: URL, authorizer: Authorizer, item: Mutation): Promise<Result>;
|
|
5
|
+
export declare function putItemWithAuthorization<Result, Mutation>(url: URL, authorizer: Authorizer, item: Mutation): Promise<Result>;
|
|
6
|
+
export declare function postItemWithAuthorization<Result, Mutation>(url: URL, authorizer: Authorizer, item?: Mutation): Promise<Result>;
|
|
7
|
+
export declare function deleteItemWithAuthorization<Result>(url: URL, authorizer: Authorizer): Promise<Result>;
|
|
8
8
|
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../../../src/common/resources/operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../../../src/common/resources/operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AASrD,wBAAsB,0BAA0B,CAAC,MAAM,EACrD,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EACnD,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE,QAAQ,EAC/D,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,QAAQ,EAC7D,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,MAAM,CAAC,CAEjB;AA2BD,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,QAAQ,EAC9D,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,UAAU,EACtB,IAAI,CAAC,EAAE,QAAQ,GACd,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED,wBAAsB,2BAA2B,CAAC,MAAM,EACtD,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
|
|
@@ -7,13 +7,13 @@ exports.putItemWithAuthorization = putItemWithAuthorization;
|
|
|
7
7
|
exports.postItemWithAuthorization = postItemWithAuthorization;
|
|
8
8
|
exports.deleteItemWithAuthorization = deleteItemWithAuthorization;
|
|
9
9
|
const utils_js_1 = require("./utils.js");
|
|
10
|
-
async function listItemsWithAuthorization(url,
|
|
10
|
+
async function listItemsWithAuthorization(url, authorizer) {
|
|
11
11
|
try {
|
|
12
12
|
console.debug('List items', { url });
|
|
13
|
-
const response = await
|
|
13
|
+
const response = await fetchWithAuthorization(url, authorizer, {
|
|
14
14
|
method: 'GET',
|
|
15
15
|
headers: (0, utils_js_1.defaultRequestHeaders)(),
|
|
16
|
-
})
|
|
16
|
+
});
|
|
17
17
|
if (response.ok) {
|
|
18
18
|
return await response.json();
|
|
19
19
|
}
|
|
@@ -23,13 +23,13 @@ async function listItemsWithAuthorization(url, authorization) {
|
|
|
23
23
|
throw (0, utils_js_1.toHttpError)(error);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
async function getItemWithAuthorization(url,
|
|
26
|
+
async function getItemWithAuthorization(url, authorizer) {
|
|
27
27
|
try {
|
|
28
28
|
console.debug('GET item', { url });
|
|
29
|
-
const response = await
|
|
29
|
+
const response = await fetchWithAuthorization(url, authorizer, {
|
|
30
30
|
method: 'GET',
|
|
31
31
|
headers: (0, utils_js_1.defaultRequestHeaders)(),
|
|
32
|
-
})
|
|
32
|
+
});
|
|
33
33
|
if (response.ok) {
|
|
34
34
|
return await response.json();
|
|
35
35
|
}
|
|
@@ -39,20 +39,20 @@ async function getItemWithAuthorization(url, authorization) {
|
|
|
39
39
|
throw (0, utils_js_1.toHttpError)(error);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
async function patchItemWithAuthorization(url,
|
|
43
|
-
return mutateItemWithAuthorization('PATCH', url,
|
|
42
|
+
async function patchItemWithAuthorization(url, authorizer, item) {
|
|
43
|
+
return mutateItemWithAuthorization('PATCH', url, authorizer, item);
|
|
44
44
|
}
|
|
45
|
-
async function putItemWithAuthorization(url,
|
|
46
|
-
return mutateItemWithAuthorization('PUT', url,
|
|
45
|
+
async function putItemWithAuthorization(url, authorizer, item) {
|
|
46
|
+
return mutateItemWithAuthorization('PUT', url, authorizer, item);
|
|
47
47
|
}
|
|
48
|
-
async function mutateItemWithAuthorization(method, url,
|
|
48
|
+
async function mutateItemWithAuthorization(method, url, authorizer, item) {
|
|
49
49
|
try {
|
|
50
50
|
console.debug(`${method} item`, { url, item });
|
|
51
|
-
const response = await
|
|
51
|
+
const response = await fetchWithAuthorization(url, authorizer, {
|
|
52
52
|
method,
|
|
53
53
|
headers: (0, utils_js_1.defaultMutationRequestHeaders)(),
|
|
54
54
|
body: JSON.stringify(item),
|
|
55
|
-
})
|
|
55
|
+
});
|
|
56
56
|
if (response.ok) {
|
|
57
57
|
return await response.json();
|
|
58
58
|
}
|
|
@@ -62,14 +62,14 @@ async function mutateItemWithAuthorization(method, url, authorization, item) {
|
|
|
62
62
|
throw (0, utils_js_1.toHttpError)(error);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
-
async function postItemWithAuthorization(url,
|
|
65
|
+
async function postItemWithAuthorization(url, authorizer, item) {
|
|
66
66
|
try {
|
|
67
67
|
console.debug('POST item', { url, item });
|
|
68
|
-
const response = await
|
|
68
|
+
const response = await fetchWithAuthorization(url, authorizer, {
|
|
69
69
|
method: 'POST',
|
|
70
70
|
headers: (0, utils_js_1.defaultMutationRequestHeaders)(),
|
|
71
71
|
body: item ? JSON.stringify(item) : undefined,
|
|
72
|
-
})
|
|
72
|
+
});
|
|
73
73
|
if (response.ok) {
|
|
74
74
|
return await response.json();
|
|
75
75
|
}
|
|
@@ -79,13 +79,13 @@ async function postItemWithAuthorization(url, authorization, item) {
|
|
|
79
79
|
throw (0, utils_js_1.toHttpError)(error);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
async function deleteItemWithAuthorization(url,
|
|
82
|
+
async function deleteItemWithAuthorization(url, authorizer) {
|
|
83
83
|
try {
|
|
84
84
|
console.debug('Delete item', { url });
|
|
85
|
-
const response = await
|
|
85
|
+
const response = await fetchWithAuthorization(url, authorizer, {
|
|
86
86
|
method: 'DELETE',
|
|
87
87
|
headers: (0, utils_js_1.defaultRequestHeaders)(),
|
|
88
|
-
})
|
|
88
|
+
});
|
|
89
89
|
if (response.ok) {
|
|
90
90
|
return (await (0, utils_js_1.jsonBody)(response));
|
|
91
91
|
}
|
|
@@ -95,3 +95,19 @@ async function deleteItemWithAuthorization(url, authorization) {
|
|
|
95
95
|
throw (0, utils_js_1.toHttpError)(error);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
+
async function fetchWithAuthorization(url, authorizer, request) {
|
|
99
|
+
const response = await fetch(url, await authorizer(cloneRequestInit(request)));
|
|
100
|
+
if (!isAuthorizationResponse(response)) {
|
|
101
|
+
return response;
|
|
102
|
+
}
|
|
103
|
+
return fetch(url, await authorizer(cloneRequestInit(request), { refresh: true }));
|
|
104
|
+
}
|
|
105
|
+
function isAuthorizationResponse(response) {
|
|
106
|
+
return [401, 403].includes(response.status);
|
|
107
|
+
}
|
|
108
|
+
function cloneRequestInit(request) {
|
|
109
|
+
return {
|
|
110
|
+
...request,
|
|
111
|
+
headers: new Headers(request.headers),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
@@ -97,16 +97,46 @@ global.fetch = mockFetch;
|
|
|
97
97
|
}));
|
|
98
98
|
});
|
|
99
99
|
(0, vitest_1.test)('should handle authorization errors', async () => {
|
|
100
|
-
|
|
100
|
+
const unauthorizedResponse = {
|
|
101
101
|
ok: false,
|
|
102
102
|
status: 401,
|
|
103
103
|
json: () => Promise.resolve({
|
|
104
104
|
error: 'unauthorized',
|
|
105
105
|
error_description: 'Invalid token',
|
|
106
106
|
}),
|
|
107
|
-
}
|
|
107
|
+
};
|
|
108
|
+
mockFetch
|
|
109
|
+
.mockResolvedValueOnce(unauthorizedResponse)
|
|
110
|
+
.mockResolvedValueOnce(unauthorizedResponse);
|
|
108
111
|
await (0, vitest_1.expect)((0, operations_js_1.getItemWithAuthorization)(testUrl, mockAuthorization)).rejects.toThrow(http_js_1.HttpError);
|
|
109
112
|
});
|
|
113
|
+
(0, vitest_1.test)('should retry once with refresh when authorization fails', async () => {
|
|
114
|
+
const mockData = { id: 1, name: 'Refreshed Item' };
|
|
115
|
+
mockFetch
|
|
116
|
+
.mockResolvedValueOnce({
|
|
117
|
+
ok: false,
|
|
118
|
+
status: 401,
|
|
119
|
+
json: () => Promise.resolve({
|
|
120
|
+
error: 'unauthorized',
|
|
121
|
+
error_description: 'Expired token',
|
|
122
|
+
}),
|
|
123
|
+
})
|
|
124
|
+
.mockResolvedValueOnce({
|
|
125
|
+
ok: true,
|
|
126
|
+
json: () => Promise.resolve(mockData),
|
|
127
|
+
});
|
|
128
|
+
const result = await (0, operations_js_1.getItemWithAuthorization)(testUrl, mockAuthorization);
|
|
129
|
+
(0, vitest_1.expect)(result).toEqual(mockData);
|
|
130
|
+
(0, vitest_1.expect)(mockFetch).toHaveBeenCalledTimes(2);
|
|
131
|
+
(0, vitest_1.expect)(mockAuthorization).toHaveBeenNthCalledWith(1, vitest_1.expect.objectContaining({
|
|
132
|
+
method: 'GET',
|
|
133
|
+
headers: vitest_1.expect.any(Headers),
|
|
134
|
+
}));
|
|
135
|
+
(0, vitest_1.expect)(mockAuthorization).toHaveBeenNthCalledWith(2, vitest_1.expect.objectContaining({
|
|
136
|
+
method: 'GET',
|
|
137
|
+
headers: vitest_1.expect.any(Headers),
|
|
138
|
+
}), { refresh: true });
|
|
139
|
+
});
|
|
110
140
|
(0, vitest_1.test)('should log debug information', async () => {
|
|
111
141
|
mockFetch.mockResolvedValueOnce({
|
|
112
142
|
ok: true,
|
|
@@ -41,17 +41,17 @@ class UserResources {
|
|
|
41
41
|
exports.UserResources = UserResources;
|
|
42
42
|
async function listUsers(instance, pagination) {
|
|
43
43
|
const url = (0, utils_js_1.addPaginationToURL)(new URL(UserResources.buildPath(), instance.config.host), pagination);
|
|
44
|
-
return (0, collection_js_1.PaginationCollectionSchema)(schema_js_1.UserSchema).parse(await (0, operations_js_1.listItemsWithAuthorization)(url, instance.
|
|
44
|
+
return (0, collection_js_1.PaginationCollectionSchema)(schema_js_1.UserSchema).parse(await (0, operations_js_1.listItemsWithAuthorization)(url, instance.authorize));
|
|
45
45
|
}
|
|
46
46
|
async function getUser(instance, id) {
|
|
47
|
-
return schema_js_1.UserSchema.parse(await (0, operations_js_1.getItemWithAuthorization)(new URL(UserResources.buildPath(id), instance.config.host), instance.
|
|
47
|
+
return schema_js_1.UserSchema.parse(await (0, operations_js_1.getItemWithAuthorization)(new URL(UserResources.buildPath(id), instance.config.host), instance.authorize));
|
|
48
48
|
}
|
|
49
49
|
async function insertUser(instance, item) {
|
|
50
|
-
return schema_js_1.UserSchema.parse(await (0, operations_js_1.postItemWithAuthorization)(new URL(UserResources.buildPath(), instance.config.host), instance.
|
|
50
|
+
return schema_js_1.UserSchema.parse(await (0, operations_js_1.postItemWithAuthorization)(new URL(UserResources.buildPath(), instance.config.host), instance.authorize, schema_js_1.InsertUserPayloadSchema.parse(item)));
|
|
51
51
|
}
|
|
52
52
|
async function updateUser(instance, id, item) {
|
|
53
|
-
return schema_js_1.UserSchema.parse(await (0, operations_js_1.patchItemWithAuthorization)(new URL(UserResources.buildPath(id), instance.config.host), instance.
|
|
53
|
+
return schema_js_1.UserSchema.parse(await (0, operations_js_1.patchItemWithAuthorization)(new URL(UserResources.buildPath(id), instance.config.host), instance.authorize, schema_js_1.UpdateUserPayloadSchema.parse(item)));
|
|
54
54
|
}
|
|
55
55
|
async function deleteUser(instance, id) {
|
|
56
|
-
return schema_js_1.UserSchema.parse(await (0, operations_js_1.deleteItemWithAuthorization)(new URL(UserResources.buildPath(id), instance.config.host), instance.
|
|
56
|
+
return schema_js_1.UserSchema.parse(await (0, operations_js_1.deleteItemWithAuthorization)(new URL(UserResources.buildPath(id), instance.config.host), instance.authorize));
|
|
57
57
|
}
|
|
@@ -20,5 +20,5 @@ export class ActivityResources {
|
|
|
20
20
|
}
|
|
21
21
|
export async function listActivities(instance, source, pagination) {
|
|
22
22
|
const url = addPaginationToURL(new URL(ActivityResources.buildPath(source), instance.config.host), pagination);
|
|
23
|
-
return PaginationCollectionSchema(ActivitySchema).parse(await getItemWithAuthorization(url, instance.
|
|
23
|
+
return PaginationCollectionSchema(ActivitySchema).parse(await getItemWithAuthorization(url, instance.authorize));
|
|
24
24
|
}
|
|
@@ -11,7 +11,7 @@ describe('Activity Resources', () => {
|
|
|
11
11
|
host: 'https://api.example.com',
|
|
12
12
|
accessToken: 'test-token',
|
|
13
13
|
},
|
|
14
|
-
|
|
14
|
+
authorize: vi.fn((req) => req),
|
|
15
15
|
};
|
|
16
16
|
activityResources = new ActivityResources(mockInstance);
|
|
17
17
|
});
|
|
@@ -144,11 +144,11 @@ describe('Activity Resources', () => {
|
|
|
144
144
|
expect(internalInstance.config.host).toBe('https://api.example.com');
|
|
145
145
|
expect(internalInstance.config.accessToken).toBe('test-token');
|
|
146
146
|
});
|
|
147
|
-
test('should maintain reference to
|
|
147
|
+
test('should maintain reference to authorize function', () => {
|
|
148
148
|
// biome-ignore lint/complexity/useLiteralKeys: <explanation>
|
|
149
149
|
const internalInstance = activityResources['instance'];
|
|
150
|
-
expect(typeof internalInstance.
|
|
151
|
-
expect(internalInstance.
|
|
150
|
+
expect(typeof internalInstance.authorize).toBe('function');
|
|
151
|
+
expect(internalInstance.authorize).toBe(mockInstance.authorize);
|
|
152
152
|
});
|
|
153
153
|
test('should work with different MondoIdentity configurations', () => {
|
|
154
154
|
const customInstance = {
|
|
@@ -156,7 +156,7 @@ describe('Activity Resources', () => {
|
|
|
156
156
|
host: 'https://custom.api.com',
|
|
157
157
|
accessToken: 'custom-token',
|
|
158
158
|
},
|
|
159
|
-
|
|
159
|
+
authorize: vi.fn(),
|
|
160
160
|
};
|
|
161
161
|
const customResources = new ActivityResources(customInstance);
|
|
162
162
|
// biome-ignore lint/complexity/useLiteralKeys: <explanation>
|
|
@@ -18,8 +18,8 @@ export class AuthorizationResources {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
export async function getAuthorization(instance, appId) {
|
|
21
|
-
return AuthorizationSchema.parse(await getItemWithAuthorization(new URL(AuthorizationResources.buildPath(appId), instance.config.host), instance.
|
|
21
|
+
return AuthorizationSchema.parse(await getItemWithAuthorization(new URL(AuthorizationResources.buildPath(appId), instance.config.host), instance.authorize));
|
|
22
22
|
}
|
|
23
23
|
export async function upsertAuthorization(instance, appId, item) {
|
|
24
|
-
return AuthorizationSchema.parse(await putItemWithAuthorization(new URL(AuthorizationResources.buildPath(appId), instance.config.host), instance.
|
|
24
|
+
return AuthorizationSchema.parse(await putItemWithAuthorization(new URL(AuthorizationResources.buildPath(appId), instance.config.host), instance.authorize, UpsertAuthorizationPayloadSchema.parse(item)));
|
|
25
25
|
}
|
|
@@ -21,8 +21,8 @@ export class OAuthResources {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
export async function getOAuth(instance, appId) {
|
|
24
|
-
return OAuthSchema.parse(await getItemWithAuthorization(new URL(OAuthResources.buildPath(appId), instance.config.host), instance.
|
|
24
|
+
return OAuthSchema.parse(await getItemWithAuthorization(new URL(OAuthResources.buildPath(appId), instance.config.host), instance.authorize));
|
|
25
25
|
}
|
|
26
26
|
export async function rotateOAuthSecret(instance, appId, item) {
|
|
27
|
-
return OAuthSchema.parse(await postItemWithAuthorization(new URL(OAuthResources.buildPath(appId), instance.config.host), instance.
|
|
27
|
+
return OAuthSchema.parse(await postItemWithAuthorization(new URL(OAuthResources.buildPath(appId), instance.config.host), instance.authorize, InsertOAuthPayloadSchema.parse(item)));
|
|
28
28
|
}
|
|
@@ -27,14 +27,14 @@ export class OIDCResources {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
export async function getOIDC(instance, appId) {
|
|
30
|
-
return OIDCSchema.parse(await getItemWithAuthorization(new URL(OIDCResources.buildPath(appId), instance.config.host), instance.
|
|
30
|
+
return OIDCSchema.parse(await getItemWithAuthorization(new URL(OIDCResources.buildPath(appId), instance.config.host), instance.authorize));
|
|
31
31
|
}
|
|
32
32
|
export async function insertOIDC(instance, appId, item) {
|
|
33
|
-
return OIDCSchema.parse(await postItemWithAuthorization(new URL(OIDCResources.buildPath(appId), instance.config.host), instance.
|
|
33
|
+
return OIDCSchema.parse(await postItemWithAuthorization(new URL(OIDCResources.buildPath(appId), instance.config.host), instance.authorize, item ? InsertOIDCPayloadSchema.parse(item) : undefined));
|
|
34
34
|
}
|
|
35
35
|
export async function updateOIDC(instance, appId, item) {
|
|
36
|
-
return OIDCSchema.parse(await patchItemWithAuthorization(new URL(OIDCResources.buildPath(appId), instance.config.host), instance.
|
|
36
|
+
return OIDCSchema.parse(await patchItemWithAuthorization(new URL(OIDCResources.buildPath(appId), instance.config.host), instance.authorize, UpdateOIDCPayloadSchema.parse(item)));
|
|
37
37
|
}
|
|
38
38
|
export async function deleteOIDC(instance, appId) {
|
|
39
|
-
return OIDCSchema.parse(await deleteItemWithAuthorization(new URL(OIDCResources.buildPath(appId), instance.config.host), instance.
|
|
39
|
+
return OIDCSchema.parse(await deleteItemWithAuthorization(new URL(OIDCResources.buildPath(appId), instance.config.host), instance.authorize));
|
|
40
40
|
}
|
|
@@ -21,8 +21,8 @@ export class RegistrationResources {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
export async function getRegistration(instance, id) {
|
|
24
|
-
return RegistrationSchema.parse(await getItemWithAuthorization(new URL(RegistrationResources.buildPath(id), instance.config.host), instance.
|
|
24
|
+
return RegistrationSchema.parse(await getItemWithAuthorization(new URL(RegistrationResources.buildPath(id), instance.config.host), instance.authorize));
|
|
25
25
|
}
|
|
26
26
|
export async function upsertRegistration(instance, id, item) {
|
|
27
|
-
return RegistrationSchema.parse(await postItemWithAuthorization(new URL(RegistrationResources.buildPath(id), instance.config.host), instance.
|
|
27
|
+
return RegistrationSchema.parse(await postItemWithAuthorization(new URL(RegistrationResources.buildPath(id), instance.config.host), instance.authorize, UpsertRegistrationPayloadSchema.parse(item)));
|
|
28
28
|
}
|
|
@@ -11,7 +11,7 @@ describe('App Registration Resources', () => {
|
|
|
11
11
|
host: 'https://api.example.com',
|
|
12
12
|
accessToken: 'test-token',
|
|
13
13
|
},
|
|
14
|
-
|
|
14
|
+
authorize: vi.fn((req) => req),
|
|
15
15
|
};
|
|
16
16
|
registrationResources = new RegistrationResources(mockInstance);
|
|
17
17
|
});
|
|
@@ -149,11 +149,11 @@ describe('App Registration Resources', () => {
|
|
|
149
149
|
expect(internalInstance.config.host).toBe('https://api.example.com');
|
|
150
150
|
expect(internalInstance.config.accessToken).toBe('test-token');
|
|
151
151
|
});
|
|
152
|
-
test('should maintain reference to
|
|
152
|
+
test('should maintain reference to authorize function', () => {
|
|
153
153
|
// biome-ignore lint/complexity/useLiteralKeys: <explanation>
|
|
154
154
|
const internalInstance = registrationResources['instance'];
|
|
155
|
-
expect(typeof internalInstance.
|
|
156
|
-
expect(internalInstance.
|
|
155
|
+
expect(typeof internalInstance.authorize).toBe('function');
|
|
156
|
+
expect(internalInstance.authorize).toBe(mockInstance.authorize);
|
|
157
157
|
});
|
|
158
158
|
test('should work with different MondoIdentity configurations', () => {
|
|
159
159
|
const customInstance = {
|
|
@@ -161,7 +161,7 @@ describe('App Registration Resources', () => {
|
|
|
161
161
|
host: 'https://custom-registration.api.com',
|
|
162
162
|
accessToken: 'custom-registration-token',
|
|
163
163
|
},
|
|
164
|
-
|
|
164
|
+
authorize: vi.fn(),
|
|
165
165
|
};
|
|
166
166
|
const customResources = new RegistrationResources(customInstance);
|
|
167
167
|
// biome-ignore lint/complexity/useLiteralKeys: <explanation>
|
|
@@ -32,17 +32,17 @@ export class AppResources {
|
|
|
32
32
|
}
|
|
33
33
|
export async function listApps(instance, pagination) {
|
|
34
34
|
const url = addPaginationToURL(new URL(AppResources.buildPath(), instance.config.host), pagination);
|
|
35
|
-
return PaginationCollectionSchema(AppSchema).parse(await getItemWithAuthorization(url, instance.
|
|
35
|
+
return PaginationCollectionSchema(AppSchema).parse(await getItemWithAuthorization(url, instance.authorize));
|
|
36
36
|
}
|
|
37
37
|
export async function getApp(instance, id) {
|
|
38
|
-
return AppSchema.parse(await getItemWithAuthorization(new URL(AppResources.buildPath(id), instance.config.host), instance.
|
|
38
|
+
return AppSchema.parse(await getItemWithAuthorization(new URL(AppResources.buildPath(id), instance.config.host), instance.authorize));
|
|
39
39
|
}
|
|
40
40
|
export async function insertApp(instance, item) {
|
|
41
|
-
return AppSchema.parse(await postItemWithAuthorization(new URL(AppResources.buildPath(), instance.config.host), instance.
|
|
41
|
+
return AppSchema.parse(await postItemWithAuthorization(new URL(AppResources.buildPath(), instance.config.host), instance.authorize, InsertAppPayloadSchema.parse(item)));
|
|
42
42
|
}
|
|
43
43
|
export async function updateApp(instance, id, item) {
|
|
44
|
-
return AppSchema.parse(await patchItemWithAuthorization(new URL(AppResources.buildPath(id), instance.config.host), instance.
|
|
44
|
+
return AppSchema.parse(await patchItemWithAuthorization(new URL(AppResources.buildPath(id), instance.config.host), instance.authorize, UpdateAppPayloadSchema.parse(item)));
|
|
45
45
|
}
|
|
46
46
|
export async function deleteApp(instance, id) {
|
|
47
|
-
return AppSchema.parse(await deleteItemWithAuthorization(new URL(AppResources.buildPath(id), instance.config.host), instance.
|
|
47
|
+
return AppSchema.parse(await deleteItemWithAuthorization(new URL(AppResources.buildPath(id), instance.config.host), instance.authorize));
|
|
48
48
|
}
|
|
@@ -11,7 +11,7 @@ describe('App Resources', () => {
|
|
|
11
11
|
host: 'https://api.example.com',
|
|
12
12
|
accessToken: 'test-token',
|
|
13
13
|
},
|
|
14
|
-
|
|
14
|
+
authorize: vi.fn((req) => req),
|
|
15
15
|
};
|
|
16
16
|
appResources = new AppResources(mockInstance);
|
|
17
17
|
});
|
|
@@ -141,11 +141,11 @@ describe('App Resources', () => {
|
|
|
141
141
|
expect(internalInstance.config.host).toBe('https://api.example.com');
|
|
142
142
|
expect(internalInstance.config.accessToken).toBe('test-token');
|
|
143
143
|
});
|
|
144
|
-
test('should maintain reference to
|
|
144
|
+
test('should maintain reference to authorize function', () => {
|
|
145
145
|
// biome-ignore lint/complexity/useLiteralKeys: <explanation>
|
|
146
146
|
const internalInstance = appResources['instance'];
|
|
147
|
-
expect(typeof internalInstance.
|
|
148
|
-
expect(internalInstance.
|
|
147
|
+
expect(typeof internalInstance.authorize).toBe('function');
|
|
148
|
+
expect(internalInstance.authorize).toBe(mockInstance.authorize);
|
|
149
149
|
});
|
|
150
150
|
test('should work with different MondoIdentity configurations', () => {
|
|
151
151
|
const customInstance = {
|
|
@@ -153,7 +153,7 @@ describe('App Resources', () => {
|
|
|
153
153
|
host: 'https://custom-apps.api.com',
|
|
154
154
|
accessToken: 'custom-app-token',
|
|
155
155
|
},
|
|
156
|
-
|
|
156
|
+
authorize: vi.fn(),
|
|
157
157
|
};
|
|
158
158
|
const customResources = new AppResources(customInstance);
|
|
159
159
|
// biome-ignore lint/complexity/useLiteralKeys: <explanation>
|