@boxyhq/saml-jackson 0.2.3-beta.226 → 0.2.3-beta.231

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/.eslintrc.js CHANGED
@@ -1,13 +1,18 @@
1
1
  module.exports = {
2
- "env": {
3
- "es2021": true,
4
- "node": true
5
- },
6
- "extends": "eslint:recommended",
7
- "parserOptions": {
8
- "ecmaVersion": 13,
9
- "sourceType": "module"
10
- },
11
- "rules": {
12
- }
2
+ env: {
3
+ es2021: true,
4
+ node: true,
5
+ },
6
+ parserOptions: {
7
+ ecmaVersion: 13,
8
+ sourceType: 'module',
9
+ },
10
+ root: true,
11
+ parser: '@typescript-eslint/parser',
12
+ plugins: ['@typescript-eslint'],
13
+ extends: [
14
+ 'eslint:recommended',
15
+ 'plugin:@typescript-eslint/recommended',
16
+ 'prettier',
17
+ ],
13
18
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boxyhq/saml-jackson",
3
- "version": "0.2.3-beta.226",
3
+ "version": "0.2.3-beta.231",
4
4
  "license": "Apache 2.0",
5
5
  "description": "SAML 2.0 service",
6
6
  "main": "dist/index.js",
@@ -57,8 +57,11 @@
57
57
  "@types/redis": "4.0.11",
58
58
  "@types/sinon": "10.0.6",
59
59
  "@types/tap": "15.0.5",
60
+ "@typescript-eslint/eslint-plugin": "^5.8.1",
61
+ "@typescript-eslint/parser": "^5.8.1",
60
62
  "cross-env": "7.0.3",
61
- "eslint": "8.5.0",
63
+ "eslint": "^8.5.0",
64
+ "eslint-config-prettier": "^8.3.0",
62
65
  "husky": "7.0.4",
63
66
  "lint-staged": "12.1.4",
64
67
  "nodemon": "2.0.15",
@@ -66,7 +69,7 @@
66
69
  "sinon": "12.0.1",
67
70
  "tap": "15.1.5",
68
71
  "ts-node": "10.4.0",
69
- "typescript": "4.5.4"
72
+ "typescript": "^4.5.4"
70
73
  },
