@boxyhq/saml-jackson 0.2.3-beta.235 → 0.2.3-beta.240

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.
Files changed (53) hide show
  1. package/dist/controller/api.d.ts +32 -0
  2. package/dist/controller/api.js +193 -0
  3. package/dist/controller/error.d.ts +5 -0
  4. package/dist/controller/error.js +12 -0
  5. package/dist/controller/oauth/allowed.d.ts +1 -0
  6. package/dist/controller/oauth/allowed.js +17 -0
  7. package/dist/controller/oauth/code-verifier.d.ts +2 -0
  8. package/dist/controller/oauth/code-verifier.js +15 -0
  9. package/dist/controller/oauth/redirect.d.ts +1 -0
  10. package/dist/controller/oauth/redirect.js +11 -0
  11. package/dist/controller/oauth.d.ts +23 -0
  12. package/dist/controller/oauth.js +263 -0
  13. package/dist/controller/utils.d.ts +6 -0
  14. package/dist/controller/utils.js +17 -0
  15. package/dist/db/db.d.ts +15 -0
  16. package/dist/db/db.js +107 -0
  17. package/dist/db/encrypter.d.ts +3 -0
  18. package/dist/db/encrypter.js +29 -0
  19. package/dist/db/mem.d.ts +20 -0
  20. package/dist/db/mem.js +128 -0
  21. package/dist/db/mongo.d.ts +17 -0
  22. package/dist/db/mongo.js +106 -0
  23. package/dist/db/redis.d.ts +15 -0
  24. package/dist/db/redis.js +107 -0
  25. package/dist/db/sql/entity/JacksonIndex.d.ts +7 -0
  26. package/dist/db/sql/entity/JacksonIndex.js +41 -0
  27. package/dist/db/sql/entity/JacksonStore.d.ts +6 -0
  28. package/dist/db/sql/entity/JacksonStore.js +42 -0
  29. package/dist/db/sql/entity/JacksonTTL.d.ts +4 -0
  30. package/dist/db/sql/entity/JacksonTTL.js +29 -0
  31. package/dist/db/sql/sql.d.ts +20 -0
  32. package/dist/db/sql/sql.js +174 -0
  33. package/dist/db/store.d.ts +5 -0
  34. package/dist/db/store.js +68 -0
  35. package/dist/db/utils.d.ts +7 -0
  36. package/dist/db/utils.js +29 -0
  37. package/dist/env.d.ts +22 -0
  38. package/dist/env.js +35 -0
  39. package/dist/index.d.ts +9 -0
  40. package/dist/index.js +80 -0
  41. package/dist/jackson.d.ts +1 -0
  42. package/dist/jackson.js +153 -0
  43. package/dist/read-config.d.ts +3 -0
  44. package/dist/read-config.js +50 -0
  45. package/dist/saml/claims.d.ts +6 -0
  46. package/dist/saml/claims.js +35 -0
  47. package/dist/saml/saml.d.ts +11 -0
  48. package/dist/saml/saml.js +200 -0
  49. package/dist/saml/x509.d.ts +7 -0
  50. package/dist/saml/x509.js +69 -0
  51. package/dist/typings.d.ts +137 -0
  52. package/dist/typings.js +2 -0
  53. package/package.json +2 -1
