@niledatabase/server 3.0.0-alpha.27 → 3.0.0-alpha.29

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/dist/Api.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import { Routes } from './api/types';
2
+ import Auth from './auth';
2
3
  import Tenants from './tenants';
3
4
  import Users from './users';
4
5
  import { Config } from './utils/Config';
5
6
  export declare class Api {
6
7
  config: Config;
7
8
  users: Users;
9
+ auth: Auth;
8
10
  tenants: Tenants;
9
11
  routes: Routes;
10
12
  handlers: {
@@ -1,4 +1,12 @@
1
1
  import { Config } from '../../utils/Config';
2
+ export type JWT = {
3
+ email: string;
4
+ sub: string;
5
+ id: string;
6
+ iat: number;
7
+ exp: number;
8
+ jti: string;
9
+ };
2
10
  export type ActiveSession = {
3
11
  id: string;
4
12
  email: string;
@@ -3,7 +3,10 @@ type ApiRouteKeys = keyof typeof apiRoutes;
3
3
  export type ApiRoutePaths = (typeof apiRoutes)[ApiRouteKeys];
4
4
  export declare const apiRoutes: (config: Config) => {
5
5
  ME: string;
6
- USERS: (tenantId?: string) => string;
6
+ USERS: (qp: {
7
+ tenantId?: null | string;
8
+ newTenantName?: null | string;
9
+ }) => string;
7
10
  USER: (userId: string) => string;
8
11
  TENANTS: string;
9
12
  TENANT: (tenantId: string) => string;
@@ -1,2 +1,2 @@
1
1
  import { Config } from '../../../utils/Config';
2
- export declare function makeRestUrl(config: Config, path: string, qp?: Record<string, string>): string;
2
+ export declare function makeRestUrl(config: Config, path: string, qp?: Record<string, string | null>): string;
@@ -1,8 +1,10 @@
1
+ import { ActiveSession, JWT } from '../api/utils/auth';
1
2
  import { Config } from '../utils/Config';
3
+ import { NileRequest } from '../utils/Requester';
2
4
  /**
3
5
  * a helper function to log in server side.
4
6
  */
5
- export default function serverAuth(config: Config, handlers: {
7
+ export declare function serverLogin(config: Config, handlers: {
6
8
  GET: (req: Request) => Promise<void | Response>;
7
9
  POST: (req: Request) => Promise<void | Response>;
8
10
  DELETE: (req: Request) => Promise<void | Response>;
@@ -11,3 +13,10 @@ export default function serverAuth(config: Config, handlers: {
11
13
  email: string;
12
14
  password: string;
13
15
  }) => Promise<Headers>;
16
+ export default class Auth extends Config {
17
+ headers?: Headers;
18
+ constructor(config: Config, headers?: Headers);
19
+ handleHeaders(init?: RequestInit): RequestInit | undefined;
20
+ get sessionUrl(): string;
21
+ session: (req: NileRequest<void> | Headers, init?: RequestInit) => Promise<Response | JWT | ActiveSession>;
22
+ }
@@ -1217,22 +1217,30 @@ var DBManager = /*#__PURE__*/function () {
1217
1217
  }();
1218
1218
 
1219
1219
  var NILEDB_API_URL = process.env.NILEDB_API_URL;
1220
+ function filterNullUndefined(obj) {
1221
+ if (!obj) {
1222
+ return undefined;
1223
+ }
1224
+ return Object.fromEntries(Object.entries(obj).filter(function (_ref) {
1225
+ var value = _ref[1];
1226
+ return value !== null && value !== undefined;
1227
+ }));
1228
+ }
1220
1229
  function makeRestUrl(config, path, qp) {
1221
1230
  var url = config.api.basePath || NILEDB_API_URL;
1222
1231
  if (!url) {
1223
1232
  throw new Error('An API url is required. Set it via NILEDB_API_URL. Was auto configuration run?');
1224
1233
  }
1225
- var params = new URLSearchParams(qp);
1226
- return "" + [url, path.substring(1, path.length)].join('/') + (qp ? "?" + params.toString() : '');
1234
+ var params = new URLSearchParams(filterNullUndefined(qp));
1235
+ var strParams = params.toString();
1236
+ return "" + [url, path.substring(1, path.length)].join('/') + (strParams ? "?" + strParams : '');
1227
1237
  }
1228
1238
 
1229
1239
  var apiRoutes = function apiRoutes(config) {
1230
1240
  return {
1231
1241
  ME: makeRestUrl(config, '/me'),
1232
- USERS: function USERS(tenantId) {
1233
- return makeRestUrl(config, '/users', tenantId ? {
1234
- tenantId: tenantId
1235
- } : undefined);
1242
+ USERS: function USERS(qp) {
1243
+ return makeRestUrl(config, '/users', qp);
1236
1244
  },
1237
1245
  USER: function USER(userId) {
1238
1246
  return makeRestUrl(config, "/users/" + userId);
@@ -1781,7 +1789,7 @@ function POST$2(_x, _x2) {
1781
1789
  }
1782
1790
  function _POST$2() {
1783
1791
  _POST$2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(config, init) {
1784
- var yurl, tenantId, tenant, url;
1792
+ var yurl, tenantId, newTenantName, tenant, url;
1785
1793
  return _regeneratorRuntime().wrap(function _callee$(_context) {
1786
1794
  while (1) switch (_context.prev = _context.next) {
1787
1795
  case 0:
@@ -1789,13 +1797,17 @@ function _POST$2() {
1789
1797
  init.method = 'POST';
1790
1798
  yurl = new URL(init.request.url);
1791
1799
  tenantId = yurl.searchParams.get('tenantId');
1800
+ newTenantName = yurl.searchParams.get('newTenantName');
1792
1801
  tenant = tenantId != null ? tenantId : getTenantFromHttp(init.request.headers);
1793
- url = apiRoutes(config).USERS(tenant ? tenant : undefined);
1794
- _context.next = 8;
1802
+ url = apiRoutes(config).USERS({
1803
+ tenantId: tenant,
1804
+ newTenantName: newTenantName
1805
+ });
1806
+ _context.next = 9;
1795
1807
  return request(url, init, config);
1796
- case 8:
1797
- return _context.abrupt("return", _context.sent);
1798
1808
  case 9:
1809
+ return _context.abrupt("return", _context.sent);
1810
+ case 10:
1799
1811
  case "end":
1800
1812
  return _context.stop();
1801
1813
  }
@@ -3295,179 +3307,6 @@ var appRoutes = function appRoutes(prefix) {
3295
3307
  };
3296
3308
  };
3297
3309
 
3298
- // url host does not matter, we only match on the 1st leg by path
3299
- var ORIGIN = 'https://us-west-2.api.dev.thenile.dev';
3300
- /**
3301
- * a helper function to log in server side.
3302
- */
3303
- function serverAuth(config, handlers) {
3304
- var _Logger = Logger(config, '[server side login]'),
3305
- info = _Logger.info,
3306
- error = _Logger.error,
3307
- debug = _Logger.debug;
3308
- var routes = appRoutes(config.routePrefix);
3309
- return /*#__PURE__*/function () {
3310
- var _login = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
3311
- var _providers, _exec;
3312
- var email, password, sessionUrl, baseHeaders, sessionReq, sessionRes, providers, csrf, csrfReq, csrfRes, csrfToken, _yield$csrfRes$json, json, _ref2, credentials, csrfCookie, signInUrl, body, postReq, loginRes, authCookie, _ref3, token, headers;
3313
- return _regeneratorRuntime().wrap(function _callee$(_context) {
3314
- while (1) switch (_context.prev = _context.next) {
3315
- case 0:
3316
- email = _ref.email, password = _ref.password;
3317
- if (!(!email || !password)) {
3318
- _context.next = 3;
3319
- break;
3320
- }
3321
- throw new Error('Server side login requires a user email and password.');
3322
- case 3:
3323
- sessionUrl = new URL("" + ORIGIN + routes.PROVIDERS);
3324
- baseHeaders = {
3325
- host: sessionUrl.host,
3326
- 'niledb-origin': ORIGIN
3327
- };
3328
- info("Obtaining providers for " + email);
3329
- sessionReq = new Request(sessionUrl, _extends({
3330
- method: 'GET'
3331
- }, baseHeaders));
3332
- _context.next = 9;
3333
- return handlers.POST(sessionReq);
3334
- case 9:
3335
- sessionRes = _context.sent;
3336
- if (!((sessionRes == null ? void 0 : sessionRes.status) === 404)) {
3337
- _context.next = 12;
3338
- break;
3339
- }
3340
- throw new Error('Unable to login, cannot find region api.');
3341
- case 12:
3342
- _context.prev = 12;
3343
- _context.next = 15;
3344
- return sessionRes == null ? void 0 : sessionRes.json();
3345
- case 15:
3346
- providers = _context.sent;
3347
- _context.next = 22;
3348
- break;
3349
- case 18:
3350
- _context.prev = 18;
3351
- _context.t0 = _context["catch"](12);
3352
- info(sessionUrl, {
3353
- sessionRes: sessionRes
3354
- });
3355
- error(_context.t0);
3356
- case 22:
3357
- info('Obtaining csrf');
3358
- csrf = new URL("" + ORIGIN + routes.CSRF);
3359
- csrfReq = new Request(csrf, {
3360
- method: 'GET',
3361
- headers: new Headers(_extends({}, baseHeaders))
3362
- });
3363
- _context.next = 27;
3364
- return handlers.POST(csrfReq);
3365
- case 27:
3366
- csrfRes = _context.sent;
3367
- _context.prev = 28;
3368
- _context.next = 31;
3369
- return csrfRes == null ? void 0 : csrfRes.json();
3370
- case 31:
3371
- _context.t1 = _yield$csrfRes$json = _context.sent;
3372
- if (!(_context.t1 != null)) {
3373
- _context.next = 36;
3374
- break;
3375
- }
3376
- _context.t2 = _yield$csrfRes$json;
3377
- _context.next = 37;
3378
- break;
3379
- case 36:
3380
- _context.t2 = {};
3381
- case 37:
3382
- json = _context.t2;
3383
- csrfToken = json == null ? void 0 : json.csrfToken;
3384
- _context.next = 45;
3385
- break;
3386
- case 41:
3387
- _context.prev = 41;
3388
- _context.t3 = _context["catch"](28);
3389
- info(sessionUrl, {
3390
- csrfRes: csrfRes
3391
- });
3392
- error(_context.t3, {
3393
- csrfRes: csrfRes
3394
- });
3395
- case 45:
3396
- _ref2 = (_providers = providers) != null ? _providers : {}, credentials = _ref2.credentials;
3397
- csrfCookie = csrfRes == null ? void 0 : csrfRes.headers.get('set-cookie');
3398
- if (credentials) {
3399
- _context.next = 49;
3400
- break;
3401
- }
3402
- throw new Error('Unable to obtain credential provider. Aborting server side login.');
3403
- case 49:
3404
- signInUrl = new URL(credentials.callbackUrl);
3405
- if (csrfCookie) {
3406
- _context.next = 53;
3407
- break;
3408
- }
3409
- debug('CSRF failed', {
3410
- headers: csrfRes == null ? void 0 : csrfRes.headers
3411
- });
3412
- throw new Error('Unable to authenticate REST, CSRF missing.');
3413
- case 53:
3414
- info("Attempting sign in with email " + email + " " + signInUrl.href);
3415
- body = JSON.stringify({
3416
- email: email,
3417
- password: password,
3418
- csrfToken: csrfToken,
3419
- callbackUrl: credentials.callbackUrl
3420
- });
3421
- postReq = new Request(signInUrl, {
3422
- method: 'POST',
3423
- headers: new Headers(_extends({}, baseHeaders, {
3424
- 'content-type': 'application/json',
3425
- cookie: csrfCookie.split(',').join('; ')
3426
- })),
3427
- body: body
3428
- });
3429
- _context.next = 58;
3430
- return handlers.POST(postReq);
3431
- case 58:
3432
- loginRes = _context.sent;
3433
- authCookie = loginRes == null ? void 0 : loginRes.headers.get('set-cookie');
3434
- if (authCookie) {
3435
- _context.next = 62;
3436
- break;
3437
- }
3438
- throw new Error('authentication failed');
3439
- case 62:
3440
- _ref3 = (_exec = /((__Secure-)?nile\.session-token=.+?);/.exec(authCookie)) != null ? _exec : [], token = _ref3[1];
3441
- if (token) {
3442
- _context.next = 66;
3443
- break;
3444
- }
3445
- error('Unable to obtain auth token', {
3446
- authCookie: authCookie
3447
- });
3448
- throw new Error('Server login failed');
3449
- case 66:
3450
- info('Server login successful', {
3451
- authCookie: authCookie,
3452
- csrfCookie: csrfCookie
3453
- });
3454
- headers = new Headers(_extends({}, baseHeaders, {
3455
- cookie: [token, csrfCookie].join('; ')
3456
- }));
3457
- return _context.abrupt("return", headers);
3458
- case 69:
3459
- case "end":
3460
- return _context.stop();
3461
- }
3462
- }, _callee, null, [[12, 18], [28, 41]]);
3463
- }));
3464
- function login(_x) {
3465
- return _login.apply(this, arguments);
3466
- }
3467
- return login;
3468
- }();
3469
- }
3470
-
3471
3310
  var Requester = /*#__PURE__*/function (_Config) {
3472
3311
  function Requester(config) {
3473
3312
  return _Config.call(this, config) || this;
@@ -3709,6 +3548,233 @@ var Requester = /*#__PURE__*/function (_Config) {
3709
3548
  return Requester;
3710
3549
  }(Config);
3711
3550
 
3551
+ // url host does not matter, we only match on the 1st leg by path
3552
+ var ORIGIN = 'https://us-west-2.api.dev.thenile.dev';
3553
+ /**
3554
+ * a helper function to log in server side.
3555
+ */
3556
+ function serverLogin(config, handlers) {
3557
+ var _Logger = Logger(config, '[server side login]'),
3558
+ info = _Logger.info,
3559
+ error = _Logger.error,
3560
+ debug = _Logger.debug;
3561
+ var routes = appRoutes(config.routePrefix);
3562
+ return /*#__PURE__*/function () {
3563
+ var _login = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
3564
+ var _providers, _exec;
3565
+ var email, password, sessionUrl, baseHeaders, sessionReq, sessionRes, providers, csrf, csrfReq, csrfRes, csrfToken, _yield$csrfRes$json, json, _ref2, credentials, csrfCookie, signInUrl, body, postReq, loginRes, authCookie, _ref3, token, headers;
3566
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
3567
+ while (1) switch (_context.prev = _context.next) {
3568
+ case 0:
3569
+ email = _ref.email, password = _ref.password;
3570
+ if (!(!email || !password)) {
3571
+ _context.next = 3;
3572
+ break;
3573
+ }
3574
+ throw new Error('Server side login requires a user email and password.');
3575
+ case 3:
3576
+ sessionUrl = new URL("" + ORIGIN + routes.PROVIDERS);
3577
+ baseHeaders = {
3578
+ host: sessionUrl.host,
3579
+ 'niledb-origin': ORIGIN
3580
+ };
3581
+ info("Obtaining providers for " + email);
3582
+ sessionReq = new Request(sessionUrl, _extends({
3583
+ method: 'GET'
3584
+ }, baseHeaders));
3585
+ _context.next = 9;
3586
+ return handlers.POST(sessionReq);
3587
+ case 9:
3588
+ sessionRes = _context.sent;
3589
+ if (!((sessionRes == null ? void 0 : sessionRes.status) === 404)) {
3590
+ _context.next = 12;
3591
+ break;
3592
+ }
3593
+ throw new Error('Unable to login, cannot find region api.');
3594
+ case 12:
3595
+ _context.prev = 12;
3596
+ _context.next = 15;
3597
+ return sessionRes == null ? void 0 : sessionRes.json();
3598
+ case 15:
3599
+ providers = _context.sent;
3600
+ _context.next = 22;
3601
+ break;
3602
+ case 18:
3603
+ _context.prev = 18;
3604
+ _context.t0 = _context["catch"](12);
3605
+ info(sessionUrl, {
3606
+ sessionRes: sessionRes
3607
+ });
3608
+ error(_context.t0);
3609
+ case 22:
3610
+ info('Obtaining csrf');
3611
+ csrf = new URL("" + ORIGIN + routes.CSRF);
3612
+ csrfReq = new Request(csrf, {
3613
+ method: 'GET',
3614
+ headers: new Headers(_extends({}, baseHeaders))
3615
+ });
3616
+ _context.next = 27;
3617
+ return handlers.POST(csrfReq);
3618
+ case 27:
3619
+ csrfRes = _context.sent;
3620
+ _context.prev = 28;
3621
+ _context.next = 31;
3622
+ return csrfRes == null ? void 0 : csrfRes.json();
3623
+ case 31:
3624
+ _context.t1 = _yield$csrfRes$json = _context.sent;
3625
+ if (!(_context.t1 != null)) {
3626
+ _context.next = 36;
3627
+ break;
3628
+ }
3629
+ _context.t2 = _yield$csrfRes$json;
3630
+ _context.next = 37;
3631
+ break;
3632
+ case 36:
3633
+ _context.t2 = {};
3634
+ case 37:
3635
+ json = _context.t2;
3636
+ csrfToken = json == null ? void 0 : json.csrfToken;
3637
+ _context.next = 45;
3638
+ break;
3639
+ case 41:
3640
+ _context.prev = 41;
3641
+ _context.t3 = _context["catch"](28);
3642
+ info(sessionUrl, {
3643
+ csrfRes: csrfRes
3644
+ });
3645
+ error(_context.t3, {
3646
+ csrfRes: csrfRes
3647
+ });
3648
+ case 45:
3649
+ _ref2 = (_providers = providers) != null ? _providers : {}, credentials = _ref2.credentials;
3650
+ csrfCookie = csrfRes == null ? void 0 : csrfRes.headers.get('set-cookie');
3651
+ if (credentials) {
3652
+ _context.next = 49;
3653
+ break;
3654
+ }
3655
+ throw new Error('Unable to obtain credential provider. Aborting server side login.');
3656
+ case 49:
3657
+ signInUrl = new URL(credentials.callbackUrl);
3658
+ if (csrfCookie) {
3659
+ _context.next = 53;
3660
+ break;
3661
+ }
3662
+ debug('CSRF failed', {
3663
+ headers: csrfRes == null ? void 0 : csrfRes.headers
3664
+ });
3665
+ throw new Error('Unable to authenticate REST, CSRF missing.');
3666
+ case 53:
3667
+ info("Attempting sign in with email " + email + " " + signInUrl.href);
3668
+ body = JSON.stringify({
3669
+ email: email,
3670
+ password: password,
3671
+ csrfToken: csrfToken,
3672
+ callbackUrl: credentials.callbackUrl
3673
+ });
3674
+ postReq = new Request(signInUrl, {
3675
+ method: 'POST',
3676
+ headers: new Headers(_extends({}, baseHeaders, {
3677
+ 'content-type': 'application/json',
3678
+ cookie: csrfCookie.split(',').join('; ')
3679
+ })),
3680
+ body: body
3681
+ });
3682
+ _context.next = 58;
3683
+ return handlers.POST(postReq);
3684
+ case 58:
3685
+ loginRes = _context.sent;
3686
+ authCookie = loginRes == null ? void 0 : loginRes.headers.get('set-cookie');
3687
+ if (authCookie) {
3688
+ _context.next = 62;
3689
+ break;
3690
+ }
3691
+ throw new Error('authentication failed');
3692
+ case 62:
3693
+ _ref3 = (_exec = /((__Secure-)?nile\.session-token=.+?);/.exec(authCookie)) != null ? _exec : [], token = _ref3[1];
3694
+ if (token) {
3695
+ _context.next = 66;
3696
+ break;
3697
+ }
3698
+ error('Unable to obtain auth token', {
3699
+ authCookie: authCookie
3700
+ });
3701
+ throw new Error('Server login failed');
3702
+ case 66:
3703
+ info('Server login successful', {
3704
+ authCookie: authCookie,
3705
+ csrfCookie: csrfCookie
3706
+ });
3707
+ headers = new Headers(_extends({}, baseHeaders, {
3708
+ cookie: [token, csrfCookie].join('; ')
3709
+ }));
3710
+ return _context.abrupt("return", headers);
3711
+ case 69:
3712
+ case "end":
3713
+ return _context.stop();
3714
+ }
3715
+ }, _callee, null, [[12, 18], [28, 41]]);
3716
+ }));
3717
+ function login(_x) {
3718
+ return _login.apply(this, arguments);
3719
+ }
3720
+ return login;
3721
+ }();
3722
+ }
3723
+ var Auth = /*#__PURE__*/function (_Config) {
3724
+ function Auth(config, headers) {
3725
+ var _this;
3726
+ _this = _Config.call(this, config) || this;
3727
+ _this.headers = void 0;
3728
+ _this.session = /*#__PURE__*/function () {
3729
+ var _ref4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(req, init) {
3730
+ var _requester, _init;
3731
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
3732
+ while (1) switch (_context2.prev = _context2.next) {
3733
+ case 0:
3734
+ _requester = new Requester(_this);
3735
+ _init = _this.handleHeaders(init);
3736
+ _context2.next = 4;
3737
+ return _requester.get(req, _this.sessionUrl, _init);
3738
+ case 4:
3739
+ return _context2.abrupt("return", _context2.sent);
3740
+ case 5:
3741
+ case "end":
3742
+ return _context2.stop();
3743
+ }
3744
+ }, _callee2);
3745
+ }));
3746
+ return function (_x2, _x3) {
3747
+ return _ref4.apply(this, arguments);
3748
+ };
3749
+ }();
3750
+ _this.headers = headers;
3751
+ return _this;
3752
+ }
3753
+ _inheritsLoose(Auth, _Config);
3754
+ var _proto = Auth.prototype;
3755
+ _proto.handleHeaders = function handleHeaders(init) {
3756
+ if (this.headers) {
3757
+ if (init) {
3758
+ var _init2;
3759
+ init.headers = new Headers(_extends({}, this.headers, (_init2 = init) == null ? void 0 : _init2.headers));
3760
+ return init;
3761
+ } else {
3762
+ init = {
3763
+ headers: this.headers
3764
+ };
3765
+ return init;
3766
+ }
3767
+ }
3768
+ return undefined;
3769
+ };
3770
+ return _createClass(Auth, [{
3771
+ key: "sessionUrl",
3772
+ get: function get() {
3773
+ return '/auth/session';
3774
+ }
3775
+ }]);
3776
+ }(Config);
3777
+
3712
3778
  var Tenants = /*#__PURE__*/function (_Config) {
3713
3779
  function Tenants(config, headers) {
3714
3780
  var _this;
@@ -4049,10 +4115,12 @@ var Api = /*#__PURE__*/function () {
4049
4115
  function Api(config) {
4050
4116
  this.config = void 0;
4051
4117
  this.users = void 0;
4118
+ this.auth = void 0;
4052
4119
  this.tenants = void 0;
4053
4120
  this.routes = void 0;
4054
4121
  this.handlers = void 0;
4055
4122
  this.config = config;
4123
+ this.auth = new Auth(config);
4056
4124
  this.users = new Users(config);
4057
4125
  this.tenants = new Tenants(config);
4058
4126
  this.routes = _extends({}, appRoutes(config == null ? void 0 : config.routePrefix), config == null ? void 0 : config.routes);
@@ -4069,7 +4137,7 @@ var Api = /*#__PURE__*/function () {
4069
4137
  while (1) switch (_context.prev = _context.next) {
4070
4138
  case 0:
4071
4139
  _context.next = 2;
4072
- return serverAuth(this.config, this.handlers)(payload);
4140
+ return serverLogin(this.config, this.handlers)(payload);
4073
4141
  case 2:
4074
4142
  this.headers = _context.sent;
4075
4143
  case 3: