lhisp-oauth-client 1.0.11 → 1.0.14

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.
@@ -16,18 +16,18 @@ const axios_1 = __importDefault(require("axios"));
16
16
  const lhisp_oauth_client_1 = require("../src/lhisp-oauth-client");
17
17
  const lhisp_oauth_client_t_1 = require("../src/lhisp-oauth-client.t");
18
18
  // Mock jest and set the type
19
- jest.mock('axios');
19
+ jest.mock("axios");
20
20
  const mockedAxios = axios_1.default;
21
21
  const apiUrl = "https://myapi.com";
22
22
  const authUrl = "https://auth.myapi.com/oauth/token";
23
23
  const clientId = "testClientdId";
24
24
  const clientSecret = "testClientSecret";
25
25
  const baseClientParams = { apiUrl, authUrl, clientId, clientSecret };
26
- const basicAuth = `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`;
27
- const contentTypeApplicationJson = "application/json";
28
- const contentTypeApplicationXFormUrlEncoded = "application/x-www-form-urlencoded";
29
- const defaultGrantValue = 'client_credentials';
30
- const defaultGrantType = `{"grant_type":"${defaultGrantValue}"}`;
26
+ const basicAuth = `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString("base64")}`;
27
+ const contentTypeApplicationJson = lhisp_oauth_client_t_1.ContentType.APPLICATION_JSON;
28
+ const contentTypeApplicationXFormUrlEncoded = lhisp_oauth_client_t_1.ContentType.APPLICATION_X_WWW_FORM_URLENCODED;
29
+ const defaultGrantValue = "client_credentials";
30
+ const defaultGrantType = `grant_type=${defaultGrantValue}`;
31
31
  describe("Get Access Token", () => {
32
32
  beforeEach(() => {
33
33
  mockedAxios.request.mockReset();
@@ -39,116 +39,128 @@ describe("Get Access Token", () => {
39
39
  validateDefaultGetAccessToken();
40
40
  }));
41
41
  it("Shoud Get with Custom Auth Header", () => __awaiter(void 0, void 0, void 0, function* () {
42
- const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { authHeaderName: 'CustomAuthorizationHeader' }));
42
+ const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { authHeaderName: "CustomAuthorizationHeader" }));
43
43
  yield accessTokenValidator(cli);
44
44
  expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
45
45
  url: authUrl,
46
46
  method: "POST",
47
47
  headers: {
48
48
  CustomAuthorizationHeader: basicAuth,
49
- 'Content-Type': contentTypeApplicationJson,
49
+ "Content-Type": contentTypeApplicationXFormUrlEncoded,
50
50
  },
51
51
  data: defaultGrantType,
52
52
  }));
53
53
  }));
54
54
  it("Shoud Get with Custom Grant Type", () => __awaiter(void 0, void 0, void 0, function* () {
55
- const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { grantType: 'PermissaoCustom' }));
55
+ const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { grantType: "PermissaoCustom" }));
56
56
  yield accessTokenValidator(cli);
57
57
  expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
58
58
  url: authUrl,
59
59
  method: "POST",
60
60
  headers: {
61
61
  Authorization: basicAuth,
62
- 'Content-Type': contentTypeApplicationJson,
62
+ "Content-Type": contentTypeApplicationXFormUrlEncoded,
63
63
  },
64
- data: '{"grant_type":"PermissaoCustom"}',
64
+ data: "grant_type=PermissaoCustom",
65
65
  }));
66
66
  }));
67
67
  it("Shoud Get with Custom Auth Scope", () => __awaiter(void 0, void 0, void 0, function* () {
68
- const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { authScope: 'EscopoCustom' }));
68
+ const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { authScope: "EscopoCustom" }));
69
69
  yield accessTokenValidator(cli);
70
70
  expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
71
71
  url: authUrl,
72
72
  method: "POST",
73
73
  headers: {
74
74
  Authorization: basicAuth,
75
- 'Content-Type': contentTypeApplicationJson,
75
+ "Content-Type": contentTypeApplicationXFormUrlEncoded,
76
76
  },
77
- data: `{"grant_type":"${defaultGrantValue}","scope":"EscopoCustom"}`,
77
+ data: `grant_type=${defaultGrantValue}&scope=EscopoCustom`,
78
78
  }));
79
79
  }));
80
80
  it("Shoud Get with Credentials on Request body", () => __awaiter(void 0, void 0, void 0, function* () {
81
- const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { sendAuthCredentialsOnRequestBody: true }));
81
+ const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { authContentType: contentTypeApplicationJson, sendAuthCredentialsOnRequestBody: true }));
82
82
  yield accessTokenValidator(cli);
