@boxyhq/saml-jackson 0.3.7-beta.693 → 0.3.7-beta.694

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.
@@ -18,24 +18,10 @@ export declare class APIController implements IAPIController {
18
18
  * consumes:
19
19
  * - application/x-www-form-urlencoded
20
20
  * parameters:
21
- * - name: name
22
- * description: Name/identifier for the config
23
- * type: string
24
- * in: formData
25
- * required: true
26
- * example: cal-saml-config
27
- * - name: description
28
- * description: A short description for the config not more than 100 characters
29
- * type: string
30
- * in: formData
31
- * example: SAML login for cal.com app
32
21
  * - name: encodedRawMetadata
33
22
  * description: Base64 encoding of the XML metadata
34
23
  * in: formData
35
- * type: string
36
- * - name: rawMetadata
37
- * description: Raw XML metadata
38
- * in: formData
24
+ * required: true
39
25
  * type: string
40
26
  * - name: defaultRedirectUrl
41
27
  * description: The redirect URL to use in the IdP login flow
@@ -77,86 +63,10 @@ export declare class APIController implements IAPIController {
77
63
  * client_id: 8958e13053832b5af58fdf2ee83f35f5d013dc74
78
64
  * client_secret: 13f01f4df5b01770c616e682d14d3ba23f20948cfa89b1d7
79
65
  * type: accounts.google.com
80
- * 400:
81
- * description: Please provide rawMetadata or encodedRawMetadata | Please provide a defaultRedirectUrl | Please provide redirectUrl | Please provide tenant | Please provide product | Please provide a friendly name | Description should not exceed 100 characters
82
66
  * 401:
83
67
  * description: Unauthorized
84
68
  */
85
69
  config(body: IdPConfig): Promise<OAuth>;
86
- /**
87
- * @swagger
88
- *
89
- * /api/v1/saml/config:
90
- * patch:
91
- * summary: Update SAML configuration
92
- * operationId: update-saml-config
93
- * tags: [SAML Config]
94
- * consumes:
95
- * - application/json
96
- * - application/x-www-form-urlencoded
97
- * parameters:
98
- * - name: clientID
99
- * description: Client ID for the config
100
- * type: string
101
- * in: formData
102
- * required: true
103
- * - name: clientSecret
104
- * description: Client Secret for the config
105
- * type: string
106
- * in: formData
107
- * required: true
108
- * - name: name
109
- * description: Name/identifier for the config
110
- * type: string
111
- * in: formData
112
- * required: true
113
- * example: cal-saml-config
114
- * - name: description
115
- * description: A short description for the config not more than 100 characters
116
- * type: string
117
- * in: formData
118
- * example: SAML login for cal.com app
119
- * - name: encodedRawMetadata
120
- * description: Base64 encoding of the XML metadata
121
- * in: formData
122
- * type: string
123
- * - name: rawMetadata
124
- * description: Raw XML metadata
125
- * in: formData
126
- * type: string
127
- * - name: defaultRedirectUrl
128
- * description: The redirect URL to use in the IdP login flow
129
- * in: formData
130
- * required: true
131
- * type: string
132
- * example: http://localhost:3000/login/saml
133
- * - name: redirectUrl
134
- * description: JSON encoded array containing a list of allowed redirect URLs
135
- * in: formData
136
- * required: true
137
- * type: string
138
- * example: '["http://localhost:3000/*"]'
139
- * - name: tenant
140
- * description: Tenant
141
- * in: formData
142
- * required: true
143
- * type: string
144
- * example: boxyhq.com
145
- * - name: product
146
- * description: Product
147
- * in: formData
148
- * required: true
149
- * type: string
150
- * example: demo
151
- * responses:
152
- * 204:
153
- * description: Success
154
- * 400:
155
- * description: Please provide clientID | Please provide clientSecret | clientSecret mismatch | Tenant/Product config mismatch with IdP metadata | Description should not exceed 100 characters
156
- * 401:
157
- * description: Unauthorized
158
- */
159
- updateConfig(body: any): Promise<void>;
160
70
  /**
161
71
  * @swagger
162
72
  *
@@ -186,35 +96,11 @@ export declare class APIController implements IAPIController {
186
96
  * description: Success
187
97
  * schema:
188
98
  * type: object
99
+ * properties:
100
+ * provider:
101
+ * type: string
189
102
  * example:
190
- * {
191
- * "config": {
192
- * "idpMetadata": {
193
- * "sso": {
194
- * "postUrl": "https://dev-20901260.okta.com/app/dev-20901260_jacksonnext_1/xxxxxxxxxxxxx/sso/saml",
195
- * "redirectUrl": "https://dev-20901260.okta.com/app/dev-20901260_jacksonnext_1/xxxxxxxxxxxxx/sso/saml"
196
- * },
197
- * "entityID": "http://www.okta.com/xxxxxxxxxxxxx",
198
- * "thumbprint": "Eo+eUi3UM3XIMkFFtdVK3yJ5vO9f7YZdasdasdad",
199
- * "loginType": "idp",
200
- * "provider": "okta.com"
201
- * },
202
- * "defaultRedirectUrl": "https://hoppscotch.io/",
203
- * "redirectUrl": ["https://hoppscotch.io/"],
204
- * "tenant": "hoppscotch.io",
205
- * "product": "API Engine",
206
- * "name": "Hoppscotch-SP",
207
- * "description": "SP for hoppscotch.io",
208
- * "clientID": "Xq8AJt3yYAxmXizsCWmUBDRiVP1iTC8Y/otnvFIMitk",
209
- * "clientSecret": "00e3e11a3426f97d8000000738300009130cd45419c5943",
210
- * "certs": {
211
- * "publicKey": "-----BEGIN CERTIFICATE-----.......-----END CERTIFICATE-----",
212
- * "privateKey": "-----BEGIN PRIVATE KEY-----......-----END PRIVATE KEY-----"
213
- * }
214
- * }
215
- * }
216
- * '400':
217
- * description: Please provide `clientID` or `tenant` and `product`.
103
+ * type: accounts.google.com
218
104
  * '401':
219
105
  * description: Unauthorized
220
106
  */
@@ -222,7 +108,7 @@ export declare class APIController implements IAPIController {
222
108
  clientID: string;
223
109
  tenant: string;
224
110
  product: string;
225
- }): Promise<any>;
111
+ }): Promise<Partial<OAuth>>;
226
112
  /**
227
113
  * @swagger
228
114
  * /api/v1/saml/config:
@@ -257,8 +143,6 @@ export declare class APIController implements IAPIController {
257
143
  * responses:
258
144
  * '200':
259
145
  * description: Success
260
- * '400':
261
- * description: clientSecret mismatch | Please provide `clientID` and `clientSecret` or `tenant` and `product`.'
262
146
  * '401':
263
147
  * description: Unauthorized
264
148
  */