@@ -0,0 +1,20 @@
1
+ import { DatabaseDriver, DatabaseOption, Index, Encrypted } from '../../typings';
2
+ declare class Sql implements DatabaseDriver {
3
+ private options;
4
+ private connection;
5
+ private storeRepository;
6
+ private indexRepository;
7
+ private ttlRepository;
8
+ private ttlCleanup;
9
+ private timerId;
10
+ constructor(options: DatabaseOption);
11
+ init(): Promise<Sql>;
12
+ get(namespace: string, key: string): Promise<any>;
13
+ getByIndex(namespace: string, idx: Index): Promise<any>;
14
+ put(namespace: string, key: string, val: Encrypted, ttl?: number, ...indexes: any[]): Promise<void>;
15
+ delete(namespace: string, key: string): Promise<any>;
16
+ }
17
+ declare const _default: {
18
+ new: (options: DatabaseOption) => Promise<Sql>;
19
+ };
20
+ export default _default;
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ /*eslint no-constant-condition: ["error", { "checkLoops": false }]*/
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
6
+ }) : (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ o[k2] = m[k];
9
+ }));
10
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
11
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
12
+ }) : function(o, v) {
13
+ o["default"] = v;
14
+ });
15
+ var __importStar = (this && this.__importStar) || function (mod) {
16
+ if (mod && mod.__esModule) return mod;
17
+ var result = {};
18
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
19
+ __setModuleDefault(result, mod);
20
+ return result;
21
+ };
22
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
23
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
24
+ return new (P || (P = Promise))(function (resolve, reject) {
25
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
26
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
27
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
28
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
29
+ });
30
+ };
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ require('reflect-metadata');
33
+ const typeorm_1 = require("typeorm");
34
+ const dbutils = __importStar(require("../utils"));
35
+ const JacksonStore_1 = require("./entity/JacksonStore");
36
+ const JacksonIndex_1 = require("./entity/JacksonIndex");
37
+ const JacksonTTL_1 = require("./entity/JacksonTTL");
38
+ class Sql {
39
+ constructor(options) {
40
+ this.options = options;
41
+ }
42
+ init() {
43
+ return __awaiter(this, void 0, void 0, function* () {
44
+ while (true) {
45
+ try {
46
+ this.connection = yield (0, typeorm_1.createConnection)({
47
+ name: this.options.type + Math.floor(Math.random() * 100000),
48
+ type: this.options.type,
49
+ url: this.options.url,
50
+ synchronize: true,
51
+ migrationsTableName: '_jackson_migrations',
52
+ logging: ['error'],
53
+ entities: [JacksonStore_1.JacksonStore, JacksonIndex_1.JacksonIndex, JacksonTTL_1.JacksonTTL],
54
+ });
55
+ break;
56
+ }
57
+ catch (err) {
58
+ console.error(`error connecting to ${this.options.type} db: ${err}`);
59
+ yield dbutils.sleep(1000);
60
+ continue;
61
+ }
62
+ }
63
+ this.storeRepository = this.connection.getRepository(JacksonStore_1.JacksonStore);
64
+ this.indexRepository = this.connection.getRepository(JacksonIndex_1.JacksonIndex);
65
+ this.ttlRepository = this.connection.getRepository(JacksonTTL_1.JacksonTTL);
66
+ if (this.options.ttl && this.options.cleanupLimit) {
67
+ this.ttlCleanup = () => __awaiter(this, void 0, void 0, function* () {
68
+ const now = Date.now();
69
+ while (true) {
70
+ const ids = yield this.ttlRepository
71
+ .createQueryBuilder('jackson_ttl')
72
+ .limit(this.options.cleanupLimit)
73
+ .where('jackson_ttl.expiresAt <= :expiresAt', {
74
+ expiresAt: now,
75
+ })
76
+ .getMany();
77
+ if (ids.length <= 0) {
78
+ break;
79
+ }
80
+ const delIds = ids.map((id) => {
81
+ return id.key;
82
+ });
83
+ yield this.storeRepository.remove(ids);
84
+ yield this.ttlRepository.delete(delIds);
85
+ }
86
+ this.timerId = setTimeout(this.ttlCleanup, this.options.ttl * 1000);
87
+ });
88
+ this.timerId = setTimeout(this.ttlCleanup, this.options.ttl * 1000);
89
+ }
90
+ else {
91
+ console.log('Warning: ttl cleanup not enabled, set both "ttl" and "cleanupLimit" options to enable it!');
92
+ }
93
+ return this;
94
+ });
95
+ }
96
+ get(namespace, key) {
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ let res = yield this.storeRepository.findOne({
99
+ key: dbutils.key(namespace, key),
100
+ });
101
+ if (res && res.value) {
102
+ return {
103
+ value: res.value,
104
+ iv: res.iv,
105
+ tag: res.tag,
106
+ };
107
+ }
108
+ return null;
109
+ });
110
+ }
111
+ getByIndex(namespace, idx) {
112
+ return __awaiter(this, void 0, void 0, function* () {
113
+ const res = yield this.indexRepository.find({
114
+ key: dbutils.keyForIndex(namespace, idx),
115
+ });
116
+ const ret = [];
117
+ if (res) {
118
+ res.forEach((r) => {
119
+ ret.push({
120
+ value: r.store.value,
121
+ iv: r.store.iv,
122
+ tag: r.store.tag,
123
+ });
124
+ });
125
+ }
126
+ return ret;
127
+ });
128
+ }
129
+ put(namespace, key, val, ttl = 0, ...indexes) {
130
+ return __awaiter(this, void 0, void 0, function* () {
131
+ yield this.connection.transaction((transactionalEntityManager) => __awaiter(this, void 0, void 0, function* () {
132
+ const dbKey = dbutils.key(namespace, key);
133
+ const store = new JacksonStore_1.JacksonStore();
134
+ store.key = dbKey;
135
+ store.value = val.value;
136
+ store.iv = val.iv;
137
+ store.tag = val.tag;
138
+ yield transactionalEntityManager.save(store);
139
+ if (ttl) {
140
+ const ttlRec = new JacksonTTL_1.JacksonTTL();
141
+ ttlRec.key = dbKey;
142
+ ttlRec.expiresAt = Date.now() + ttl * 1000;
143
+ yield transactionalEntityManager.save(ttlRec);
144
+ }
145
+ // no ttl support for secondary indexes
146
+ for (const idx of indexes || []) {
147
+ const key = dbutils.keyForIndex(namespace, idx);
148
+ const rec = yield this.indexRepository.findOne({
149
+ key,
150
+ storeKey: store.key,
151
+ });
152
+ if (!rec) {
153
+ const ji = new JacksonIndex_1.JacksonIndex();
154
+ ji.key = key;
155
+ ji.store = store;
156
+ yield transactionalEntityManager.save(ji);
157
+ }
158
+ }
159
+ }));
160
+ });
161
+ }
162
+ delete(namespace, key) {
163
+ return __awaiter(this, void 0, void 0, function* () {
164
+ return yield this.storeRepository.remove({
165
+ key: dbutils.key(namespace, key),
166
+ });
167
+ });
168
+ }
169
+ }
170
+ exports.default = {
171
+ new: (options) => __awaiter(void 0, void 0, void 0, function* () {
172
+ return yield new Sql(options).init();
173
+ }),
174
+ };
@@ -0,0 +1,5 @@
1
+ import { Storable } from '../typings';
2
+ declare const _default: {
3
+ new: (namespace: string, db: any, ttl?: number) => Storable;
4
+ };
5
+ export default _default;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ const dbutils = __importStar(require("./utils"));
32
+ class Store {
33
+ constructor(namespace, db, ttl = 0) {
34
+ this.namespace = namespace;
35
+ this.db = db;
36
+ this.ttl = ttl;
37
+ }
38
+ get(key) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ return yield this.db.get(this.namespace, dbutils.keyDigest(key));
41
+ });
42
+ }
43
+ getByIndex(idx) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ idx.value = dbutils.keyDigest(idx.value);
46
+ return yield this.db.getByIndex(this.namespace, idx);
47
+ });
48
+ }
49
+ put(key, val, ...indexes) {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ indexes = (indexes || []).map((idx) => {
52
+ idx.value = dbutils.keyDigest(idx.value);
53
+ return idx;
54
+ });
55
+ return yield this.db.put(this.namespace, dbutils.keyDigest(key), val, this.ttl, ...indexes);
56
+ });
57
+ }
58
+ delete(key) {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ return yield this.db.delete(this.namespace, dbutils.keyDigest(key));
61
+ });
62
+ }
63
+ }
64
+ exports.default = {
65
+ new: (namespace, db, ttl = 0) => {
66
+ return new Store(namespace, db, ttl);
67
+ },
68
+ };
@@ -0,0 +1,7 @@
1
+ import { Index } from '../typings';
2
+ export declare const key: (namespace: string, k: string) => string;
3
+ export declare const keyForIndex: (namespace: string, idx: Index) => string;
4
+ export declare const keyDigest: (k: string) => string;
5
+ export declare const keyFromParts: (...parts: string[]) => string;
6
+ export declare const sleep: (ms: number) => Promise<void>;
7
+ export declare const indexPrefix = "_index";
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.indexPrefix = exports.sleep = exports.keyFromParts = exports.keyDigest = exports.keyForIndex = exports.key = void 0;
7
+ const ripemd160_1 = __importDefault(require("ripemd160"));
8
+ const key = (namespace, k) => {
9
+ return namespace + ':' + k;
10
+ };
11
+ exports.key = key;
12
+ const keyForIndex = (namespace, idx) => {
13
+ return (0, exports.key)((0, exports.key)(namespace, idx.name), idx.value);
14
+ };
15
+ exports.keyForIndex = keyForIndex;
16
+ const keyDigest = (k) => {
17
+ return new ripemd160_1.default().update(k).digest('hex');
18
+ };
19
+ exports.keyDigest = keyDigest;
20
+ const keyFromParts = (...parts) => {
21
+ // TODO: pick a better strategy, keys can collide now
22
+ return parts.join(':');
23
+ };
24
+ exports.keyFromParts = keyFromParts;
25
+ const sleep = (ms) => {
26
+ return new Promise((resolve) => setTimeout(resolve, ms));
27
+ };
28
+ exports.sleep = sleep;
29
+ exports.indexPrefix = '_index';
package/dist/env.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ declare const env: {
2
+ hostUrl: string;
3
+ hostPort: number;
4
+ externalUrl: string;
5
+ samlPath: string;
6
+ samlAudience: string;
7
+ preLoadedConfig: string | undefined;
8
+ internalHostUrl: string;
9
+ internalHostPort: number;
10
+ apiKeys: string[];
11
+ idpEnabled: string | undefined;
12
+ db: {
13
+ engine: string | undefined;
14
+ url: string | undefined;
15
+ type: string | undefined;
16
+ ttl: string | undefined;
17
+ encryptionKey: string | undefined;
18
+ cleanupLimit: string | undefined;
19
+ };
20
+ useInternalServer: boolean;
21
+ };
22
+ export default env;
package/dist/env.js ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const hostUrl = process.env.HOST_URL || 'localhost';
4
+ const hostPort = +(process.env.HOST_PORT || '5000');
5
+ const externalUrl = process.env.EXTERNAL_URL || 'http://' + hostUrl + ':' + hostPort;
6
+ const samlPath = process.env.SAML_PATH || '/oauth/saml';
7
+ const internalHostUrl = process.env.INTERNAL_HOST_URL || 'localhost';
8
+ const internalHostPort = +(process.env.INTERNAL_HOST_PORT || '6000');
9
+ const apiKeys = (process.env.JACKSON_API_KEYS || '').split(',');
10
+ const samlAudience = process.env.SAML_AUDIENCE || 'https://saml.boxyhq.com';
11
+ const preLoadedConfig = process.env.PRE_LOADED_CONFIG;
12
+ const idpEnabled = process.env.IDP_ENABLED;
13
+ const db = {
14
+ engine: process.env.DB_ENGINE,
15
+ url: process.env.DB_URL,
16
+ type: process.env.DB_TYPE,
17
+ ttl: process.env.DB_TTL,
18
+ encryptionKey: process.env.DB_ENCRYPTION_KEY,
19
+ cleanupLimit: process.env.DB_CLEANUP_LIMIT,
20
+ };
21
+ const env = {
22
+ hostUrl,
23
+ hostPort,
24
+ externalUrl,
25
+ samlPath,
26
+ samlAudience,
27
+ preLoadedConfig,
28
+ internalHostUrl,
29
+ internalHostPort,
30
+ apiKeys,
31
+ idpEnabled,
32
+ db,
33
+ useInternalServer: !(hostUrl === internalHostUrl && hostPort === internalHostPort),
34
+ };
35
+ exports.default = env;
@@ -0,0 +1,9 @@
1
+ import { JacksonOption } from './typings';
2
+ import { SAMLConfig } from './controller/api';
3
+ import { OAuthController } from './controller/oauth';
4
+ declare const controllers: (opts: JacksonOption) => Promise<{
5
+ apiController: SAMLConfig;
6
+ oauthController: OAuthController;
7
+ }>;
8
+ export default controllers;
9
+ export * from './typings';
package/dist/index.js ADDED
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ const api_1 = require("./controller/api");
26
+ const oauth_1 = require("./controller/oauth");
27
+ const db_1 = __importDefault(require("./db/db"));
28
+ const read_config_1 = __importDefault(require("./read-config"));
29
+ const defaultOpts = (opts) => {
30
+ const newOpts = Object.assign({}, opts);
31
+ if (!newOpts.externalUrl) {
32
+ throw new Error('externalUrl is required');
33
+ }
34
+ if (!newOpts.samlPath) {
35
+ throw new Error('samlPath is required');
36
+ }
37
+ newOpts.samlAudience = newOpts.samlAudience || 'https://saml.boxyhq.com';
38
+ newOpts.preLoadedConfig = newOpts.preLoadedConfig || ''; // path to folder containing static SAML config that will be preloaded. This is useful for self-hosted deployments that only have to support a single tenant (or small number of known tenants).
39
+ newOpts.idpEnabled = newOpts.idpEnabled === true;
40
+ newOpts.db = newOpts.db || {};
41
+ newOpts.db.engine = newOpts.db.engine || 'sql';
42
+ newOpts.db.url =
43
+ newOpts.db.url || 'postgresql://postgres:postgres@localhost:5432/postgres';
44
+ newOpts.db.type = newOpts.db.type || 'postgres'; // Only needed if DB_ENGINE is sql.
45
+ newOpts.db.ttl = (newOpts.db.ttl || 300) * 1; // TTL for the code, session and token stores (in seconds)
46
+ newOpts.db.cleanupLimit = (newOpts.db.cleanupLimit || 1000) * 1; // Limit cleanup of TTL entries to this many items at a time
47
+ return newOpts;
48
+ };
49
+ const controllers = (opts) => __awaiter(void 0, void 0, void 0, function* () {
50
+ opts = defaultOpts(opts);
51
+ const db = yield db_1.default.new(opts.db);
52
+ const configStore = db.store('saml:config');
53
+ const sessionStore = db.store('oauth:session', opts.db.ttl);
54
+ const codeStore = db.store('oauth:code', opts.db.ttl);
55
+ const tokenStore = db.store('oauth:token', opts.db.ttl);
56
+ const apiController = new api_1.SAMLConfig({ configStore });
57
+ const oauthController = new oauth_1.OAuthController({
58
+ configStore,
59
+ sessionStore,
60
+ codeStore,
61
+ tokenStore,
62
+ opts,
63
+ });
64
+ // write pre-loaded config if present
65
+ if (opts.preLoadedConfig && opts.preLoadedConfig.length > 0) {
66
+ const configs = yield (0, read_config_1.default)(opts.preLoadedConfig);
67
+ for (const config of configs) {
68
+ yield apiController.config(config);
69
+ console.log(`loaded config for tenant "${config.tenant}" and product "${config.product}"`);
70
+ }
71
+ }
72
+ const type = opts.db.engine === 'sql' && opts.db.type ? ' Type: ' + opts.db.type : '';
73
+ console.log(`Using engine: ${opts.db.engine}.${type}`);
74
+ return {
75
+ apiController,
76
+ oauthController,
77
+ };
78
+ });
79
+ exports.default = controllers;
80
+ __exportStar(require("./typings"), exports);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,153 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const cors_1 = __importDefault(require("cors"));
16
+ const express_1 = __importDefault(require("express"));
17
+ const utils_1 = require("./controller/utils");
18
+ const env_1 = __importDefault(require("./env"));
19
+ const index_1 = __importDefault(require("./index"));
20
+ let apiController;
21
+ let oauthController;
22
+ const oauthPath = '/oauth';
23
+ const apiPath = '/api/v1/saml';
24
+ const app = (0, express_1.default)();
25
+ app.use(express_1.default.json());
26
+ app.use(express_1.default.urlencoded({ extended: true }));
27
+ app.get(oauthPath + '/authorize', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
28
+ try {
29
+ // @ts-ignore
30
+ const { redirect_url } = yield oauthController.authorize(req.query);
31
+ res.redirect(redirect_url);
32
+ }
33
+ catch (err) {
34
+ const { message, statusCode = 500 } = err;
35
+ res.status(statusCode).send(message);
36
+ }
37
+ }));
38
+ app.post(env_1.default.samlPath, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
39
+ try {
40
+ const { redirect_url } = yield oauthController.samlResponse(req.body);
41
+ res.redirect(redirect_url);
42
+ }
43
+ catch (err) {
44
+ const { message, statusCode = 500 } = err;
45
+ res.status(statusCode).send(message);
46
+ }
47
+ }));
48
+ app.post(oauthPath + '/token', (0, cors_1.default)(), (req, res) => __awaiter(void 0, void 0, void 0, function* () {
49
+ try {
50
+ const result = yield oauthController.token(req.body);
51
+ res.json(result);
52
+ }
53
+ catch (err) {
54
+ const { message, statusCode = 500 } = err;
55
+ res.status(statusCode).send(message);
56
+ }
57
+ }));
58
+ app.get(oauthPath + '/userinfo', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
59
+ try {
60
+ let token = (0, utils_1.extractAuthToken)(req);
61
+ // check for query param
62
+ if (!token) {
63
+ // @ts-ignore
64
+ token = req.query.access_token;
65
+ }
66
+ if (!token) {
67
+ return res.status(401).json({ message: 'Unauthorized' });
68
+ }
69
+ const profile = yield oauthController.userInfo(token);
70
+ res.json(profile);
71
+ }
72
+ catch (err) {
73
+ const { message, statusCode = 500 } = err;
74
+ res.status(statusCode).json({ message });
75
+ }
76
+ }));
77
+ const server = app.listen(env_1.default.hostPort, () => __awaiter(void 0, void 0, void 0, function* () {
78
+ console.log(`🚀 The path of the righteous server: http://${env_1.default.hostUrl}:${env_1.default.hostPort}`);
79
+ // @ts-ignore
80
+ const ctrlrModule = yield (0, index_1.default)(env_1.default);
81
+ apiController = ctrlrModule.apiController;
82
+ oauthController = ctrlrModule.oauthController;
83
+ }));
84
+ // Internal routes, recommended not to expose this to the public interface though it would be guarded by API key(s)
85
+ let internalApp = app;
86
+ if (env_1.default.useInternalServer) {
87
+ internalApp = (0, express_1.default)();
88
+ internalApp.use(express_1.default.json());
89
+ internalApp.use(express_1.default.urlencoded({ extended: true }));
90
+ }
91
+ const validateApiKey = (token) => {
92
+ return env_1.default.apiKeys.includes(token);
93
+ };
94
+ internalApp.post(apiPath + '/config', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
95
+ try {
96
+ const apiKey = (0, utils_1.extractAuthToken)(req);
97
+ if (!validateApiKey(apiKey)) {
98
+ res.status(401).send('Unauthorized');
99
+ return;
100
+ }
101
+ res.json(yield apiController.config(req.body));
102
+ }
103
+ catch (err) {
104
+ const { message } = err;
105
+ res.status(500).json({
106
+ error: message,
107
+ });
108
+ }
109
+ }));
110
+ internalApp.get(apiPath + '/config', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
111
+ try {
112
+ const apiKey = (0, utils_1.extractAuthToken)(req);
113
+ if (!validateApiKey(apiKey)) {
114
+ res.status(401).send('Unauthorized');
115
+ return;
116
+ }
117
+ // @ts-ignore
118
+ res.json(yield apiController.getConfig(req.query));
119
+ }
120
+ catch (err) {
121
+ const { message } = err;
122
+ res.status(500).json({
123
+ error: message,
124
+ });
125
+ }
126
+ }));
127
+ internalApp.delete(apiPath + '/config', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
128
+ try {
129
+ const apiKey = (0, utils_1.extractAuthToken)(req);
130
+ if (!validateApiKey(apiKey)) {
131
+ res.status(401).send('Unauthorized');
132
+ return;
133
+ }
134
+ yield apiController.deleteConfig(req.body);
135
+ res.status(200).end();
136
+ }
137
+ catch (err) {
138
+ const { message } = err;
139
+ res.status(500).json({
140
+ error: message,
141
+ });
142
+ }
143
+ }));
144
+ let internalServer = server;
145
+ if (env_1.default.useInternalServer) {
146
+ internalServer = internalApp.listen(env_1.default.internalHostPort, () => __awaiter(void 0, void 0, void 0, function* () {
147
+ console.log(`🚀 The path of the righteous internal server: http://${env_1.default.internalHostUrl}:${env_1.default.internalHostPort}`);
148
+ }));
149
+ }
150
+ module.exports = {
151
+ server,
152
+ internalServer,
153
+ };
@@ -0,0 +1,3 @@
1
+ import { IdPConfig } from './typings';
2
+ declare const readConfig: (preLoadedConfig: string) => Promise<IdPConfig[]>;
3
+ export default readConfig;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ const fs = __importStar(require("fs"));
32
+ const path = __importStar(require("path"));
33
+ const readConfig = (preLoadedConfig) => __awaiter(void 0, void 0, void 0, function* () {
34
+ if (preLoadedConfig.startsWith('./')) {
35
+ preLoadedConfig = path.resolve(process.cwd(), preLoadedConfig);
36
+ }
37
+ const files = yield fs.promises.readdir(preLoadedConfig);
38
+ const configs = [];
39
+ for (const idx in files) {
40
+ const file = files[idx];
41
+ if (file.endsWith('.js')) {
42
+ const config = require(path.join(preLoadedConfig, file));
43
+ const rawMetadata = yield fs.promises.readFile(path.join(preLoadedConfig, path.parse(file).name + '.xml'), 'utf8');
44
+ config.rawMetadata = rawMetadata;
45
+ configs.push(config);
46
+ }
47
+ }
48
+ return configs;
49
+ });
50
+ exports.default = readConfig;