@boxyhq/saml-jackson 0.2.3-beta.236 → 0.2.3-beta.241

Sign up to get free protection for your applications and to get access to all the features.
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 +3 -2
@@ -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;