83
83
  expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
84
84
  url: authUrl,
85
85
  method: "POST",
86
86
  headers: {
87
87
  Authorization: basicAuth,
88
- 'Content-Type': contentTypeApplicationJson,
88
+ "Content-Type": contentTypeApplicationJson,
89
89
  },
90
90
  data: `{"grant_type":"${defaultGrantValue}","client_id":"${clientId}","client_secret":"${clientSecret}"}`,
91
91
  }));
92
92
  }));
93
+ it("Shoud Get with Credentials without ContentType", () => __awaiter(void 0, void 0, void 0, function* () {
94
+ const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { disableAuthContentType: true }));
95
+ yield accessTokenValidator(cli);
96
+ expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
97
+ url: authUrl,
98
+ method: "POST",
99
+ headers: {
100
+ Authorization: basicAuth,
101
+ },
102
+ data: `grant_type=${defaultGrantValue}`,
103
+ }));
104
+ }));
93
105
  });
94
106
  describe("Request", () => {
95
107
  beforeEach(() => {
96
108
  mockedAxios.request.mockReset();
97
109
  mockedAxios.request.mockResolvedValueOnce({ data: mockedAccessToken });
98
- mockedAxios.request.mockResolvedValueOnce({ data: { "status": "ok" } });
110
+ mockedAxios.request.mockResolvedValueOnce({ data: { status: "ok" } });
99
111
  });
100
112
  it("Get without Params", () => __awaiter(void 0, void 0, void 0, function* () {
101
113
  const cli = getOauthClient();
102
- const resp = yield cli.get({ path: '/my-test-url' });
114
+ const resp = yield cli.get({ path: "/my-test-url" });
103
115
  validateDefaultGetAccessToken();
104
116
  expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
105
117
  url: `${apiUrl}/my-test-url`,
106
118
  method: "GET",
107
119
  headers: {
108
120
  Authorization: `Bearer SomeAccessToken`,
109
- 'Content-Type': contentTypeApplicationJson,
121
+ "Content-Type": contentTypeApplicationJson,
110
122
  },
111
- data: undefined
123
+ data: undefined,
112
124
  }));
113
- expect(resp).toStrictEqual({ "status": "ok" });
125
+ expect(resp).toStrictEqual({ status: "ok" });
114
126
  }));
115
127
  it("Get with Params", () => __awaiter(void 0, void 0, void 0, function* () {
116
128
  const cli = getOauthClient();
117
- const resp = yield cli.get({ path: '/my-test-url', params: { id: 1 } });
129
+ const resp = yield cli.get({ path: "/my-test-url", params: { id: 1 } });
118
130
  validateDefaultGetAccessToken();
119
131
  expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
120
132
  url: `${apiUrl}/my-test-url`,
121
133
  method: "GET",
122
134
  headers: {
123
135
  Authorization: `Bearer SomeAccessToken`,
124
- 'Content-Type': contentTypeApplicationJson,
136
+ "Content-Type": contentTypeApplicationJson,
125
137
  },
126
138
  params: { id: 1 },
127
- data: undefined
139
+ data: undefined,
128
140
  }));
129
- expect(resp).toStrictEqual({ "status": "ok" });
141
+ expect(resp).toStrictEqual({ status: "ok" });
130
142
  }));
131
143
  it("Post", () => __awaiter(void 0, void 0, void 0, function* () {
132
144
  const cli = getOauthClient();
133
- const resp = yield cli.post({ path: '/my-test-url-post', data: { id: 1, user: 'test' } });
145
+ const resp = yield cli.post({ path: "/my-test-url-post", data: { id: 1, user: "test" } });
134
146
  validateDefaultGetAccessToken();
135
147
  expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
136
148
  url: `${apiUrl}/my-test-url-post`,
137
149
  method: "POST",
138
150
  headers: {
139
151
  Authorization: `Bearer SomeAccessToken`,
140
- 'Content-Type': contentTypeApplicationJson,
152
+ "Content-Type": contentTypeApplicationJson,
141
153
  },
142
- data: { id: 1, user: 'test' }
154
+ data: { id: 1, user: "test" },
143
155
  }));
144
- expect(resp).toStrictEqual({ "status": "ok" });
156
+ expect(resp).toStrictEqual({ status: "ok" });
145
157
  }));