@@ -27,17 +27,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
27
27
  step((generator = generator.apply(thisArg, _arguments || [])).next());
28
28
  });
29
29
  };
30
- var __rest = (this && this.__rest) || function (s, e) {
31
- var t = {};
32
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
33
- t[p] = s[p];
34
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
35
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
36
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
37
- t[p[i]] = s[p[i]];
38
- }
39
- return t;
40
- };
41
30
  var __importDefault = (this && this.__importDefault) || function (mod) {
42
31
  return (mod && mod.__esModule) ? mod : { "default": mod };
43
32
  };
@@ -45,6 +34,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
45
34
  exports.APIController = void 0;
46
35
  const crypto_1 = __importDefault(require("crypto"));
47
36
  const dbutils = __importStar(require("../db/utils"));
37
+ const metrics = __importStar(require("../opentelemetry/metrics"));
48
38
  const saml_1 = __importDefault(require("../saml/saml"));
49
39
  const x509_1 = __importDefault(require("../saml/x509"));
50
40
  const error_1 = require("./error");
@@ -54,7 +44,7 @@ class APIController {
54
44
  this.configStore = configStore;
55
45
  }
56
46
  _validateIdPConfig(body) {
57
- const { encodedRawMetadata, rawMetadata, defaultRedirectUrl, redirectUrl, tenant, product, name, description, } = body;
47
+ const { encodedRawMetadata, rawMetadata, defaultRedirectUrl, redirectUrl, tenant, product } = body;
58
48
  if (!rawMetadata && !encodedRawMetadata) {
59
49
  throw new error_1.JacksonError('Please provide rawMetadata or encodedRawMetadata', 400);
60
50
  }
@@ -70,12 +60,6 @@ class APIController {
70
60
  if (!product) {
71
61
  throw new error_1.JacksonError('Please provide product', 400);
72
62
  }
73
- if (!name) {
74
- throw new error_1.JacksonError('Please provide a friendly name', 400);
75
- }
76
- if (description && description.length > 100) {
77
- throw new error_1.JacksonError('Description should not exceed 100 characters', 400);
78
- }
79
63
  }
80
64
  /**
81
65
  * @swagger
@@ -90,24 +74,10 @@ class APIController {
90
74
  * consumes:
91
75
  * - application/x-www-form-urlencoded
92
76
  * parameters:
93
- * - name: name
94
- * description: Name/identifier for the config
95
- * type: string
96
- * in: formData
97
- * required: true
98
- * example: cal-saml-config
99
- * - name: description
100
- * description: A short description for the config not more than 100 characters
101
- * type: string
102
- * in: formData
103
- * example: SAML login for cal.com app
104
77
  * - name: encodedRawMetadata
105
78
  * description: Base64 encoding of the XML metadata
106
79
  * in: formData
107
- * type: string
108
- * - name: rawMetadata
109
- * description: Raw XML metadata
110
- * in: formData
80
+ * required: true
111
81
  * type: string
112
82
  * - name: defaultRedirectUrl
113
83
  * description: The redirect URL to use in the IdP login flow
@@ -149,14 +119,13 @@ class APIController {
149
119
  * client_id: 8958e13053832b5af58fdf2ee83f35f5d013dc74
150
120
  * client_secret: 13f01f4df5b01770c616e682d14d3ba23f20948cfa89b1d7
151
121
  * type: accounts.google.com
152
- * 400:
153
- * description: Please provide rawMetadata or encodedRawMetadata | Please provide a defaultRedirectUrl | Please provide redirectUrl | Please provide tenant | Please provide product | Please provide a friendly name | Description should not exceed 100 characters
154
122
  * 401:
155
123
  * description: Unauthorized
156
124
  */
157
125
  config(body) {
158
126
  return __awaiter(this, void 0, void 0, function* () {
159
- const { encodedRawMetadata, rawMetadata, defaultRedirectUrl, redirectUrl, tenant, product, name, description, } = body;
127
+ const { encodedRawMetadata, rawMetadata, defaultRedirectUrl, redirectUrl, tenant, product } = body;
128
+ metrics.increment('createConfig');
160
129
  this._validateIdPConfig(body);
161
130
  let metaData = rawMetadata;
162
131
  if (encodedRawMetadata) {
@@ -188,8 +157,6 @@ class APIController {
188
157
  redirectUrl: JSON.parse(redirectUrl),
189
158
  tenant,
190
159
  product,
191
- name,
192
- description,
193
160
  clientID,
194
161
  clientSecret,
195
162
  certs,
@@ -209,130 +176,6 @@ class APIController {
209
176
  };
210
177
  });
211
178
  }
212
- /**
213
- * @swagger
214
- *
215
- * /api/v1/saml/config:
216
- * patch:
217
- * summary: Update SAML configuration
218
- * operationId: update-saml-config
219
- * tags: [SAML Config]
220
- * consumes:
221
- * - application/json
222
- * - application/x-www-form-urlencoded
223
- * parameters:
224
- * - name: clientID
225
- * description: Client ID for the config
226
- * type: string
227
- * in: formData
228
- * required: true
229
- * - name: clientSecret
230
- * description: Client Secret for the config
231
- * type: string
232
- * in: formData
233
- * required: true
234
- * - name: name
235
- * description: Name/identifier for the config
236
- * type: string
237
- * in: formData
238
- * required: true
239
- * example: cal-saml-config
240
- * - name: description
241
- * description: A short description for the config not more than 100 characters
242
- * type: string
243
- * in: formData
244
- * example: SAML login for cal.com app
245
- * - name: encodedRawMetadata
246
- * description: Base64 encoding of the XML metadata
247
- * in: formData
248
- * type: string
249
- * - name: rawMetadata
250
- * description: Raw XML metadata
251
- * in: formData
252
- * type: string
253
- * - name: defaultRedirectUrl
254
- * description: The redirect URL to use in the IdP login flow
255
- * in: formData
256
- * required: true
257
- * type: string
258
- * example: http://localhost:3000/login/saml
259
- * - name: redirectUrl
260
- * description: JSON encoded array containing a list of allowed redirect URLs
261
- * in: formData
262
- * required: true
263
- * type: string
264
- * example: '["http://localhost:3000/*"]'
265
- * - name: tenant
266
- * description: Tenant
267
- * in: formData
268
- * required: true
269
- * type: string
270
- * example: boxyhq.com
271
- * - name: product
272
- * description: Product
273
- * in: formData
274
- * required: true
275
- * type: string
276
- * example: demo
277
- * responses:
278
- * 204:
279
- * description: Success
280
- * 400:
281
- * description: Please provide clientID | Please provide clientSecret | clientSecret mismatch | Tenant/Product config mismatch with IdP metadata | Description should not exceed 100 characters
282
- * 401:
283
- * description: Unauthorized
284
- */
285
- updateConfig(body) {
286
- var _a;
287
- return __awaiter(this, void 0, void 0, function* () {
288
- const { encodedRawMetadata, // could be empty
289
- rawMetadata, // could be empty
290
- defaultRedirectUrl, redirectUrl, name, description } = body, clientInfo = __rest(body, ["encodedRawMetadata", "rawMetadata", "defaultRedirectUrl", "redirectUrl", "name", "description"]);
291
- if (!(clientInfo === null || clientInfo === void 0 ? void 0 : clientInfo.clientID)) {
292
- throw new error_1.JacksonError('Please provide clientID', 400);
293
- }
294
- if (!(clientInfo === null || clientInfo === void 0 ? void 0 : clientInfo.clientSecret)) {
295
- throw new error_1.JacksonError('Please provide clientSecret', 400);
296
- }
297
- if (description && description.length > 100) {
298
- throw new error_1.JacksonError('Description should not exceed 100 characters', 400);
299
- }
300
- const _currentConfig = (_a = (yield this.getConfig(clientInfo))) === null || _a === void 0 ? void 0 : _a.config;
301
- if (_currentConfig.clientSecret !== (clientInfo === null || clientInfo === void 0 ? void 0 : clientInfo.clientSecret)) {
302
- throw new error_1.JacksonError('clientSecret mismatch', 400);
303
- }
304
- let metaData = rawMetadata;
305
- if (encodedRawMetadata) {
306
- metaData = Buffer.from(encodedRawMetadata, 'base64').toString();
307
- }
308
- let newMetadata;
309
- if (metaData) {
310
- newMetadata = yield saml_1.default.parseMetadataAsync(metaData);
311
- // extract provider
312
- let providerName = extractHostName(newMetadata.entityID);
313
- if (!providerName) {
314
- providerName = extractHostName(newMetadata.sso.redirectUrl || newMetadata.sso.postUrl);
315
- }
316
- newMetadata.provider = providerName ? providerName : 'Unknown';
317
- }
318
- if (newMetadata) {
319
- // check if clientID matches with new metadata payload
320
- const clientID = dbutils.keyDigest(dbutils.keyFromParts(clientInfo.tenant, clientInfo.product, newMetadata.entityID));
321
- if (clientID !== (clientInfo === null || clientInfo === void 0 ? void 0 : clientInfo.clientID)) {
322
- throw new error_1.JacksonError('Tenant/Product config mismatch with IdP metadata', 400);
323
- }
324
- }
325
- yield this.configStore.put(clientInfo === null || clientInfo === void 0 ? void 0 : clientInfo.clientID, Object.assign(Object.assign({}, _currentConfig), { name: name ? name : _currentConfig.name, description: description ? description : _currentConfig.description, idpMetadata: newMetadata ? newMetadata : _currentConfig.idpMetadata, defaultRedirectUrl: defaultRedirectUrl ? defaultRedirectUrl : _currentConfig.defaultRedirectUrl, redirectUrl: redirectUrl ? JSON.parse(redirectUrl) : _currentConfig.redirectUrl }), {
326
- // secondary index on entityID
327
- name: utils_1.IndexNames.EntityID,
328
- value: _currentConfig.idpMetadata.entityID,
329
- }, {
330
- // secondary index on tenant + product
331
- name: utils_1.IndexNames.TenantProduct,
332
- value: dbutils.keyFromParts(_currentConfig.tenant, _currentConfig.product),
333
- });
334
- });
335
- }
336
179
  /**
337
180
  * @swagger
338
181
  *
@@ -362,44 +205,21 @@ class APIController {
362
205
  * description: Success
363
206
  * schema:
364
207
  * type: object
208
+ * properties:
209
+ * provider:
210
+ * type: string
365
211
  * example:
366
- * {
367
- * "config": {
368
- * "idpMetadata": {
369
- * "sso": {
370
- * "postUrl": "https://dev-20901260.okta.com/app/dev-20901260_jacksonnext_1/xxxxxxxxxxxxx/sso/saml",
371
- * "redirectUrl": "https://dev-20901260.okta.com/app/dev-20901260_jacksonnext_1/xxxxxxxxxxxxx/sso/saml"
372
- * },
373
- * "entityID": "http://www.okta.com/xxxxxxxxxxxxx",
374
- * "thumbprint": "Eo+eUi3UM3XIMkFFtdVK3yJ5vO9f7YZdasdasdad",
375
- * "loginType": "idp",
376
- * "provider": "okta.com"
377
- * },
378
- * "defaultRedirectUrl": "https://hoppscotch.io/",
379
- * "redirectUrl": ["https://hoppscotch.io/"],
380
- * "tenant": "hoppscotch.io",
381
- * "product": "API Engine",
382
- * "name": "Hoppscotch-SP",
383
- * "description": "SP for hoppscotch.io",
384
- * "clientID": "Xq8AJt3yYAxmXizsCWmUBDRiVP1iTC8Y/otnvFIMitk",
385
- * "clientSecret": "00e3e11a3426f97d8000000738300009130cd45419c5943",
386
- * "certs": {
387
- * "publicKey": "-----BEGIN CERTIFICATE-----.......-----END CERTIFICATE-----",
388
- * "privateKey": "-----BEGIN PRIVATE KEY-----......-----END PRIVATE KEY-----"
389
- * }
390
- * }
391
- * }
392
- * '400':
393
- * description: Please provide `clientID` or `tenant` and `product`.
212
+ * type: accounts.google.com
394
213
  * '401':
395
214
  * description: Unauthorized
396
215
  */
397
216
  getConfig(body) {
398
217
  return __awaiter(this, void 0, void 0, function* () {
399
218
  const { clientID, tenant, product } = body;
219
+ metrics.increment('getConfig');
400
220
  if (clientID) {
401
221
  const samlConfig = yield this.configStore.get(clientID);
402
- return samlConfig ? { config: samlConfig } : {};
222
+ return samlConfig ? { provider: samlConfig.idpMetadata.provider } : {};
403
223
  }
404
224
  if (tenant && product) {
405
225
  const samlConfigs = yield this.configStore.getByIndex({
@@ -409,7 +229,7 @@ class APIController {
409
229
  if (!samlConfigs || !samlConfigs.length) {
410
230
  return {};
411
231
  }
412
- return { config: samlConfigs[0] };
232
+ return { provider: samlConfigs[0].idpMetadata.provider };
413
233
  }
414
234
  throw new error_1.JacksonError('Please provide `clientID` or `tenant` and `product`.', 400);
415
235
  });
@@ -448,14 +268,13 @@ class APIController {
448
268
  * responses:
449
269
  * '200':
450
270
  * description: Success
451
- * '400':
452
- * description: clientSecret mismatch | Please provide `clientID` and `clientSecret` or `tenant` and `product`.'
453
271
  * '401':
454
272
  * description: Unauthorized
455
273
  */
456
274
  deleteConfig(body) {
457
275
  return __awaiter(this, void 0, void 0, function* () {
458
276
  const { clientID, clientSecret, tenant, product } = body;
277
+ metrics.increment('deleteConfig');
459
278
  if (clientID && clientSecret) {
460
279
  const samlConfig = yield this.configStore.get(clientID);
461
280
  if (!samlConfig) {
@@ -465,7 +284,7 @@ class APIController {
465
284
  yield this.configStore.delete(clientID);
466
285
  }
467
286
  else {
468
- throw new error_1.JacksonError('clientSecret mismatch', 400);
287
+ throw new error_1.JacksonError('clientSecret mismatch.', 400);
469
288
  }
470
289
  return;
471
290
  }
@@ -33,15 +33,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
34
  exports.OAuthController = void 0;
35
35
  const crypto_1 = __importDefault(require("crypto"));
36
+ const util_1 = require("util");
37
+ const zlib_1 = require("zlib");
36
38
  const dbutils = __importStar(require("../db/utils"));
39
+ const metrics = __importStar(require("../opentelemetry/metrics"));
37
40
  const saml_1 = __importDefault(require("../saml/saml"));
38
41
  const error_1 = require("./error");
39
42
  const allowed = __importStar(require("./oauth/allowed"));
40
43
  const codeVerifier = __importStar(require("./oauth/code-verifier"));
41
44
  const redirect = __importStar(require("./oauth/redirect"));
42
45
  const utils_1 = require("./utils");
43
- const util_1 = require("util");
44
- const zlib_1 = require("zlib");
45
46
  const deflateRawAsync = (0, util_1.promisify)(zlib_1.deflateRaw);
46
47
  const relayStatePrefix = 'boxyhq_jackson_';
47
48
  function getEncodedClientId(client_id) {
@@ -74,6 +75,7 @@ class OAuthController {
74
75
  const { response_type = 'code', client_id, redirect_uri, state, tenant, product, code_challenge, code_challenge_method = '',
75
76
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
76
77
  provider = 'saml', } = body;
78
+ metrics.increment('oauthAuthorize');
77
79
  if (!redirect_uri) {
78
80
  throw new error_1.JacksonError('Please specify a redirect URL.', 400);
79
81
  }
@@ -262,6 +264,7 @@ class OAuthController {
262
264
  token(body) {
263
265
  return __awaiter(this, void 0, void 0, function* () {
264
266
  const { client_id, client_secret, code_verifier, code, grant_type = 'authorization_code' } = body;
267
+ metrics.increment('oauthToken');
265
268
  if (grant_type !== 'authorization_code') {
266
269
  throw new error_1.JacksonError('Unsupported grant_type', 400);
267
270
  }
@@ -345,6 +348,7 @@ class OAuthController {
345
348
  userInfo(token) {
346
349
  return __awaiter(this, void 0, void 0, function* () {
347
350
  const rsp = yield this.tokenStore.get(token);
351
+ metrics.increment('oauthUserInfo');
348
352
  if (!rsp || !rsp.claims) {
349
353
  throw new error_1.JacksonError('Invalid token', 403);
350
354
  }
package/dist/db/db.d.ts CHANGED
@@ -4,7 +4,6 @@ declare class DB implements DatabaseDriver {
4
4
  private encryptionKey;
5
5
  constructor(db: DatabaseDriver, encryptionKey: EncryptionKey);
6
6
  get(namespace: string, key: string): Promise<unknown>;
7
- getAll(namespace: any): Promise<unknown[]>;
8
7
  getByIndex(namespace: string, idx: Index): Promise<unknown[]>;
9
8
  put(namespace: string, key: string, val: unknown, ttl?: number, ...indexes: Index[]): Promise<unknown>;
10
9
  delete(namespace: string, key: string): Promise<unknown>;
package/dist/db/db.js CHANGED
@@ -57,15 +57,6 @@ class DB {
57
57
  return decrypt(res, this.encryptionKey);
58
58
  });
59
59
  }
60
- getAll(namespace) {
61
- return __awaiter(this, void 0, void 0, function* () {
62
- const res = (yield this.db.getAll(namespace));
63
- const encryptionKey = this.encryptionKey;
64
- return res.map((r) => {
65
- return decrypt(r, encryptionKey);
66
- });
67
- });
68
- }
69
60
  getByIndex(namespace, idx) {
70
61
  return __awaiter(this, void 0, void 0, function* () {
71
62
  const res = yield this.db.getByIndex(namespace, idx);
package/dist/db/mem.d.ts CHANGED
@@ -10,7 +10,6 @@ declare class Mem implements DatabaseDriver {
10
10
  constructor(options: DatabaseOption);
11
11
  init(): Promise<Mem>;
12
12
  get(namespace: string, key: string): Promise<any>;
13
- getAll(namespace: string): Promise<unknown[]>;
14
13
  getByIndex(namespace: string, idx: Index): Promise<any>;
15
14
  put(namespace: string, key: string, val: Encrypted, ttl?: number, ...indexes: any[]): Promise<any>;
16
15
  delete(namespace: string, key: string): Promise<any>;
package/dist/db/mem.js CHANGED
@@ -66,21 +66,6 @@ class Mem {
66
66
  return null;
67
67
  });
68
68
  }
69
- getAll(namespace) {
70
- return __awaiter(this, void 0, void 0, function* () {
71
- const returnValue = [];
72
- if (namespace) {
73
- for (const key in this.store) {
74
- if (key.startsWith(namespace)) {
75
- returnValue.push(this.store[key]);
76
- }
77
- }
78
- }
79
- if (returnValue)
80
- return returnValue;
81
- return [];
82
- });
83
- }
84
69
  getByIndex(namespace, idx) {
85
70
  return __awaiter(this, void 0, void 0, function* () {
86
71
  const dbKeys = yield this.indexes[dbutils.keyForIndex(namespace, idx)];
@@ -95,10 +80,6 @@ class Mem {
95
80
  return __awaiter(this, void 0, void 0, function* () {
96
81
  const k = dbutils.key(namespace, key);
97
82
  this.store[k] = val;
98
- if (!Date.parse(this.store['createdAt']))
99
- this.store['createdAt'] = new Date().toISOString();
100
- this.store['modifiedAt'] = new Date().toISOString();
101
- // console.log(this.store)
102
83
  if (ttl) {
103
84
  this.ttlStore[k] = {
104
85
  namespace,
@@ -7,7 +7,6 @@ declare class Mongo implements DatabaseDriver {
7
7
  constructor(options: DatabaseOption);
8
8
  init(): Promise<Mongo>;
9
9
  get(namespace: string, key: string): Promise<any>;
10
- getAll(namespace: string): Promise<unknown[]>;
11
10
  getByIndex(namespace: string, idx: Index): Promise<any>;
12
11
  put(namespace: string, key: string, val: Encrypted, ttl?: number, ...indexes: any[]): Promise<void>;
13
12
  delete(namespace: string, key: string): Promise<any>;
package/dist/db/mongo.js CHANGED
@@ -36,16 +36,8 @@ class Mongo {
36
36
  }
37
37
  init() {
38
38
  return __awaiter(this, void 0, void 0, function* () {
39
- try {
40
- if (!this.options.url) {
41
- throw Error('Please specify a db url');
42
- }
43
- this.client = new mongodb_1.MongoClient(this.options.url);
44
- yield this.client.connect();
45
- }
46
- catch (err) {
47
- console.error(`error connecting to ${this.options.type} db: ${err}`);
48
- }
39
+ this.client = new mongodb_1.MongoClient(this.options.url);
40
+ yield this.client.connect();
49
41
  this.db = this.client.db();
50
42
  this.collection = this.db.collection('jacksonStore');
51
43
  yield this.collection.createIndex({ indexes: 1 });
@@ -64,15 +56,6 @@ class Mongo {
64
56
  return null;
65
57
  });
66
58
  }
67
- getAll(namespace) {
68
- return __awaiter(this, void 0, void 0, function* () {
69
- const _namespaceMatch = new RegExp(`^${namespace}:.*`);
70
- const docs = yield this.collection.find({ _id: _namespaceMatch }).toArray();
71
- if (docs)
72
- return docs.map(({ value }) => value);
73
- return [];
74
- });
75
- }
76
59
  getByIndex(namespace, idx) {
77
60
  return __awaiter(this, void 0, void 0, function* () {
78
61
  const docs = yield this.collection
@@ -103,12 +86,8 @@ class Mongo {
103
86
  }
104
87
  doc.indexes.push(idxKey);
105
88
  }
106
- doc.modifiedAt = new Date().toISOString();
107
89
  yield this.collection.updateOne({ _id: dbutils.key(namespace, key) }, {
108
90
  $set: doc,
109
- $setOnInsert: {
110
- createdAt: new Date().toISOString(),
111
- },
112
91
  }, { upsert: true });
113
92
  });
114
93
  }
@@ -5,7 +5,6 @@ declare class Redis implements DatabaseDriver {
5
5
  constructor(options: DatabaseOption);
6
6
  init(): Promise<Redis>;
7
7
  get(namespace: string, key: string): Promise<any>;
8
- getAll(namespace: string): Promise<unknown[]>;
9
8
  getByIndex(namespace: string, idx: Index): Promise<any>;
10
9
  put(namespace: string, key: string, val: Encrypted, ttl?: number, ...indexes: any[]): Promise<void>;
11
10
  delete(namespace: string, key: string): Promise<any>;
package/dist/db/redis.js CHANGED
@@ -57,26 +57,6 @@ class Redis {
57
57
  return null;
58
58
  });
59
59
  }
60
- getAll(namespace) {
61
- return __awaiter(this, void 0, void 0, function* () {
62
- const keys = yield this.client.sendCommand(['keys', namespace + ':*']);
63
- const returnValue = [];
64
- for (let i = 0; i < keys.length; i++) {
65
- try {
66
- if (this.client.get(keys[i])) {
67
- const value = yield this.client.get(keys[i]);
68
- returnValue.push(JSON.parse(value));
69
- }
70
- }
71
- catch (error) {
72
- console.error(error);
73
- }
74
- }
75
- if (returnValue)
76
- return returnValue;
77
- return [];
78
- });
79
- }
80
60
  getByIndex(namespace, idx) {
81
61
  return __awaiter(this, void 0, void 0, function* () {
82
62
  const dbKeys = yield this.client.sMembers(dbutils.keyForIndex(namespace, idx));
@@ -3,6 +3,4 @@ export declare class JacksonStore {
3
3
  value: string;
4
4
  iv?: string;
5
5
  tag?: string;
6
- createdAt?: Date;
7
- modifiedAt?: string;
8
6
  }
@@ -36,19 +36,6 @@ __decorate([
36
36
  nullable: true,
37
37
  })
38
38
  ], JacksonStore.prototype, "tag", void 0);
39
- __decorate([
40
- (0, typeorm_1.Column)({
41
- type: 'timestamp',
42
- default: () => 'CURRENT_TIMESTAMP',
43
- nullable: false,
44
- })
45
- ], JacksonStore.prototype, "createdAt", void 0);
46
- __decorate([
47
- (0, typeorm_1.Column)({
48
- type: 'timestamp',
49
- nullable: true,
50
- })
51
- ], JacksonStore.prototype, "modifiedAt", void 0);
52
39
  JacksonStore = __decorate([
53
40
  (0, typeorm_1.Entity)()
54
41
  ], JacksonStore);
@@ -10,7 +10,6 @@ declare class Sql implements DatabaseDriver {
10
10
  constructor(options: DatabaseOption);
11
11
  init(): Promise<Sql>;
12
12
  get(namespace: string, key: string): Promise<any>;
13
- getAll(namespace: string): Promise<unknown[]>;
14
13
  getByIndex(namespace: string, idx: Index): Promise<any>;
15
14
  put(namespace: string, key: string, val: Encrypted, ttl?: number, ...indexes: any[]): Promise<void>;
16
15
  delete(namespace: string, key: string): Promise<any>;
@@ -95,7 +95,7 @@ class Sql {
95
95
  }
96
96
  get(namespace, key) {
97
97
  return __awaiter(this, void 0, void 0, function* () {
98
- const res = yield this.storeRepository.findOne({
98
+ let res = yield this.storeRepository.findOne({
99
99
  key: dbutils.key(namespace, key),
100
100
  });
101
101
  if (res && res.value) {
@@ -108,22 +108,6 @@ class Sql {
108
108
  return null;
109
109
  });
110
110
  }
111
- getAll(namespace) {
112
- return __awaiter(this, void 0, void 0, function* () {
113
- const response = yield this.storeRepository.find({
114
- where: { key: (0, typeorm_1.Like)(`%${namespace}%`) },
115
- select: ['value', 'iv', 'tag'],
116
- order: {
117
- ['createdAt']: 'DESC',
118
- // ['createdAt']: 'ASC',
119
- },
120
- });
121
- const returnValue = JSON.parse(JSON.stringify(response));
122
- if (returnValue)
123
- return returnValue;
124
- return [];
125
- });
126
- }
127
111
  getByIndex(namespace, idx) {
128
112
  return __awaiter(this, void 0, void 0, function* () {
129
113
  const res = yield this.indexRepository.find({
@@ -151,7 +135,6 @@ class Sql {
151
135
  store.value = val.value;
152
136
  store.iv = val.iv;
153
137
  store.tag = val.tag;
154
- store.modifiedAt = new Date().toISOString();
155
138
  yield transactionalEntityManager.save(store);
156
139
  if (ttl) {
157
140
  const ttlRec = new JacksonTTL_1.JacksonTTL();
package/dist/db/store.js CHANGED
@@ -40,11 +40,6 @@ class Store {
40
40
  return yield this.db.get(this.namespace, dbutils.keyDigest(key));
41
41
  });
42
42
  }
43
- getAll() {
44
- return __awaiter(this, void 0, void 0, function* () {
45
- return yield this.db.getAll(this.namespace);
46
- });
47
- }
48
43
  getByIndex(idx) {
49
44
  return __awaiter(this, void 0, void 0, function* () {
50
45
  idx.value = dbutils.keyDigest(idx.value);
package/dist/index.d.ts CHANGED
@@ -1,11 +1,9 @@
1
- import { JacksonOption } from './typings';
2
1
  import { APIController } from './controller/api';
3
2
  import { OAuthController } from './controller/oauth';
4
- import { AdminController } from './controller/admin';
3
+ import { JacksonOption } from './typings';
5
4
  export declare const controllers: (opts: JacksonOption) => Promise<{
6
5
  apiController: APIController;
7
6
  oauthController: OAuthController;
8
- adminController: AdminController;
9
7
  }>;
10
8
  export default controllers;
11
9
  export * from './typings';
package/dist/index.js CHANGED
@@ -25,7 +25,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.controllers = void 0;
26
26
  const api_1 = require("./controller/api");
27
27
  const oauth_1 = require("./controller/oauth");
28
- const admin_1 = require("./controller/admin");
29
28
  const db_1 = __importDefault(require("./db/db"));
30
29
  const read_config_1 = __importDefault(require("./read-config"));
31
30
  const defaultOpts = (opts) => {
@@ -56,7 +55,6 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () {
56
55
  const codeStore = db.store('oauth:code', opts.db.ttl);
57
56
  const tokenStore = db.store('oauth:token', opts.db.ttl);
58
57
  const apiController = new api_1.APIController({ configStore });
59
- const adminController = new admin_1.AdminController({ configStore });
60
58
  const oauthController = new oauth_1.OAuthController({
61
59
  configStore,
62
60
  sessionStore,
@@ -77,7 +75,6 @@ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () {
77
75
  return {
78
76
  apiController,
79
77
  oauthController,
80
- adminController,
81
78
  };
82
79
  });
83
80
  exports.controllers = controllers;
@@ -0,0 +1,2 @@
1
+ declare const increment: (action: string) => void;
2
+ export { increment };
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.increment = void 0;
4
+ const api_metrics_1 = require("@opentelemetry/api-metrics");
5
+ const counters = {
6
+ createConfig: {
7
+ name: 'saml.config.create',
8
+ description: 'Number of SAML config create requests',
9
+ },
10
+ getConfig: {
11
+ name: 'saml.config.get',
12
+ description: 'Number of SAML config get requests',
13
+ },
14
+ deleteConfig: {
15
+ name: 'saml.config.delete',
16
+ description: 'Number of SAML config delete requests',
17
+ },
18
+ oauthAuthorize: {
19
+ name: 'saml.oauth.authorize',
20
+ description: 'Number of SAML oauth authorize requests',
21
+ },
22
+ oauthToken: {
23
+ name: 'saml.oauth.token',
24
+ description: 'Number of SAML oauth token requests',
25
+ },
26
+ oauthUserInfo: {
27
+ name: 'saml.oauth.userinfo',
28
+ description: 'Number of SAML oauth user info requests',
29
+ }
30
+ };
31
+ const createCounter = (action) => {
32
+ const meter = api_metrics_1.metrics.getMeterProvider().getMeter('saml-jackson');
33
+ const counter = counters[action];
34
+ return meter.createCounter(counter.name, {
35
+ description: counter.description,
36
+ });
37
+ };
38
+ const increment = (action) => {
39
+ const counter = createCounter(action);
40
+ counter.add(1);
41
+ };
42
+ exports.increment = increment;
package/dist/typings.d.ts CHANGED
@@ -3,8 +3,6 @@ export declare type IdPConfig = {
3
3
  redirectUrl: string;
4
4
  tenant: string;
5
5
  product: string;
6
- name: string;
7
- description: string;
8
6
  rawMetadata?: string;
9
7
  encodedRawMetadata?: string;
10
8
  };
@@ -15,12 +13,11 @@ export interface OAuth {
15
13
  }
16
14
  export interface IAPIController {
17
15
  config(body: IdPConfig): Promise<OAuth>;
18
- updateConfig(body: any): Promise<void>;
19
16
  getConfig(body: {
20
17
  clientID?: string;
21
18
  tenant?: string;
22
19
  product?: string;
23
- }): Promise<any>;
20
+ }): Promise<Partial<OAuth>>;
24
21
  deleteConfig(body: {
25
22
  clientID?: string;
26
23
  clientSecret?: string;
@@ -38,9 +35,6 @@ export interface IOAuthController {
38
35
  token(body: OAuthTokenReq): Promise<OAuthTokenRes>;
39
36
  userInfo(token: string): Promise<Profile>;
40
37
  }
41
- export interface IAdminController {
42
- getAllConfig(): any;
43
- }
44
38
  export interface OAuthReqBody {
45
39
  response_type: 'code';
46
40
  client_id: string;
@@ -79,14 +73,12 @@ export interface Index {
79
73
  value: string;
80
74
  }
81
75
  export interface DatabaseDriver {
82
- getAll(namespace: string): Promise<unknown[]>;
83
76
  get(namespace: string, key: string): Promise<any>;
84
77
  put(namespace: string, key: string, val: any, ttl: number, ...indexes: Index[]): Promise<any>;
85
78
  delete(namespace: string, key: string): Promise<any>;
86
79
  getByIndex(namespace: string, idx: Index): Promise<any>;
87
80
  }
88
81
  export interface Storable {
89
- getAll(): Promise<unknown[]>;
90
82
  get(key: string): Promise<any>;
91
83
  put(key: string, val: any, ...indexes: Index[]): Promise<any>;
92
84
  delete(key: string): Promise<any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boxyhq/saml-jackson",
3
- "version": "0.3.7-beta.693",
3
+ "version": "0.3.7-beta.694",
4
4
  "description": "SAML 2.0 service",
5
5
  "keywords": [
6
6
  "SAML 2.0"
@@ -18,9 +18,9 @@
18
18
  ],
19
19
  "scripts": {
20
20
  "build": "tsc -p tsconfig.build.json",
21
- "db:migration:generate:postgres": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate --config ormconfig.js -n createdAt",
22
- "db:migration:generate:mysql": "cross-env DB_TYPE=mysql DB_URL=mysql://root:mysql@localhost:3307/mysql ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate --config ormconfig.js -n createdAt",
23
- "db:migration:generate:mariadb": "cross-env DB_TYPE=mariadb DB_URL=mariadb://root@localhost:3306/mysql ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate --config ormconfig.js -n createdAt",
21
+ "db:migration:generate:postgres": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate --config ormconfig.js -n Initial",
22
+ "db:migration:generate:mysql": "cross-env DB_TYPE=mysql DB_URL=mysql://root:mysql@localhost:3307/mysql ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate --config ormconfig.js -n Initial",
23
+ "db:migration:generate:mariadb": "cross-env DB_TYPE=mariadb DB_URL=mariadb://root@localhost:3306/mysql ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate --config ormconfig.js -n Initial",
24
24
  "db:migration:run:postgres": "ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run",
25
25
  "db:migration:run:mysql": "cross-env DB_TYPE=mysql DB_URL=mysql://root:mysql@localhost:3307/mysql ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run",
26
26
  "db:migration:run:mariadb": "cross-env DB_TYPE=mariadb DB_URL=mariadb://root@localhost:3306/mysql ts-node --transpile-only ./node_modules/typeorm/cli.js migration:run",
@@ -37,6 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@boxyhq/saml20": "0.2.0",
40
+ "@opentelemetry/api-metrics": "0.27.0",
40
41
  "@peculiar/webcrypto": "1.2.3",
41
42
  "@peculiar/x509": "1.6.1",
42
43
  "cors": "2.8.5",
@@ -1,8 +0,0 @@
1
- import { IAdminController, Storable, OAuth } from '../typings';
2
- export declare class AdminController implements IAdminController {
3
- configStore: Storable;
4
- constructor({ configStore }: {
5
- configStore: any;
6
- });
7
- getAllConfig(): Promise<Partial<OAuth>[]>;
8
- }
@@ -1,27 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.AdminController = void 0;
13
- class AdminController {
14
- constructor({ configStore }) {
15
- this.configStore = configStore;
16
- }
17
- getAllConfig() {
18
- return __awaiter(this, void 0, void 0, function* () {
19
- const configList = (yield this.configStore.getAll());
20
- if (!configList || !configList.length) {
21
- return [];
22
- }
23
- return configList;
24
- });
25
- }
26
- }
27
- exports.AdminController = AdminController;
@@ -1,16 +0,0 @@
1
- import {MigrationInterface, QueryRunner} from "typeorm";
2
-
3
- export class createdAt1644332636666 implements MigrationInterface {
4
- name = 'createdAt1644332636666'
5
-
6
- public async up(queryRunner: QueryRunner): Promise<void> {
7
- await queryRunner.query(`ALTER TABLE \`jackson_store\` ADD \`createdAt\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP()`);
8
- await queryRunner.query(`ALTER TABLE \`jackson_store\` ADD \`modifiedAt\` timestamp NULL`);
9
- }
10
-
11
- public async down(queryRunner: QueryRunner): Promise<void> {
12
- await queryRunner.query(`ALTER TABLE \`jackson_store\` DROP COLUMN \`modifiedAt\``);
13
- await queryRunner.query(`ALTER TABLE \`jackson_store\` DROP COLUMN \`createdAt\``);
14
- }
15
-
16
- }
@@ -1,16 +0,0 @@
1
- import {MigrationInterface, QueryRunner} from "typeorm";
2
-
3
- export class createdAt1644332641078 implements MigrationInterface {
4
- name = 'createdAt1644332641078'
5
-
6
- public async up(queryRunner: QueryRunner): Promise<void> {
7
- await queryRunner.query(`ALTER TABLE \`jackson_store\` ADD \`createdAt\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP`);
8
- await queryRunner.query(`ALTER TABLE \`jackson_store\` ADD \`modifiedAt\` timestamp NULL`);
9
- }
10
-
11
- public async down(queryRunner: QueryRunner): Promise<void> {
12
- await queryRunner.query(`ALTER TABLE \`jackson_store\` DROP COLUMN \`modifiedAt\``);
13
- await queryRunner.query(`ALTER TABLE \`jackson_store\` DROP COLUMN \`createdAt\``);
14
- }
15
-
16
- }
@@ -1,16 +0,0 @@
1
- import {MigrationInterface, QueryRunner} from "typeorm";
2
-
3
- export class createdAt1644332647279 implements MigrationInterface {
4
- name = 'createdAt1644332647279'
5
-
6
- public async up(queryRunner: QueryRunner): Promise<void> {
7
- await queryRunner.query(`ALTER TABLE "jackson_store" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`);
8
- await queryRunner.query(`ALTER TABLE "jackson_store" ADD "modifiedAt" TIMESTAMP`);
9
- }
10
-
11
- public async down(queryRunner: QueryRunner): Promise<void> {
12
- await queryRunner.query(`ALTER TABLE "jackson_store" DROP COLUMN "modifiedAt"`);
13
- await queryRunner.query(`ALTER TABLE "jackson_store" DROP COLUMN "createdAt"`);
14
- }
15
-
16
- }