@motionpicture/coa-service 9.7.0-alpha.2 → 9.7.0-alpha.3

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
@@ -2,7 +2,6 @@
2
2
 
3
3
  [![npm (scoped)](https://img.shields.io/npm/v/@motionpicture/coa-service.svg)](https://www.npmjs.com/package/@motionpicture/coa-service)
4
4
  [![CircleCI](https://circleci.com/gh/motionpicture/coa-service.svg?style=shield)](https://circleci.com/gh/motionpicture/coa-service)
5
- [![Coverage Status](https://coveralls.io/repos/github/motionpicture/coa-service/badge.svg?branch=master)](https://coveralls.io/github/motionpicture/coa-service?branch=master)
6
5
  [![Known Vulnerabilities](https://snyk.io/test/github/motionpicture/coa-service/badge.svg)](https://snyk.io/test/github/motionpicture/coa-service)
7
6
  [![npm](https://img.shields.io/npm/dm/@motionpicture/coa-service.svg)](https://nodei.co/npm/@motionpicture/coa-service/)
8
7
 
@@ -1,26 +1,26 @@
1
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
- });
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
4
  };
11
5
  Object.defineProperty(exports, "__esModule", { value: true });
12
6
  exports.RefreshTokenClient = void 0;
13
- const createDebug = require("debug");
14
- const http_status_1 = require("http-status");
7
+ const debug_1 = __importDefault(require("debug"));
15
8
  // import { default as fetch } from 'node-fetch';
9
+ const httpStatus_1 = require("../httpStatus");
16
10
  const transporters_1 = require("../transporters");
17
- const debug = createDebug('coa-service:auth:refreshTokenClient');
11
+ const debug = (0, debug_1.default)('coa-service:auth:refreshTokenClient');
18
12
  const TIMEOUT = 10000;
19
13
  const MAX_NUM_TRY_REQUEST = 1;
20
14
  /**
21
15
  * リフレッシュトークン認証クライアント
22
16
  */
23
17
  class RefreshTokenClient {
18
+ /**
19
+ * アクセストークンの有効期限までの猶予時間初期値
20
+ */
21
+ static DEFAULT_SPARE_TIME_IN_MILLISECONDS = 60000;
22
+ credentials;
23
+ options;
24
24
  constructor(options) {
25
25
  this.options = options;
26
26
  this.credentials = {};
@@ -28,80 +28,73 @@ class RefreshTokenClient {
28
28
  /**
29
29
  * トークンエンドポイントからアクセストークンを取得します。
30
30
  */
31
- getTokenWithFetch() {
32
- return __awaiter(this, void 0, void 0, function* () {
33
- debug('requesting an access token...');
31
+ async getTokenWithFetch() {
32
+ debug('requesting an access token...');
33
+ try {
34
+ const params = new URLSearchParams({ refresh_token: String(this.options.refreshToken) });
35
+ const res = await fetch(`${this.options.endpoint}/token/access_token`, {
36
+ method: 'POST',
37
+ headers: {
38
+ 'Content-Type': 'application/x-www-form-urlencoded'
39
+ },
40
+ body: params,
41
+ signal: AbortSignal.timeout(TIMEOUT)
42
+ });
43
+ let body;
34
44
  try {
35
- const params = new URLSearchParams({ refresh_token: String(this.options.refreshToken) });
36
- const res = yield fetch(`${this.options.endpoint}/token/access_token`, {
37
- method: 'POST',
38
- headers: {
39
- 'Content-Type': 'application/x-www-form-urlencoded'
40
- },
41
- body: params,
42
- signal: AbortSignal.timeout(TIMEOUT)
43
- });
44
- let body;
45
- try {
46
- body = yield res.json();
47
- }
48
- catch (error) {
49
- // no op
50
- }
51
- debug('res.status:', res.status, 'body:', body);
52
- switch (res.status) {
53
- case http_status_1.OK:
54
- this.credentials = body;
55
- break;
56
- default:
57
- let err = new Error('Unexpected error occurred.');
58
- if (body !== undefined && body !== null) {
59
- if (typeof body === 'string') {
60
- err = new Error(body);
61
- }
62
- else if (typeof body.message === 'string' && body.message.length > 0) {
63
- // エラーレスポンスにメッセージがあった場合
64
- err = new Error(body.message);
65
- }
66
- else if (body.status !== undefined && body.status !== 0) {
67
- // エラーレスポンスにステータスがあった場合
68
- err = new Error(body.status);
69
- }
70
- }
71
- throw err;
72
- }
45
+ body = await res.json();
73
46
  }
74
- catch (err) {
75
- // tslint:disable-next-line:no-single-line-block-comment
76
- /* istanbul ignore next */
77
- if (err.name === 'TimeoutError') {
78
- // tslint:disable-next-line:no-console
79
- console.error('getTokenWithFetch: Timeout: It took more than 5 seconds to get the result!', err);
80
- }
81
- else if (err.name === 'AbortError') {
82
- // tslint:disable-next-line:no-console
83
- console.error('getTokenWithFetch: Fetch aborted by user action (browser stop button, closing tab, etc.', err);
84
- }
85
- else if (err.name === 'TypeError') {
86
- // tslint:disable-next-line:no-console
87
- console.error('getTokenWithFetch: AbortSignal.timeout() method is not supported', err);
88
- }
89
- else {
90
- // A network error, or some other problem.
91
- // tslint:disable-next-line:no-console
92
- console.error(`getTokenWithFetch: Error: type: ${err.name}, message: ${err.message}`, err);
47
+ catch (_error) {
48
+ // no op
49
+ }
50
+ debug('res.status:', res.status, 'body:', body);
51
+ switch (res.status) {
52
+ case httpStatus_1.status.OK:
53
+ this.credentials = body;
54
+ break;
55
+ default: {
56
+ let err = new Error('Unexpected error occurred.');
57
+ if (body !== undefined && body !== null) {
58
+ if (typeof body === 'string') {
59
+ err = new Error(body);
60
+ }
61
+ else if (typeof body.message === 'string' && body.message.length > 0) {
62
+ // エラーレスポンスにメッセージがあった場合
63
+ err = new Error(body.message);
64
+ }
65
+ else if (body.status !== undefined && body.status !== 0) {
66
+ // エラーレスポンスにステータスがあった場合
67
+ err = new Error(body.status);
68
+ }
69
+ }
70
+ throw err;
93
71
  }
94
- throw err;
95
72
  }
96
- // save in remote
97
- // tslint:disable-next-line:no-single-line-block-comment
73
+ }
74
+ catch (err) {
98
75
  /* istanbul ignore next */
99
- if (this.options.credentialsRepo !== undefined) {
100
- debug('saving in repo...', this.credentials);
101
- yield this.options.credentialsRepo.save(this.credentials);
76
+ if (err.name === 'TimeoutError') {
77
+ console.error('getTokenWithFetch: Timeout: It took more than 5 seconds to get the result!', err);
78
+ }
79
+ else if (err.name === 'AbortError') {
80
+ console.error('getTokenWithFetch: Fetch aborted by user action (browser stop button, closing tab, etc.', err);
102
81
  }
103
- return this.credentials;
104
- });
82
+ else if (err.name === 'TypeError') {
83
+ console.error('getTokenWithFetch: AbortSignal.timeout() method is not supported', err);
84
+ }
85
+ else {
86
+ // A network error, or some other problem.
87
+ console.error(`getTokenWithFetch: Error: type: ${err.name}, message: ${err.message}`, err);
88
+ }
89
+ throw err;
90
+ }
91
+ // save in remote
92
+ /* istanbul ignore next */
93
+ if (this.options.credentialsRepo !== undefined) {
94
+ debug('saving in repo...', this.credentials);
95
+ await this.options.credentialsRepo.save(this.credentials);
96
+ }
97
+ return this.credentials;
105
98
  }
106
99
  /**
107
100
  * 認証情報を手動でセットする
@@ -112,126 +105,108 @@ class RefreshTokenClient {
112
105
  /**
113
106
  * アクセストークンを更新する
114
107
  */
115
- refreshAccessToken() {
116
- return __awaiter(this, void 0, void 0, function* () {
117
- if (this.options.refreshToken === undefined) {
118
- throw new Error('No refresh token is set.');
119
- }
120
- return this.refreshToken(this.options.refreshToken);
121
- });
108
+ async refreshAccessToken() {
109
+ if (this.options.refreshToken === undefined) {
110
+ throw new Error('No refresh token is set.');
111
+ }
112
+ return this.refreshToken(this.options.refreshToken);
122
113
  }
123
114
  /**
124
115
  * 期限の切れていないアクセストークンを取得します。
125
116
  * 必要であれば更新してから取得します。
126
117
  */
127
- getAccessToken() {
128
- return __awaiter(this, void 0, void 0, function* () {
129
- // find from remote
130
- // localに存在せず、remoteに存在すれば採用
131
- // tslint:disable-next-line:no-single-line-block-comment
132
- /* istanbul ignore next */
133
- if (typeof this.credentials.access_token !== 'string') {
134
- if (this.options.credentialsRepo !== undefined) {
135
- const credentialsFromRepo = yield this.options.credentialsRepo.find();
136
- debug('credentials in repo found,', credentialsFromRepo);
137
- if (typeof (credentialsFromRepo === null || credentialsFromRepo === void 0 ? void 0 : credentialsFromRepo.access_token) === 'string') {
138
- this.credentials = credentialsFromRepo;
139
- }
140
- }
141
- }
142
- const expiredAt = this.credentials.expired_at;
143
- const spareTimeInMilliseconds = RefreshTokenClient.DEFAULT_SPARE_TIME_IN_MILLISECONDS;
144
- let isTokenExpired = true;
145
- if (expiredAt !== undefined) {
146
- // 認証情報があれば期限をチェック
147
- debug('validating existing credentials...', this.credentials, spareTimeInMilliseconds);
148
- const dateExpiredAtOfCredentials = new Date(expiredAt);
149
- const dateExpiredAtActually = new Date();
150
- dateExpiredAtActually.setMilliseconds(dateExpiredAtActually.getMilliseconds() + spareTimeInMilliseconds);
151
- if (dateExpiredAtOfCredentials.getTime() > dateExpiredAtActually.getTime()) {
152
- isTokenExpired = false;
118
+ async getAccessToken() {
119
+ // find from remote
120
+ // localに存在せず、remoteに存在すれば採用
121
+ /* istanbul ignore next */
122
+ if (typeof this.credentials.access_token !== 'string') {
123
+ if (this.options.credentialsRepo !== undefined) {
124
+ const credentialsFromRepo = await this.options.credentialsRepo.find();
125
+ debug('credentials in repo found,', credentialsFromRepo);
126
+ if (typeof credentialsFromRepo?.access_token === 'string') {
127
+ this.credentials = credentialsFromRepo;
153
128
  }
154
129
  }
155
- if (this.credentials.access_token === undefined && this.options.refreshToken === undefined) {
156
- throw new Error('No access or refresh token is set.');
130
+ }
131
+ const expiredAt = this.credentials.expired_at;
132
+ const spareTimeInMilliseconds = RefreshTokenClient.DEFAULT_SPARE_TIME_IN_MILLISECONDS;
133
+ let isTokenExpired = true;
134
+ if (expiredAt !== undefined) {
135
+ // 認証情報があれば期限をチェック
136
+ debug('validating existing credentials...', this.credentials, spareTimeInMilliseconds);
137
+ const dateExpiredAtOfCredentials = new Date(expiredAt);
138
+ const dateExpiredAtActually = new Date();
139
+ dateExpiredAtActually.setMilliseconds(dateExpiredAtActually.getMilliseconds() + spareTimeInMilliseconds);
140
+ if (dateExpiredAtOfCredentials.getTime() > dateExpiredAtActually.getTime()) {
141
+ isTokenExpired = false;
157
142
  }
158
- const shouldRefresh = (this.credentials.access_token === undefined) || isTokenExpired;
159
- if (shouldRefresh && this.options.refreshToken !== undefined) {
160
- yield this.refreshAccessToken();
161
- }
162
- return this.credentials.access_token;
163
- });
143
+ }
144
+ if (this.credentials.access_token === undefined && this.options.refreshToken === undefined) {
145
+ throw new Error('No access or refresh token is set.');
146
+ }
147
+ const shouldRefresh = (this.credentials.access_token === undefined) || isTokenExpired;
148
+ if (shouldRefresh && this.options.refreshToken !== undefined) {
149
+ await this.refreshAccessToken();
150
+ }
151
+ return this.credentials.access_token;
164
152
  }
165
153
  /**
166
154
  * APIリクエストを投げる
167
155
  * 認証エラー(401,403)であれば自動的に一度だけアクセストークンをリフレッシュします。
168
156
  */
169
- request(options, expectedStatusCodes) {
170
- return __awaiter(this, void 0, void 0, function* () {
171
- let retry = true;
172
- let result;
173
- let numberOfTry = 0;
174
- while (result === undefined) {
175
- try {
176
- numberOfTry += 1;
177
- if (numberOfTry > MAX_NUM_TRY_REQUEST) {
178
- retry = false;
179
- }
180
- options.auth = { bearer: yield this.getAccessToken() };
181
- result = yield this.makeRequest(options, expectedStatusCodes);
182
- break;
157
+ async request(options, expectedStatusCodes) {
158
+ let retry = true;
159
+ let result;
160
+ let numberOfTry = 0;
161
+ while (result === undefined) {
162
+ try {
163
+ numberOfTry += 1;
164
+ if (numberOfTry > MAX_NUM_TRY_REQUEST) {
165
+ retry = false;
183
166
  }
184
- catch (error) {
185
- // tslint:disable-next-line:no-single-line-block-comment
167
+ options.auth = { bearer: await this.getAccessToken() };
168
+ result = await this.makeRequest(options, expectedStatusCodes);
169
+ break;
170
+ }
171
+ catch (error) {
172
+ /* istanbul ignore else */
173
+ if (error instanceof Error) {
174
+ const statusCode = error.code;
186
175
  /* istanbul ignore else */
187
- if (error instanceof Error) {
188
- const statusCode = error.code;
189
- // tslint:disable-next-line:no-single-line-block-comment
190
- /* istanbul ignore else */
191
- if (statusCode === http_status_1.UNAUTHORIZED || statusCode === http_status_1.FORBIDDEN) {
192
- if (retry) {
193
- // 多くの場合、認証エラーは、トークンの期限が原因なので、一度だけリフレッシュするのは有効なはず。
194
- // リフレッシュしても同様に認証エラーの場合は、それ以外の原因で起きているのであきらめる。
195
- yield this.refreshAccessToken();
196
- continue;
197
- }
198
- else {
199
- // リトライしても認証エラーが出る状況は不可解なので、エラー出力
200
- // tslint:disable-next-line:no-console
201
- console.error('[COA service]Retried request threw an error.', error, 'credentials:', this.credentials, 'request options:', options, 'now:', new Date());
202
- }
176
+ if (statusCode === httpStatus_1.status.UNAUTHORIZED || statusCode === httpStatus_1.status.FORBIDDEN) {
177
+ if (retry) {
178
+ // 多くの場合、認証エラーは、トークンの期限が原因なので、一度だけリフレッシュするのは有効なはず。
179
+ // リフレッシュしても同様に認証エラーの場合は、それ以外の原因で起きているのであきらめる。
180
+ await this.refreshAccessToken();
181
+ continue;
182
+ }
183
+ else {
184
+ // リトライしても認証エラーが出る状況は不可解なので、エラー出力
185
+ console.error('[COA service]Retried request threw an error.', error, 'credentials:', this.credentials, 'request options:', options, 'now:', new Date());
203
186
  }
204
187
  }
205
- throw error;
206
188
  }
189
+ throw error;
207
190
  }
208
- return result;
209
- });
191
+ }
192
+ return result;
210
193
  }
211
194
  /**
212
195
  * 認証情報が適切である前提でAPIリクエストを投げる
213
196
  */
214
- makeRequest(options, expectedStatusCodes) {
215
- return __awaiter(this, void 0, void 0, function* () {
216
- const transporter = (this.options.useFetch === true)
217
- ? new transporters_1.FetchTransporter(expectedStatusCodes)
218
- : new transporters_1.FetchTransporter(expectedStatusCodes);
219
- return transporter.request(options);
220
- });
197
+ async makeRequest(options, expectedStatusCodes) {
198
+ const transporter = (this.options.useFetch === true)
199
+ ? new transporters_1.FetchTransporter(expectedStatusCodes)
200
+ : new transporters_1.FetchTransporter(expectedStatusCodes);
201
+ return transporter.request(options);
221
202
  }
222
203
  /**
223
204
  * 認証情報を更新する
224
205
  */
225
- refreshToken(__) {
226
- return __awaiter(this, void 0, void 0, function* () {
227
- debug('refreshing an access token...');
228
- // return this.getTokenWithRequest();
229
- return this.getTokenWithFetch();
230
- });
206
+ async refreshToken(__) {
207
+ debug('refreshing an access token...');
208
+ // return this.getTokenWithRequest();
209
+ return this.getTokenWithFetch();
231
210
  }
232
211
  }
233
- /**
234
- * アクセストークンの有効期限までの猶予時間初期値
235
- */
236
- RefreshTokenClient.DEFAULT_SPARE_TIME_IN_MILLISECONDS = 60000;
237
212
  exports.RefreshTokenClient = RefreshTokenClient;
@@ -0,0 +1,23 @@
1
+ declare const status: {
2
+ readonly CONTINUE: 100;
3
+ readonly OK: 200;
4
+ readonly CREATED: 201;
5
+ readonly ACCEPTED: 202;
6
+ readonly NO_CONTENT: 204;
7
+ readonly BAD_REQUEST: 400;
8
+ readonly UNAUTHORIZED: 401;
9
+ readonly FORBIDDEN: 403;
10
+ readonly NOT_FOUND: 404;
11
+ readonly METHOD_NOT_ALLOWED: 405;
12
+ readonly NOT_ACCEPTABLE: 406;
13
+ readonly PROXY_AUTHENTICATION_REQUIRED: 407;
14
+ readonly CONFLICT: 409;
15
+ readonly GONE: 410;
16
+ readonly TOO_MANY_REQUESTS: 429;
17
+ readonly INTERNAL_SERVER_ERROR: 500;
18
+ readonly NOT_IMPLEMENTED: 501;
19
+ readonly BAD_GATEWAY: 502;
20
+ readonly SERVICE_UNAVAILABLE: 503;
21
+ readonly GATEWAY_TIMEOUT: 504;
22
+ };
23
+ export { status };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.status = void 0;
4
+ const status = {
5
+ CONTINUE: 100,
6
+ OK: 200,
7
+ CREATED: 201,
8
+ ACCEPTED: 202,
9
+ NO_CONTENT: 204,
10
+ BAD_REQUEST: 400,
11
+ UNAUTHORIZED: 401,
12
+ FORBIDDEN: 403,
13
+ NOT_FOUND: 404,
14
+ METHOD_NOT_ALLOWED: 405,
15
+ NOT_ACCEPTABLE: 406,
16
+ PROXY_AUTHENTICATION_REQUIRED: 407,
17
+ CONFLICT: 409,
18
+ GONE: 410,
19
+ TOO_MANY_REQUESTS: 429,
20
+ INTERNAL_SERVER_ERROR: 500,
21
+ NOT_IMPLEMENTED: 501,
22
+ BAD_GATEWAY: 502,
23
+ SERVICE_UNAVAILABLE: 503,
24
+ GATEWAY_TIMEOUT: 504
25
+ };
26
+ exports.status = status;
package/lib/index.js CHANGED
@@ -1,4 +1,27 @@
1
1
  "use strict";
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.service = exports.auth = exports.factory = exports.COAServiceError = void 0;
4
27
  /**
@@ -7,7 +30,7 @@ exports.service = exports.auth = exports.factory = exports.COAServiceError = voi
7
30
  const factory_1 = require("@coasystems/factory");
8
31
  Object.defineProperty(exports, "factory", { enumerable: true, get: function () { return factory_1.COAFactory; } });
9
32
  const refreshTokenClient_1 = require("./auth/refreshTokenClient");
10
- const CredentialsRepo = require("./auth/repo/credentials");
33
+ const CredentialsRepo = __importStar(require("./auth/repo/credentials"));
11
34
  const master_1 = require("./service/master");
12
35
  const reserve_1 = require("./service/reserve");
13
36
  const coaServiceError_1 = require("./transporter/coaServiceError");
@@ -24,7 +47,7 @@ var auth;
24
47
  (function (repo) {
25
48
  repo.credentials = CredentialsRepo;
26
49
  })(repo = auth.repo || (auth.repo = {}));
27
- })(auth = exports.auth || (exports.auth = {}));
50
+ })(auth || (exports.auth = auth = {}));
28
51
  var service;
29
52
  (function (service) {
30
53
  /**
@@ -39,4 +62,4 @@ var service;
39
62
  class Reserve extends reserve_1.ReserveService {
40
63
  }
41
64
  service.Reserve = Reserve;
42
- })(service = exports.service || (exports.service = {}));
65
+ })(service || (exports.service = service = {}));