146
158
  it("Post with different contentType", () => __awaiter(void 0, void 0, void 0, function* () {
147
159
  const cli = getOauthClient();
148
160
  const resp = yield cli.post({
149
- path: '/my-test-url-post',
150
- data: { id: 1, user: 'test' },
151
- contentType: lhisp_oauth_client_t_1.ContentType.APPLICATION_X_WWW_FORM_URLENCODED
161
+ path: "/my-test-url-post",
162
+ data: { id: 1, user: "test" },
163
+ contentType: lhisp_oauth_client_t_1.ContentType.APPLICATION_X_WWW_FORM_URLENCODED,
152
164
  });
153
165
  validateDefaultGetAccessToken();
154
166
  expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
@@ -156,30 +168,30 @@ describe("Request", () => {
156
168
  method: "POST",
157
169
  headers: {
158
170
  Authorization: `Bearer SomeAccessToken`,
159
- 'Content-Type': contentTypeApplicationXFormUrlEncoded,
171
+ "Content-Type": contentTypeApplicationXFormUrlEncoded,
160
172
  },
161
- data: { id: 1, user: 'test' }
173
+ data: { id: 1, user: "test" },
162
174
  }));
163
- expect(resp).toStrictEqual({ "status": "ok" });
175
+ expect(resp).toStrictEqual({ status: "ok" });
164
176
  }));
165
177
  it("Post with Different Token Header Name", () => __awaiter(void 0, void 0, void 0, function* () {
166
178
  const cli = getOauthClient(Object.assign(Object.assign({}, baseClientParams), { tokenHeaderName: "x-token" }));
167
179
  const resp = yield cli.post({
168
- path: '/my-test-url-post',
169
- data: { id: 1, user: 'test' },
170
- contentType: lhisp_oauth_client_t_1.ContentType.APPLICATION_X_WWW_FORM_URLENCODED
180
+ path: "/my-test-url-post",
181
+ data: { id: 1, user: "test" },
182
+ contentType: lhisp_oauth_client_t_1.ContentType.APPLICATION_X_WWW_FORM_URLENCODED,
171
183
  });
172
184
  validateDefaultGetAccessToken();
173
185
  expect(mockedAxios.request).toBeCalledWith(expect.objectContaining({
174
186
  url: `${apiUrl}/my-test-url-post`,
175
187
  method: "POST",
176
188
  headers: {
177
- 'x-token': `Bearer SomeAccessToken`,
178
- 'Content-Type': contentTypeApplicationXFormUrlEncoded,
189
+ "x-token": `Bearer SomeAccessToken`,
190
+ "Content-Type": contentTypeApplicationXFormUrlEncoded,
179
191
  },
180
- data: { id: 1, user: 'test' }
192
+ data: { id: 1, user: "test" },
181
193
  }));
182
- expect(resp).toStrictEqual({ "status": "ok" });
194
+ expect(resp).toStrictEqual({ status: "ok" });
183
195
  }));
184
196
  });
185
197
  function validateDefaultGetAccessToken() {
@@ -188,7 +200,7 @@ function validateDefaultGetAccessToken() {
188
200
  method: "POST",
189
201
  headers: {
190
202
  Authorization: basicAuth,
191
- 'Content-Type': contentTypeApplicationJson,
203
+ "Content-Type": contentTypeApplicationXFormUrlEncoded,
192
204
  },
193
205
  data: defaultGrantType,
194
206
  }));
@@ -202,7 +214,6 @@ function accessTokenValidator(cli) {
202
214
  expect(accessToken.access_token).toBe(mockedAccessToken.access_token);
203
215
  expect(accessToken.expires_in).toBe(mockedAccessToken.expires_in);
204
216
  expect(accessToken.scope).toBe(mockedAccessToken.scope);
205
- expect(accessToken.created_at).toBeGreaterThanOrEqual(now);
206
217
  });
207
218
  }
208
219
  function getOauthClient(opt = baseClientParams) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lhisp-oauth-client",
3
- "version": "1.0.11",
3
+ "version": "1.0.14",
4
4
  "main": "src/index",
5
5
  "types": "src/index.d.ts",
6
6
  "repository": "git@bitbucket.org:leandro_costa/lhisp-oauth-client.git",
package/src/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './lhisp-oauth-client';
2
- export * from './lhisp-oauth-client.t';
1
+ export * from "./lhisp-oauth-client";
2
+ export * from "./lhisp-oauth-client.t";
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import https from "https";
3
3
  import { AccessToken, ContentType, ExecutarRequestParams, LhispOauthClientConstructorParams } from "./lhisp-oauth-client.t";
