caprover-api 0.0.5 → 0.0.7

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/README.md CHANGED
@@ -19,13 +19,12 @@ import CapRoverAPI, { CapRoverModels } from 'caprover-api'
19
19
 
20
20
  const caprover = new CapRoverAPI(
21
21
  'https://captain.server.demo.caprover.com',
22
- () => {
23
- // get password and otp from user
22
+ new SimpleAuthenticationProvider(() => {
24
23
  return Promise.resolve({
25
24
  password: 'captain42',
26
- otpToken: undefined, // only if 2FA is enabled
25
+ otpToken: undefined,
27
26
  })
28
- }
27
+ })
29
28
  )
30
29
 
31
30
  caprover
@@ -28,14 +28,24 @@ export type AuthenticationContent = {
28
28
  password: string;
29
29
  otpToken?: string;
30
30
  };
31
- export type AuthRequiredCallback = () => Promise<AuthenticationContent>;
31
+ export interface AuthenticationProvider {
32
+ onAuthTokenRequested(): Promise<string>;
33
+ onCredentialsRequested(): Promise<AuthenticationContent>;
34
+ onAuthTokenUpdated(authToken: string): void;
35
+ }
36
+ export declare class SimpleAuthenticationProvider implements AuthenticationProvider {
37
+ private onCredRequestedImpl;
38
+ private authToken;
39
+ constructor(onCredRequestedImpl: () => Promise<AuthenticationContent>);
40
+ onAuthTokenRequested(): Promise<string>;
41
+ onCredentialsRequested(): Promise<AuthenticationContent>;
42
+ onAuthTokenUpdated(newAuthToken: string): void;
43
+ }
32
44
  export default class ApiManager {
33
- private authCallback;
34
- private authToken?;
35
45
  private http;
36
- constructor(baseDomain: string, authCallback: AuthRequiredCallback, authToken?: string | undefined);
46
+ constructor(baseDomain: string, authProvider: AuthenticationProvider);
37
47
  destroy(): void;
38
- getAuthToken(): Promise<string>;
48
+ login(password: string, otpToken?: string): Promise<string>;
39
49
  getAllThemes(): Promise<{
40
50
  themes: CapRoverTheme[] | undefined;
41
51
  }>;
@@ -3,32 +3,55 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SimpleAuthenticationProvider = void 0;
6
7
  const HttpClient_1 = __importDefault(require("./HttpClient"));
8
+ class SimpleAuthenticationProvider {
9
+ constructor(onCredRequestedImpl) {
10
+ this.onCredRequestedImpl = onCredRequestedImpl;
11
+ this.authToken = '';
12
+ }
13
+ onAuthTokenRequested() {
14
+ return Promise.resolve(this.authToken);
15
+ }
16
+ onCredentialsRequested() {
17
+ return this.onCredRequestedImpl();
18
+ }
19
+ onAuthTokenUpdated(newAuthToken) {
20
+ this.authToken = newAuthToken;
21
+ }
22
+ }
23
+ exports.SimpleAuthenticationProvider = SimpleAuthenticationProvider;
7
24
  class ApiManager {
8
- constructor(baseDomain, authCallback, authToken) {
9
- this.authCallback = authCallback;
10
- this.authToken = authToken;
25
+ constructor(baseDomain, authProvider) {
11
26
  const self = this;
12
27
  const URL = baseDomain + '/api/v2';
13
- this.http = new HttpClient_1.default(URL, function () {
14
- return self.getAuthToken();
15
- }, authToken);
28
+ this.http = new HttpClient_1.default(URL, () => {
29
+ return authProvider.onAuthTokenRequested();
30
+ }, () => {
31
+ return Promise.resolve() //
32
+ .then(() => {
33
+ return authProvider.onCredentialsRequested();
34
+ })
35
+ .then((authContent) => {
36
+ return self.login(authContent.password, authContent.otpToken);
37
+ }) //
38
+ .then((authToken) => {
39
+ authProvider.onAuthTokenUpdated(authToken);
40
+ });
41
+ });
16
42
  }
17
43
  destroy() {
18
44
  this.http.destroy();
19
45
  }
20
- getAuthToken() {
46
+ login(password, otpToken) {
21
47
  const self = this;
22
48
  const http = self.http;
23
49
  return Promise.resolve() //
24
- .then(() => {
25
- return self.authCallback();
26
- })
27
50
  .then((authContent) => {
28
51
  return Promise.resolve() //
29
52
  .then(http.fetch(http.POST, '/login', {
30
- password: authContent?.password,
31
- otpToken: authContent?.otpToken,
53
+ password: password,
54
+ otpToken: otpToken,
32
55
  }));
33
56
  })
34
57
  .then(function (data) {
@@ -1,13 +1,12 @@
1
1
  export default class HttpClient {
2
2
  private baseUrl;
3
- private onAuthFailure;
4
- private authToken?;
3
+ private authTokenProvider;
4
+ private onLoginRequested;
5
5
  readonly GET = "GET";
6
6
  readonly POST = "POST";
7
7
  isDestroyed: boolean;
8
- constructor(baseUrl: string, onAuthFailure: () => Promise<string>, authToken?: string | undefined);
9
- createHeaders(): any;
10
- setAuthToken(authToken: string): void;
8
+ constructor(baseUrl: string, authTokenProvider: () => Promise<string>, onLoginRequested: () => Promise<void>);
9
+ createHeaders(): Promise<any>;
11
10
  destroy(): void;
12
11
  fetch(method: 'GET' | 'POST', endpoint: string, variables: any): () => Promise<any>;
13
12
  fetchInternal(method: 'GET' | 'POST', endpoint: string, variables: any): Promise<import("axios").AxiosResponse<any, any>>;
@@ -9,27 +9,28 @@ let TOKEN_HEADER = 'x-captain-auth';
9
9
  let NAMESPACE = 'x-namespace';
10
10
  let CAPTAIN = 'captain';
11
11
  class HttpClient {
12
- constructor(baseUrl, onAuthFailure, authToken) {
12
+ constructor(baseUrl, authTokenProvider, onLoginRequested) {
13
13
  this.baseUrl = baseUrl;
14
- this.onAuthFailure = onAuthFailure;
15
- this.authToken = authToken;
14
+ this.authTokenProvider = authTokenProvider;
15
+ this.onLoginRequested = onLoginRequested;
16
16
  this.GET = 'GET';
17
17
  this.POST = 'POST';
18
18
  this.isDestroyed = false;
19
- if (!authToken) {
20
- this.authToken = '';
21
- }
19
+ //
22
20
  }
23
21
  createHeaders() {
24
22
  let headers = {};
25
- if (this.authToken)
26
- headers[TOKEN_HEADER] = this.authToken;
27
23
  headers[NAMESPACE] = CAPTAIN;
28
24
  // check user/appData or apiManager.uploadAppData before changing this signature.
29
- return headers;
30
- }
31
- setAuthToken(authToken) {
32
- this.authToken = authToken;
25
+ return Promise.resolve() //
26
+ .then(() => {
27
+ return this.authTokenProvider();
28
+ })
29
+ .then((authToken) => {
30
+ if (authToken)
31
+ headers[TOKEN_HEADER] = authToken;
32
+ return headers;
33
+ });
33
34
  }
34
35
  destroy() {
35
36
  this.isDestroyed = true;
@@ -43,11 +44,12 @@ class HttpClient {
43
44
  })
44
45
  .then(function (axiosResponse) {
45
46
  const data = axiosResponse.data; // this is an axios thing!
46
- if (data.status === ErrorFactory_1.default.STATUS_AUTH_TOKEN_INVALID) {
47
+ if (
48
+ // if we ever get STATUS_ERROR_NOT_AUTHORIZED when trying to log in, we will end up in an infinite loop!
49
+ data.status === ErrorFactory_1.default.STATUS_AUTH_TOKEN_INVALID) {
47
50
  return self
48
- .onAuthFailure() //
49
- .then(function (authToken) {
50
- self.setAuthToken(authToken);
51
+ .onLoginRequested() //
52
+ .then(function () {
51
53
  return self
52
54
  .fetchInternal(method, endpoint, variables)
53
55
  .then(function (newAxiosResponse) {
@@ -55,15 +57,6 @@ class HttpClient {
55
57
  });
56
58
  })
57
59
  .catch(function (error) {
58
- // Upon wrong password or back-off error, we force logout the user
59
- // to avoid getting stuck with wrong password loop
60
- if (error.captainStatus + '' ===
61
- ErrorFactory_1.default.STATUS_PASSWORD_BACK_OFF +
62
- '' ||
63
- error.captainStatus + '' ===
64
- ErrorFactory_1.default.STATUS_WRONG_PASSWORD + '') {
65
- self.setAuthToken('');
66
- }
67
60
  return Promise.reject(error);
68
61
  });
69
62
  }
@@ -107,11 +100,16 @@ class HttpClient {
107
100
  }
108
101
  getReq(endpoint, variables) {
109
102
  const self = this;
110
- return axios_1.default
111
- .get(this.baseUrl + endpoint, {
112
- params: variables,
113
- headers: self.createHeaders(),
114
- }) //
103
+ return Promise.resolve() //
104
+ .then(function () {
105
+ return self.createHeaders();
106
+ })
107
+ .then(function (headers) {
108
+ return axios_1.default.get(self.baseUrl + endpoint, {
109
+ params: variables,
110
+ headers: headers,
111
+ });
112
+ })
115
113
  .then(function (data) {
116
114
  // console.log(data);
117
115
  return data;
@@ -119,9 +117,14 @@ class HttpClient {
119
117
  }
120
118
  postReq(endpoint, variables) {
121
119
  const self = this;
122
- return axios_1.default
123
- .post(this.baseUrl + endpoint, variables, {
124
- headers: self.createHeaders(),
120
+ return Promise.resolve() //
121
+ .then(function () {
122
+ return self.createHeaders();
123
+ })
124
+ .then(function (headers) {
125
+ return axios_1.default.post(self.baseUrl + endpoint, variables, {
126
+ headers: headers,
127
+ }); //
125
128
  }) //
126
129
  .then(function (data) {
127
130
  // console.log(data);
package/dist/example.js CHANGED
@@ -1,16 +1,45 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
5
35
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const index_1 = __importDefault(require("./index"));
7
- const caprover = new index_1.default('https://captain.server.demo.caprover.com', () => {
8
- // get password and otp from user
36
+ const index_1 = __importStar(require("./index"));
37
+ const caprover = new index_1.default('https://captain.server.demo.caprover.com', new index_1.SimpleAuthenticationProvider(() => {
9
38
  return Promise.resolve({
10
39
  password: 'captain42',
11
40
  otpToken: undefined,
12
41
  });
13
- });
42
+ }));
14
43
  console.log('===============================================');
15
44
  Promise.resolve()
16
45
  .then(() => {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import CapRoverAPI from './api/ApiManager';
2
2
  import * as CapRoverModels from './models';
3
+ import { AuthenticationContent, SimpleAuthenticationProvider, AuthenticationProvider } from './api/ApiManager';
3
4
  export default CapRoverAPI;
4
5
  export { CapRoverModels };
6
+ export { AuthenticationContent, SimpleAuthenticationProvider, AuthenticationProvider, };
package/dist/index.js CHANGED
@@ -36,8 +36,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.CapRoverModels = void 0;
39
+ exports.SimpleAuthenticationProvider = exports.CapRoverModels = void 0;
40
40
  const ApiManager_1 = __importDefault(require("./api/ApiManager"));
41
41
  const CapRoverModels = __importStar(require("./models"));
42
42
  exports.CapRoverModels = CapRoverModels;
43
+ const ApiManager_2 = require("./api/ApiManager");
44
+ Object.defineProperty(exports, "SimpleAuthenticationProvider", { enumerable: true, get: function () { return ApiManager_2.SimpleAuthenticationProvider; } });
43
45
  exports.default = ApiManager_1.default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "caprover-api",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "API client for CapRover",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
@@ -36,24 +36,58 @@ export type AuthenticationContent = {
36
36
  otpToken?: string
37
37
  }
38
38
 
39
- export type AuthRequiredCallback = () => Promise<AuthenticationContent>
39
+ export interface AuthenticationProvider {
40
+ onAuthTokenRequested(): Promise<string>
41
+ onCredentialsRequested(): Promise<AuthenticationContent>
42
+ onAuthTokenUpdated(authToken: string): void
43
+ }
44
+
45
+ export class SimpleAuthenticationProvider implements AuthenticationProvider {
46
+ private authToken: string = ''
47
+
48
+ constructor(
49
+ private onCredRequestedImpl: () => Promise<AuthenticationContent>
50
+ ) {}
51
+
52
+ onAuthTokenRequested(): Promise<string> {
53
+ return Promise.resolve(this.authToken)
54
+ }
55
+
56
+ onCredentialsRequested(): Promise<AuthenticationContent> {
57
+ return this.onCredRequestedImpl()
58
+ }
59
+
60
+ onAuthTokenUpdated(newAuthToken: string) {
61
+ this.authToken = newAuthToken
62
+ }
63
+ }
40
64
 
41
65
  export default class ApiManager {
42
66
  private http: HttpClient
43
67
 
44
- constructor(
45
- baseDomain: string,
46
- private authCallback: AuthRequiredCallback,
47
- private authToken?: string
48
- ) {
68
+ constructor(baseDomain: string, authProvider: AuthenticationProvider) {
49
69
  const self = this
50
70
  const URL = baseDomain + '/api/v2'
51
71
  this.http = new HttpClient(
52
72
  URL,
53
- function () {
54
- return self.getAuthToken()
73
+ () => {
74
+ return authProvider.onAuthTokenRequested()
55
75
  },
56
- authToken
76
+ () => {
77
+ return Promise.resolve() //
78
+ .then(() => {
79
+ return authProvider.onCredentialsRequested()
80
+ })
81
+ .then((authContent) => {
82
+ return self.login(
83
+ authContent.password,
84
+ authContent.otpToken
85
+ )
86
+ }) //
87
+ .then((authToken) => {
88
+ authProvider.onAuthTokenUpdated(authToken)
89
+ })
90
+ }
57
91
  )
58
92
  }
59
93
 
@@ -61,20 +95,17 @@ export default class ApiManager {
61
95
  this.http.destroy()
62
96
  }
63
97
 
64
- getAuthToken(): Promise<string> {
98
+ login(password: string, otpToken?: string): Promise<string> {
65
99
  const self = this
66
100
  const http = self.http
67
101
 
68
102
  return Promise.resolve() //
69
- .then(() => {
70
- return self.authCallback()
71
- })
72
103
  .then((authContent) => {
73
104
  return Promise.resolve() //
74
105
  .then(
75
106
  http.fetch(http.POST, '/login', {
76
- password: authContent?.password,
77
- otpToken: authContent?.otpToken,
107
+ password: password,
108
+ otpToken: otpToken,
78
109
  })
79
110
  )
80
111
  })
@@ -1,5 +1,6 @@
1
1
  import axios from 'axios'
2
2
  import ErrorFactory from './ErrorFactory'
3
+ import { AuthenticationProvider } from './ApiManager'
3
4
 
4
5
  let TOKEN_HEADER = 'x-captain-auth'
5
6
  let NAMESPACE = 'x-namespace'
@@ -12,25 +13,26 @@ export default class HttpClient {
12
13
 
13
14
  constructor(
14
15
  private baseUrl: string,
15
- private onAuthFailure: () => Promise<string>,
16
- private authToken?: string
16
+ private authTokenProvider: () => Promise<string>,
17
+ private onLoginRequested: () => Promise<void>
17
18
  ) {
18
- if (!authToken) {
19
- this.authToken = ''
20
- }
19
+ //
21
20
  }
22
21
 
23
22
  createHeaders() {
24
23
  let headers: any = {}
25
- if (this.authToken) headers[TOKEN_HEADER] = this.authToken
26
24
  headers[NAMESPACE] = CAPTAIN
27
25
 
28
26
  // check user/appData or apiManager.uploadAppData before changing this signature.
29
- return headers
30
- }
31
27
 
32
- setAuthToken(authToken: string) {
33
- this.authToken = authToken
28
+ return Promise.resolve() //
29
+ .then(() => {
30
+ return this.authTokenProvider()
31
+ })
32
+ .then((authToken) => {
33
+ if (authToken) headers[TOKEN_HEADER] = authToken
34
+ return headers
35
+ })
34
36
  }
35
37
 
36
38
  destroy() {
@@ -48,12 +50,12 @@ export default class HttpClient {
48
50
  const data = axiosResponse.data // this is an axios thing!
49
51
 
50
52
  if (
53
+ // if we ever get STATUS_ERROR_NOT_AUTHORIZED when trying to log in, we will end up in an infinite loop!
51
54
  data.status === ErrorFactory.STATUS_AUTH_TOKEN_INVALID
52
55
  ) {
53
56
  return self
54
- .onAuthFailure() //
55
- .then(function (authToken) {
56
- self.setAuthToken(authToken)
57
+ .onLoginRequested() //
58
+ .then(function () {
57
59
  return self
58
60
  .fetchInternal(method, endpoint, variables)
59
61
  .then(function (newAxiosResponse) {
@@ -61,18 +63,6 @@ export default class HttpClient {
61
63
  })
62
64
  })
63
65
  .catch(function (error) {
64
- // Upon wrong password or back-off error, we force logout the user
65
- // to avoid getting stuck with wrong password loop
66
- if (
67
- error.captainStatus + '' ===
68
- ErrorFactory.STATUS_PASSWORD_BACK_OFF +
69
- '' ||
70
- error.captainStatus + '' ===
71
- ErrorFactory.STATUS_WRONG_PASSWORD + ''
72
- ) {
73
- self.setAuthToken('')
74
- }
75
-
76
66
  return Promise.reject(error)
77
67
  })
78
68
  } else {
@@ -120,11 +110,16 @@ export default class HttpClient {
120
110
 
121
111
  getReq(endpoint: string, variables: any) {
122
112
  const self = this
123
- return axios
124
- .get(this.baseUrl + endpoint, {
125
- params: variables,
126
- headers: self.createHeaders(),
127
- }) //
113
+ return Promise.resolve() //
114
+ .then(function () {
115
+ return self.createHeaders()
116
+ })
117
+ .then(function (headers) {
118
+ return axios.get(self.baseUrl + endpoint, {
119
+ params: variables,
120
+ headers: headers,
121
+ })
122
+ })
128
123
  .then(function (data) {
129
124
  // console.log(data);
130
125
  return data
@@ -133,9 +128,14 @@ export default class HttpClient {
133
128
 
134
129
  postReq(endpoint: string, variables: any) {
135
130
  const self = this
136
- return axios
137
- .post(this.baseUrl + endpoint, variables, {
138
- headers: self.createHeaders(),
131
+ return Promise.resolve() //
132
+ .then(function () {
133
+ return self.createHeaders()
134
+ })
135
+ .then(function (headers) {
136
+ return axios.post(self.baseUrl + endpoint, variables, {
137
+ headers: headers,
138
+ }) //
139
139
  }) //
140
140
  .then(function (data) {
141
141
  // console.log(data);
package/src/example.ts CHANGED
@@ -1,14 +1,16 @@
1
- import CapRoverAPI, { CapRoverModels } from './index'
1
+ import CapRoverAPI, {
2
+ CapRoverModels,
3
+ SimpleAuthenticationProvider,
4
+ } from './index'
2
5
 
3
6
  const caprover = new CapRoverAPI(
4
7
  'https://captain.server.demo.caprover.com',
5
- () => {
6
- // get password and otp from user
8
+ new SimpleAuthenticationProvider(() => {
7
9
  return Promise.resolve({
8
10
  password: 'captain42',
9
11
  otpToken: undefined,
10
12
  })
11
- }
13
+ })
12
14
  )
13
15
 
14
16
  console.log('===============================================')
package/src/index.ts CHANGED
@@ -1,5 +1,15 @@
1
1
  import CapRoverAPI from './api/ApiManager'
2
2
  import * as CapRoverModels from './models'
3
+ import {
4
+ AuthenticationContent,
5
+ SimpleAuthenticationProvider,
6
+ AuthenticationProvider,
7
+ } from './api/ApiManager'
3
8
 
4
9
  export default CapRoverAPI
5
10
  export { CapRoverModels }
11
+ export {
12
+ AuthenticationContent,
13
+ SimpleAuthenticationProvider,
14
+ AuthenticationProvider,
15
+ }