71
74
  "lint-staged": {
72
75
  "*.{js,ts}": "eslint --cache --fix",
@@ -56,13 +56,13 @@ export class SAMLConfig implements ISAMLConfig {
56
56
 
57
57
  idpMetadata.provider = providerName ? providerName : 'Unknown';
58
58
 
59
- let clientID = dbutils.keyDigest(
59
+ const clientID = dbutils.keyDigest(
60
60
  dbutils.keyFromParts(tenant, product, idpMetadata.entityID)
61
61
  );
62
62
 
63
63
  let clientSecret;
64
64
 
65
- let exists = await this.configStore.get(clientID);
65
+ const exists = await this.configStore.get(clientID);
66
66
 
67
67
  if (exists) {
68
68
  clientSecret = exists.clientSecret;
@@ -2,7 +2,7 @@ export class JacksonError extends Error {
2
2
  public name: string;
3
3
  public statusCode: number;
4
4
 
5
- constructor(message: string, statusCode: number = 500) {
5
+ constructor(message: string, statusCode = 500) {
6
6
  super(message);
7
7
 
8
8
  this.name = this.constructor.name;
@@ -66,7 +66,7 @@ export class OAuthController implements IOAuthController {
66
66
  product,
67
67
  code_challenge,
68
68
  code_challenge_method = '',
69
- // eslint-disable-next-line no-unused-vars
69
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
70
70
  provider = 'saml',
71
71
  } = body;
72
72
 
@@ -134,7 +134,6 @@ export class OAuthController implements IOAuthController {
134
134
  }
135
135
 
136
136
  const samlReq = saml.request({
137
- // @ts-ignore
138
137
  entityID: this.opts.samlAudience,
139
138
  callbackUrl: this.opts.externalUrl + this.opts.samlPath,
140
139
  signingKey: samlConfig.certs.privateKey,
@@ -190,8 +189,6 @@ export class OAuthController implements IOAuthController {
190
189
 
191
190
  const samlConfigs = await this.configStore.getByIndex({
192
191
  name: IndexNames.EntityID,
193
-
194
- // @ts-ignore
195
192
  value: parsedResp?.issuer,
196
193
  });
197
194
 
@@ -214,7 +211,7 @@ export class OAuthController implements IOAuthController {
214
211
  }
215
212
  }
216
213
 
217
- let validateOpts: any = {
214
+ const validateOpts: Record<string, string> = {
218
215
  thumbprint: samlConfig.idpMetadata.thumbprint,
219
216
  audience: this.opts.samlAudience,
220
217
  };
@@ -228,7 +225,7 @@ export class OAuthController implements IOAuthController {
228
225
  // store details against a code
229
226
  const code = crypto.randomBytes(20).toString('hex');
230
227
 
231
- let codeVal: any = {
228
+ const codeVal: Record<string, unknown> = {
232
229
  profile,
233
230
  clientID: samlConfig.clientID,
234
231
  clientSecret: samlConfig.clientSecret,
@@ -248,7 +245,7 @@ export class OAuthController implements IOAuthController {
248
245
  throw new JacksonError('Redirect URL is not allowed.', 403);
249
246
  }
250
247
 
251
- let params: any = {
248
+ const params: Record<string, string> = {
252
249
  code,
253
250
  };
254
251
 
package/src/db/db.ts CHANGED
@@ -13,7 +13,7 @@ import redis from './redis';
13
13
  import sql from './sql/sql';
14
14
  import store from './store';
15
15
 
16
- const decrypt = (res: Encrypted, encryptionKey: EncryptionKey): any => {
16
+ const decrypt = (res: Encrypted, encryptionKey: EncryptionKey): unknown => {
17
17
  if (res.iv && res.tag) {
18
18
  return JSON.parse(
19
19
  encrypter.decrypt(res.value, res.iv, res.tag, encryptionKey)
@@ -24,15 +24,15 @@ const decrypt = (res: Encrypted, encryptionKey: EncryptionKey): any => {
24
24
  };
25
25
 
26
26
  class DB implements DatabaseDriver {
27
- private db: any;
27
+ private db: DatabaseDriver;
28
28
  private encryptionKey: EncryptionKey;
29
29
 
30
- constructor(db: any, encryptionKey: EncryptionKey) {
30
+ constructor(db: DatabaseDriver, encryptionKey: EncryptionKey) {
31
31
  this.db = db;
32
32
  this.encryptionKey = encryptionKey;
33
33
  }
34
34
 
35
- async get(namespace: string, key: string): Promise<any> {
35
+ async get(namespace: string, key: string): Promise<unknown> {
36
36
  const res = await this.db.get(namespace, key);
37
37
 
38
38
  if (!res) {
@@ -42,7 +42,7 @@ class DB implements DatabaseDriver {
42
42
  return decrypt(res, this.encryptionKey);
43
43
  }
44
44
 
45
- async getByIndex(namespace: string, idx: Index): Promise<any> {
45
+ async getByIndex(namespace: string, idx: Index): Promise<unknown[]> {
46
46
  const res = await this.db.getByIndex(namespace, idx);
47
47
  const encryptionKey = this.encryptionKey;
48
48
  return res.map((r) => {
@@ -54,10 +54,10 @@ class DB implements DatabaseDriver {
54
54
  async put(
55
55
  namespace: string,
56
56
  key: string,
57
- val: any,
58
- ttl: number = 0,
59
- ...indexes: any[]
60
- ): Promise<any> {
57
+ val: unknown,
58
+ ttl = 0,
59
+ ...indexes: Index[]
60
+ ): Promise<unknown> {
61
61
  if (ttl > 0 && indexes && indexes.length > 0) {
62
62
  throw new Error('secondary indexes not allow on a store with ttl');
63
63
  }
@@ -69,11 +69,11 @@ class DB implements DatabaseDriver {
69
69
  return await this.db.put(namespace, key, dbVal, ttl, ...indexes);
70
70
  }
71
71
 
72
- async delete(namespace: string, key: string): Promise<any> {
72
+ async delete(namespace: string, key: string): Promise<unknown> {
73
73
  return await this.db.delete(namespace, key);
74
74
  }
75
75
 
76
- store(namespace: string, ttl: number = 0): Storable {
76
+ store(namespace: string, ttl = 0): Storable {
77
77
  return store.new(namespace, this, ttl);
78
78
  }
79
79
  }
package/src/db/mem.ts CHANGED
@@ -43,7 +43,7 @@ class Mem implements DatabaseDriver {
43
43
  }
44
44
 
45
45
  async get(namespace: string, key: string): Promise<any> {
46
- let res = this.store[dbutils.key(namespace, key)];
46
+ const res = this.store[dbutils.key(namespace, key)];
47
47
  if (res) {
48
48
  return res;
49
49
  }
@@ -66,7 +66,7 @@ class Mem implements DatabaseDriver {
66
66
  namespace: string,
67
67
  key: string,
68
68
  val: Encrypted,
69
- ttl: number = 0,
69
+ ttl = 0,
70
70
  ...indexes: any[]
71
71
  ): Promise<any> {
72
72
  const k = dbutils.key(namespace, key);
package/src/db/mongo.ts CHANGED
@@ -36,7 +36,7 @@ class Mongo implements DatabaseDriver {
36
36
  }
37
37
 
38
38
  async get(namespace: string, key: string): Promise<any> {
39
- let res = await this.collection.findOne({
39
+ const res = await this.collection.findOne({
40
40
  _id: dbutils.key(namespace, key),
41
41
  });
42
42
  if (res && res.value) {
@@ -65,7 +65,7 @@ class Mongo implements DatabaseDriver {
65
65
  namespace: string,
66
66
  key: string,
67
67
  val: Encrypted,
68
- ttl: number = 0,
68
+ ttl = 0,
69
69
  ...indexes: any[]
70
70
  ): Promise<void> {
71
71
  const doc = <Document>{
package/src/db/redis.ts CHANGED
@@ -11,7 +11,7 @@ class Redis implements DatabaseDriver {
11
11
  }
12
12
 
13
13
  async init(): Promise<Redis> {
14
- let opts = {};
14
+ const opts = {};
15
15
 
16
16
  if (this.options && this.options.url) {
17
17
  opts['socket'] = {
@@ -30,7 +30,7 @@ class Redis implements DatabaseDriver {
30
30
  }
31
31
 
32
32
  async get(namespace: string, key: string): Promise<any> {
33
- let res = await this.client.get(dbutils.key(namespace, key));
33
+ const res = await this.client.get(dbutils.key(namespace, key));
34
34
  if (res) {
35
35
  return JSON.parse(res);
36
36
  }
@@ -55,7 +55,7 @@ class Redis implements DatabaseDriver {
55
55
  namespace: string,
56
56
  key: string,
57
57
  val: Encrypted,
58
- ttl: number = 0,
58
+ ttl = 0,
59
59
  ...indexes: any[]
60
60
  ): Promise<void> {
61
61
  let tx = this.client.multi();
@@ -21,7 +21,6 @@ export default new EntitySchema({
21
21
  },
22
22
  },
23
23
  relations: {
24
- // TODO: Remove the below line to see the error
25
24
  // @ts-ignore
26
25
  store: {
27
26
  target: () => JacksonStore,
package/src/db/sql/sql.ts CHANGED
@@ -5,20 +5,21 @@ require('reflect-metadata');
5
5
  import { DatabaseDriver, DatabaseOption, Index, Encrypted } from 'saml-jackson';
6
6
  import { Connection, createConnection } from 'typeorm';
7
7
  import * as dbutils from '../utils';
8
+ import JacksonIndexEntity from './entity/JacksonIndex';
9
+ import JacksonStoreEntity from './entity/JacksonStore';
10
+ import {
11
+ JacksonTTL,
12
+ JacksonTTL as JacksonTTLEntity,
13
+ } from './entity/JacksonTTL';
8
14
  import { JacksonIndex } from './model/JacksonIndex';
9
15
  import { JacksonStore } from './model/JacksonStore';
10
- import { JacksonTTL } from './entity/JacksonTTL';
11
-
12
- import JacksonStoreEntity from './entity/JacksonStore';
13
- import JacksonIndexEntity from './entity/JacksonIndex';
14
- import { JacksonTTL as JacksonTTLEntity } from './entity/JacksonTTL';
15
16
 
16
17
  class Sql implements DatabaseDriver {
17
18
  private options: DatabaseOption;
18
19
  private connection!: Connection;
19
- private storeRepository; //!: typeorm.Repository<JacksonStore>;
20
- private indexRepository; //!: typeorm.Repository<JacksonIndex>;
21
- private ttlRepository; //!: typeorm.Repository<JacksonTTL>;
20
+ private storeRepository;
21
+ private indexRepository;
22
+ private ttlRepository;
22
23
  private ttlCleanup;
23
24
  private timerId;
24
25
 
package/src/db/store.ts CHANGED
@@ -6,7 +6,7 @@ class Store implements Storable {
6
6
  private db: any;
7
7
  private ttl: number;
8
8
 
9
- constructor(namespace: string, db: any, ttl: number = 0) {
9
+ constructor(namespace: string, db: any, ttl = 0) {
10
10
  this.namespace = namespace;
11
11
  this.db = db;
12
12
  this.ttl = ttl;
@@ -43,7 +43,7 @@ class Store implements Storable {
43
43
  }
44
44
 
45
45
  export default {
46
- new: (namespace: string, db: any, ttl: number = 0): Storable => {
46
+ new: (namespace: string, db: any, ttl = 0): Storable => {
47
47
  return new Store(namespace, db, ttl);
48
48
  },
49
49
  };
package/src/env.ts CHANGED
@@ -9,7 +9,7 @@ const internalHostPort = +(process.env.INTERNAL_HOST_PORT || '6000');
9
9
 
10
10
  const apiKeys = (process.env.JACKSON_API_KEYS || '').split(',');
11
11
 
12
- const samlAudience = process.env.SAML_AUDIENCE;
12
+ const samlAudience = process.env.SAML_AUDIENCE || 'https://saml.boxyhq.com';
13
13
  const preLoadedConfig = process.env.PRE_LOADED_CONFIG;
14
14
 
15
15
  const idpEnabled = process.env.IDP_ENABLED;
package/src/index.ts CHANGED
@@ -32,9 +32,12 @@ const defaultOpts = (opts: JacksonOption): JacksonOption => {
32
32
  return newOpts;
33
33
  };
34
34
 
35
- export default async function controllers(
35
+ const controllers = async (
36
36
  opts: JacksonOption
37
- ): Promise<{ apiController: SAMLConfig; oauthController: OAuthController }> {
37
+ ): Promise<{
38
+ apiController: SAMLConfig;
39
+ oauthController: OAuthController;
40
+ }> => {
38
41
  opts = defaultOpts(opts);
39
42
 
40
43
  const db = await DB.new(opts.db);
@@ -76,4 +79,6 @@ export default async function controllers(
76
79
  apiController,
77
80
  oauthController,
78
81
  };
79
- }
82
+ };
83
+
84
+ export default controllers;
package/src/jackson.ts CHANGED
@@ -1,12 +1,16 @@
1
1
  import cors from 'cors';
2
2
  import express from 'express';
3
+ import { IOAuthController, ISAMLConfig } from 'saml-jackson';
3
4
  import { JacksonError } from './controller/error';
4
5
  import { extractAuthToken } from './controller/utils';
5
6
  import env from './env';
6
- import jackson from './index';
7
7
 
8
- let apiController;
9
- let oauthController;
8
+ //import jackson from './index';
9
+
10
+ const jackson = require('./index');
11
+
12
+ let apiController: ISAMLConfig;
13
+ let oauthController: IOAuthController;
10
14
 
11
15
  const oauthPath = '/oauth';
12
16
  const apiPath = '/api/v1/saml';
@@ -62,7 +66,7 @@ app.get(oauthPath + '/userinfo', async (req, res) => {
62
66
  }
63
67
 
64
68
  if (!token) {
65
- res.status(401).json({ message: 'Unauthorized' });
69
+ return res.status(401).json({ message: 'Unauthorized' });
66
70
  }
67
71
 
68
72
  const profile = await oauthController.userInfo(token);
@@ -80,8 +84,6 @@ const server = app.listen(env.hostPort, async () => {
80
84
  `🚀 The path of the righteous server: http://${env.hostUrl}:${env.hostPort}`
81
85
  );
82
86
 
83
- // TODO: Fix it
84
- // @ts-ignore
85
87
  const ctrlrModule = await jackson(env);
86
88
 
87
89
  apiController = ctrlrModule.apiController;
package/src/saml/saml.ts CHANGED
@@ -1,7 +1,7 @@
1
- const saml = require('@boxyhq/saml20');
2
- const xml2js = require('xml2js');
3
- const thumbprint = require('thumbprint');
4
- const xmlcrypto = require('xml-crypto');
1
+ import saml from '@boxyhq/saml20';
2
+ import xml2js from 'xml2js';
3
+ import thumbprint from 'thumbprint';
4
+ import xmlcrypto from 'xml-crypto';
5
5
  import * as rambda from 'rambda';
6
6
  import xmlbuilder from 'xmlbuilder';
7
7
  import crypto from 'crypto';
@@ -53,7 +53,8 @@ const request = ({
53
53
  const id = idPrefix + crypto.randomBytes(10).toString('hex');
54
54
  const date = new Date().toISOString();
55
55
 
56
- let samlReq: Record<string, any> = {
56
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
+ const samlReq: Record<string, any> = {
57
58
  'samlp:AuthnRequest': {
58
59
  '@xmlns:samlp': 'urn:oasis:names:tc:SAML:2.0:protocol',
59
60
  '@ID': id,
@@ -97,9 +98,7 @@ const request = ({
97
98
  };
98
99
  };
99
100
 
100
- const parseAsync = async (
101
- rawAssertion: string
102
- ): Promise<SAMLProfile | void> => {
101
+ const parseAsync = async (rawAssertion: string): Promise<SAMLProfile> => {
103
102
  return new Promise((resolve, reject) => {
104
103
  saml.parse(
105
104
  rawAssertion,
@@ -118,7 +117,7 @@ const parseAsync = async (
118
117
  const validateAsync = async (
119
118
  rawAssertion: string,
120
119
  options
121
- ): Promise<SAMLProfile | void> => {
120
+ ): Promise<SAMLProfile> => {
122
121
  return new Promise((resolve, reject) => {
123
122
  saml.validate(
124
123
  rawAssertion,
@@ -144,7 +144,7 @@ tap.test('controller/api', async (t) => {
144
144
  t.equal(response.client_id, CLIENT_ID);
145
145
  t.equal(response.provider, PROVIDER);
146
146
 
147
- let savedConf = await apiController.getConfig({
147
+ const savedConf = await apiController.getConfig({
148
148
  clientID: CLIENT_ID,
149
149
  });
150
150
 
@@ -1,30 +1,36 @@
1
1
  import crypto from 'crypto';
2
2
  import { promises as fs } from 'fs';
3
3
  import path from 'path';
4
- import { JacksonOption } from 'saml-jackson';
4
+ import {
5
+ IOAuthController,
6
+ ISAMLConfig,
7
+ JacksonOption,
8
+ OAuthReqBody,
9
+ OAuthTokenReq,
10
+ SAMLResponsePayload,
11
+ } from 'saml-jackson';
5
12
  import sinon from 'sinon';
6
13
  import tap from 'tap';
7
14
  import { JacksonError } from '../controller/error';
8
15
  import readConfig from '../read-config';
9
16
  import saml from '../saml/saml';
10
17
 
11
- // TODO: Add type
12
- let apiController;
13
- let oauthController;
18
+ let apiController: ISAMLConfig;
19
+ let oauthController: IOAuthController;
14
20
 
15
21
  const code = '1234567890';
16
22
  const token = '24c1550190dd6a5a9bd6fe2a8ff69d593121c7b9';
17
23
 
18
24
  const metadataPath = path.join(__dirname, '/data/metadata');
19
25
 
20
- const options = {
26
+ const options = <JacksonOption>{
21
27
  externalUrl: 'https://my-cool-app.com',
22
28
  samlAudience: 'https://saml.boxyhq.com',
23
29
  samlPath: '/sso/oauth/saml',
24
30
  db: {
25
31
  engine: 'mem',
26
32
  },
27
- } as JacksonOption;
33
+ };
28
34
 
29
35
  const samlConfig = {
30
36
  tenant: 'boxyhq.com',
@@ -57,13 +63,13 @@ tap.teardown(async () => {
57
63
 
58
64
  tap.test('authorize()', async (t) => {
59
65
  t.test('Should throw an error if `redirect_uri` null', async (t) => {
60
- const body = {
61
- redirect_uri: null,
66
+ const body: Partial<OAuthReqBody> = {
67
+ redirect_uri: undefined,
62
68
  state: 'state',
63
69
  };
64
70
 
65
71
  try {
66
- await oauthController.authorize(body);
72
+ await oauthController.authorize(<OAuthReqBody>body);
67
73
  t.fail('Expecting JacksonError.');
68
74
  } catch (err) {
69
75
  const { message, statusCode } = err as JacksonError;
@@ -79,13 +85,13 @@ tap.test('authorize()', async (t) => {
79
85
  });
80
86
 
81
87
  t.test('Should throw an error if `state` null', async (t) => {
82
- const body = {
88
+ const body: Partial<OAuthReqBody> = {
83
89
  redirect_uri: 'https://example.com/',
84
- state: null,
90
+ state: undefined,
85
91
  };
86
92
 
87
93
  try {
88
- await oauthController.authorize(body);
94
+ await oauthController.authorize(<OAuthReqBody>body);
89
95
 
90
96
  t.fail('Expecting JacksonError.');
91
97
  } catch (err) {
@@ -109,7 +115,7 @@ tap.test('authorize()', async (t) => {
109
115
  };
110
116
 
111
117
  try {
112
- await oauthController.authorize(body);
118
+ await oauthController.authorize(<OAuthReqBody>body);
113
119
 
114
120
  t.fail('Expecting JacksonError.');
115
121
  } catch (err) {
@@ -135,7 +141,7 @@ tap.test('authorize()', async (t) => {
135
141
  };
136
142
 
137
143
  try {
138
- await oauthController.authorize(body);
144
+ await oauthController.authorize(<OAuthReqBody>body);
139
145
 
140
146
  t.fail('Expecting JacksonError.');
141
147
  } catch (err) {
@@ -159,7 +165,7 @@ tap.test('authorize()', async (t) => {
159
165
  client_id: `tenant=${samlConfig.tenant}&product=${samlConfig.product}`,
160
166
  };
161
167
 
162
- const response = await oauthController.authorize(body);
168
+ const response = await oauthController.authorize(<OAuthReqBody>body);
163
169
  const params = new URLSearchParams(new URL(response.redirect_url).search);
164
170
 
165
171
  t.ok('redirect_url' in response, 'got the Idp authorize URL');
@@ -179,7 +185,9 @@ tap.test('samlResponse()', async (t) => {
179
185
  client_id: `tenant=${samlConfig.tenant}&product=${samlConfig.product}`,
180
186
  };
181
187
 
182
- const { redirect_url } = await oauthController.authorize(authBody);
188
+ const { redirect_url } = await oauthController.authorize(
189
+ <OAuthReqBody>authBody
190
+ );
183
191
 
184
192
  const relayState = new URLSearchParams(new URL(redirect_url).search).get(
185
193
  'RelayState'
@@ -191,12 +199,12 @@ tap.test('samlResponse()', async (t) => {
191
199
  );
192
200
 
193
201
  t.test('Should throw an error if `RelayState` is missing', async (t) => {
194
- const responseBody = {
202
+ const responseBody: Partial<SAMLResponsePayload> = {
195
203
  SAMLResponse: rawResponse,
196
204
  };
197
205
 
198
206
  try {
199
- await oauthController.samlResponse(responseBody);
207
+ await oauthController.samlResponse(<SAMLResponsePayload>responseBody);
200
208
 
201
209
  t.fail('Expecting JacksonError.');
202
210
  } catch (err) {
@@ -224,10 +232,13 @@ tap.test('samlResponse()', async (t) => {
224
232
  const stubValidateAsync = sinon
225
233
  .stub(saml, 'validateAsync')
226
234
  .resolves({ audience: '', claims: {}, issuer: '', sessionIndex: '' });
235
+
227
236
  //@ts-ignore
228
237
  const stubRandomBytes = sinon.stub(crypto, 'randomBytes').returns(code);
229
238
 
230
- const response = await oauthController.samlResponse(responseBody);
239
+ const response = await oauthController.samlResponse(
240
+ <SAMLResponsePayload>responseBody
241
+ );
231
242
 
232
243
  const params = new URLSearchParams(new URL(response.redirect_url).search);
233
244
 
@@ -257,7 +268,7 @@ tap.test('token()', (t) => {
257
268
  };
258
269
 
259
270
  try {
260
- await oauthController.token(body);
271
+ await oauthController.token(<OAuthTokenReq>body);
261
272
 
262
273
  t.fail('Expecting JacksonError.');
263
274
  } catch (err) {
@@ -280,7 +291,7 @@ tap.test('token()', (t) => {
280
291
  };
281
292
 
282
293
  try {
283
- await oauthController.token(body);
294
+ await oauthController.token(<OAuthTokenReq>body);
284
295
 
285
296
  t.fail('Expecting JacksonError.');
286
297
  } catch (err) {
@@ -293,16 +304,15 @@ tap.test('token()', (t) => {
293
304
  });
294
305
 
295
306
  t.test('Should throw an error if `code` is invalid', async (t) => {
296
- const body = {
307
+ const body: Partial<OAuthTokenReq> = {
297
308
  grant_type: 'authorization_code',
298
309
  client_id: `tenant=${samlConfig.tenant}&product=${samlConfig.product}`,
299
310
  client_secret: 'some-secret',
300
- redirect_uri: null,
301
311
  code: 'invalid-code',
302
312
  };
303
313
 
304
314
  try {
305
- await oauthController.token(body);
315
+ await oauthController.token(<OAuthTokenReq>body);
306
316
 
307
317
  t.fail('Expecting JacksonError.');
308
318
  } catch (err) {
@@ -315,11 +325,10 @@ tap.test('token()', (t) => {
315
325
  });
316
326
 
317
327
  t.test('Should return the `access_token` for a valid request', async (t) => {
318
- const body = {
328
+ const body: Partial<OAuthTokenReq> = {
319
329
  grant_type: 'authorization_code',
320
330
  client_id: `tenant=${samlConfig.tenant}&product=${samlConfig.product}`,
321
331
  client_secret: 'some-secret',
322
- redirect_uri: null,
323
332
  code: code,
324
333
  };
325
334
 
@@ -329,7 +338,7 @@ tap.test('token()', (t) => {
329
338
  //@ts-ignore
330
339
  .returns(token);
331
340
 
332
- const response = await oauthController.token(body);
341
+ const response = await oauthController.token(<OAuthTokenReq>body);
333
342
 
334
343
  t.ok(stubRandomBytes.calledOnce, 'randomBytes called once');
335
344
  t.ok('access_token' in response, 'includes access_token');
package/src/typings.ts CHANGED
@@ -51,7 +51,7 @@ declare module 'saml-jackson' {
51
51
  authorize(body: OAuthReqBody): Promise<{ redirect_url: string }>;
52
52
  samlResponse(body: SAMLResponsePayload): Promise<{ redirect_url: string }>;
53
53
  token(body: OAuthTokenReq): Promise<OAuthTokenRes>;
54
- userInfo(body: string): Promise<Profile>;
54
+ userInfo(token: string): Promise<Profile>;
55
55
  }
56
56
 
57
57
  export interface OAuthReqBody {
@@ -104,7 +104,7 @@ declare module 'saml-jackson' {
104
104
  key: string,
105
105
  val: any,
106
106
  ttl: number,
107
- indexes: Index[]
107
+ ...indexes: Index[]
108
108
  ): Promise<any>;
109
109
  delete(namespace: string, key: string): Promise<any>;
110
110
  getByIndex(namespace: string, idx: Index): Promise<any>;
@@ -159,7 +159,7 @@ declare module 'saml-jackson' {
159
159
  export interface JacksonOption {
160
160
  externalUrl: string;
161
161
  samlPath: string;
162
- samlAudience?: string;
162
+ samlAudience: string;
163
163
  preLoadedConfig?: string;
164
164
  idpEnabled?: boolean;
165
165
  db: DatabaseOption;