4
- export declare class LhispOauthClient {
4
+ export declare class LhispOauthClient<iAccessToken extends AccessToken = AccessToken> {
5
5
  protected authUrl: string;
6
6
  protected apiUrl: string;
7
7
  protected clientId: string;
@@ -9,14 +9,17 @@ export declare class LhispOauthClient {
9
9
  protected authHeaderName: string;
10
10
  protected tokenHeaderName: string;
11
11
  protected authContentType: ContentType;
12
+ protected disableAuthContentType: boolean;
12
13
  protected certificado?: string;
13
14
  protected senhaCertificado?: string;
14
15
  protected authScope?: string;
15
16
  protected headers?: Headers;
16
17
  protected grantType?: string;
17
18
  protected agent: https.Agent;
18
- protected accessToken?: AccessToken;
19
- protected refreshToken?: AccessToken;
19
+ protected accessToken?: iAccessToken;
20
+ protected refreshToken?: iAccessToken;
21
+ protected tokenCreatedAt: number;
22
+ protected tokenExpiresIn: number;
20
23
  protected sendAuthCredentialsOnRequestBody?: boolean;
21
24
  constructor(params: LhispOauthClientConstructorParams);
22
25
  getAuthHeaderValue(): string;
@@ -24,9 +27,9 @@ export declare class LhispOauthClient {
24
27
  data: any;
25
28
  contentType: string;
26
29
  }): string | undefined;
27
- isTokenValid(token: AccessToken): boolean;
28
- getAccessToken(): Promise<AccessToken>;
29
- buildAccessToken(data: Omit<AccessToken, "created_at">): AccessToken;
30
+ isTokenValid(): boolean;
31
+ getAccessToken(): Promise<iAccessToken>;
32
+ buildAccessToken(data: any): iAccessToken;
30
33
  getAuthToken(): string;
31
34
  executarRequest<ResponseType>({ method, path, data, params, contentType, }: ExecutarRequestParams): Promise<ResponseType>;
32
35
  get<ResponseType>({ path, contentType, params }: ExecutarRequestParams): Promise<ResponseType>;
@@ -20,6 +20,9 @@ const lhisp_oauth_client_t_1 = require("./lhisp-oauth-client.t");
20
20
  const lhisp_logger_1 = __importDefault(require("lhisp-logger"));
21
21
  class LhispOauthClient {
22
22
  constructor(params) {
23
+ this.disableAuthContentType = false;
24
+ this.tokenCreatedAt = 0;
25
+ this.tokenExpiresIn = 0;
23
26
  if (params.certificado) {
24
27
  this.agent = new https_1.default.Agent({
25
28
  pfx: params.certificado,
@@ -39,6 +42,7 @@ class LhispOauthClient {
39
42
  this.authScope = params.authScope;
40
43
  this.grantType = params.grantType || lhisp_oauth_client_t_1.defaultGrantType;
41
44
  this.authContentType = params.authContentType || lhisp_oauth_client_t_1.defaultAuthContentType;
45
+ this.disableAuthContentType = Boolean(params.disableAuthContentType);
42
46
  this.clientId = params.clientId;
43
47
  this.clientSecret = params.clientSecret;
44
48
  this.authHeaderName = params.authHeaderName || lhisp_oauth_client_t_1.defaultAuthHeaderName;
@@ -60,18 +64,19 @@ class LhispOauthClient {
60
64
  throw new Error(`Content Type Inválido: [${contentType}]`);
61
65
  }
62
66
  }
63
- isTokenValid(token) {
64
- if (!token)
67
+ isTokenValid() {
68
+ if (!this.accessToken)
65
69
  return false;
66
- if (!token.created_at)
70
+ if (!this.tokenCreatedAt)
67
71
  return false;
68
- const timeDiff = (Date.now() - token.created_at) / 1000;
69
- return timeDiff < token.expires_in - 10;
72
+ const timeDiff = (Date.now() - this.tokenCreatedAt) / 1000;
73
+ return timeDiff < this.tokenExpiresIn - 10;
70
74
  }
71
75
  getAccessToken() {
76
+ var _a;
72
77
  return __awaiter(this, void 0, void 0, function* () {
73
78
  try {
74
- if (this.accessToken && this.isTokenValid(this.accessToken)) {
79
+ if (this.accessToken && this.isTokenValid()) {
75
80
  return this.accessToken;
76
81
  }
77
82
  // TODO: Implementar Refresh Token.
@@ -79,10 +84,7 @@ class LhispOauthClient {
79
84
  method: "POST",
80
85
  url: this.authUrl,
81
86
  httpsAgent: this.agent,
82
- headers: {
83
- [this.authHeaderName]: this.getAuthHeaderValue(),
84
- "Content-Type": this.authContentType,
85
- },
87
+ headers: Object.assign({ [this.authHeaderName]: this.getAuthHeaderValue() }, (this.disableAuthContentType ? {} : { "Content-Type": this.authContentType })),
86
88
  data: {},
87
89
  };
88
90
  if (this.grantType)
@@ -95,12 +97,12 @@ class LhispOauthClient {
95
97
  if (this.clientSecret)
96
98
  authRequestOpt.data.client_secret = this.clientSecret;
97
99
  }
98
- authRequestOpt.data = this.parseData({
99
- data: authRequestOpt.data,
100
- contentType: this.authContentType,
101
- });
102
- const response = yield axios_1.default.request(authRequestOpt);
103
- return this.buildAccessToken(response.data);
100
+ authRequestOpt.data = this.parseData({ data: authRequestOpt.data, contentType: this.authContentType });
101
+ const resp = yield axios_1.default.request(authRequestOpt);
102
+ this.accessToken = this.buildAccessToken(resp.data);
103
+ this.tokenCreatedAt = new Date().getTime();
104
+ this.tokenExpiresIn = ((_a = this.accessToken) === null || _a === void 0 ? void 0 : _a.expires_in) || this.tokenCreatedAt + 60000;
105
+ return this.accessToken;
104
106
  }
105
107
  catch (error) {
106
108
  lhisp_logger_1.default.error({ message: "LhispOauthClient.getAccessToken", error });
@@ -109,25 +111,19 @@ class LhispOauthClient {
109
111
  });
110
112
  }
111
113
  buildAccessToken(data) {
112
- this.accessToken = Object.assign(Object.assign({}, data), { created_at: Date.now() });
113
- return this.accessToken;
114
+ return data;
114
115
  }
115
116
  getAuthToken() {
116
117
  var _a, _b;
117
118
  return `${(_a = this.accessToken) === null || _a === void 0 ? void 0 : _a.token_type} ${(_b = this.accessToken) === null || _b === void 0 ? void 0 : _b.access_token}`;
118
119
  }
119
120
  executarRequest({ method, path, data, params, contentType = lhisp_oauth_client_t_1.ContentType.APPLICATION_JSON, }) {
120
- var _a;
121
121
  return __awaiter(this, void 0, void 0, function* () {
122
122
  try {
123
123
  yield this.getAccessToken();
124
- if (!((_a = this.accessToken) === null || _a === void 0 ? void 0 : _a.token_type)) {
125
- console.log("## LHOAUTH2 NO TOKEN ?:", this.accessToken);
126
- }
127
124
  let headers = {
128
125
  "Content-Type": contentType,
129
126
  [this.tokenHeaderName]: this.getAuthToken(),
130
- // ...this.headers
131
127
  };
132
128
  const response = yield axios_1.default.request({
133
129
  method,
@@ -16,6 +16,7 @@ export interface LhispOauthClientConstructorParams {
16
16
  grantType?: string;
17
17
  authContentType?: ContentType;
18
18
  sendAuthCredentialsOnRequestBody?: boolean;
19
+ disableAuthContentType?: boolean;
19
20
  debug?: boolean;
20
21
  }
21
22
  export interface ExecutarRequestParams extends AxiosRequestConfig {
@@ -27,7 +28,6 @@ export interface AccessToken {
27
28
  access_token: string;
28
29
  expires_in: number;
29
30
  scope?: string;
30
- created_at?: number;
31
31
  }
32
32
  export declare enum ContentType {
33
33
  APPLICATION_JSON = "application/json",
@@ -6,7 +6,7 @@ var ContentType;
6
6
  ContentType["APPLICATION_JSON"] = "application/json";
7
7
  ContentType["APPLICATION_X_WWW_FORM_URLENCODED"] = "application/x-www-form-urlencoded";
8
8
  })(ContentType || (exports.ContentType = ContentType = {}));
9
- exports.defaultGrantType = 'client_credentials';
9
+ exports.defaultGrantType = "client_credentials";
10
10
  exports.defaultAuthContentType = ContentType.APPLICATION_X_WWW_FORM_URLENCODED;
11
- exports.defaultAuthHeaderName = 'Authorization';
12
- exports.defaultTokenHeaderName = 'Authorization';
11
+ exports.defaultAuthHeaderName = "Authorization";
12
+ exports.defaultTokenHeaderName = "Authorization";