@vtecx/vtecxnext 1.0.3 → 1.0.5
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/vtecxnext.d.ts +79 -1
- package/dist/vtecxnext.js +604 -22
- package/package.json +3 -1
package/dist/vtecxnext.d.ts
CHANGED
|
@@ -388,7 +388,8 @@ export declare const getBQ: (req: IncomingMessage, res: ServerResponse, sql: str
|
|
|
388
388
|
*/
|
|
389
389
|
export declare const getBQCsv: (req: IncomingMessage, res: ServerResponse, sql: string, values?: any[], filename?: string, parent?: string) => Promise<boolean>;
|
|
390
390
|
/**
|
|
391
|
-
* Create PDF
|
|
391
|
+
* Create PDF.
|
|
392
|
+
* Writes a PDF to the response.
|
|
392
393
|
* @param req request (for authentication)
|
|
393
394
|
* @param res response
|
|
394
395
|
* @param htmlTemplate PDF layout
|
|
@@ -629,6 +630,83 @@ export declare const deleteuser: (req: IncomingMessage, res: ServerResponse, acc
|
|
|
629
630
|
* @return message feed
|
|
630
631
|
*/
|
|
631
632
|
export declare const deleteusers: (req: IncomingMessage, res: ServerResponse, feed: any) => Promise<any>;
|
|
633
|
+
/**
|
|
634
|
+
* save files
|
|
635
|
+
* @param req request
|
|
636
|
+
* @param res respose (for authentication)
|
|
637
|
+
* @param uri key
|
|
638
|
+
* @returns message
|
|
639
|
+
*/
|
|
640
|
+
export declare const savefiles: (req: IncomingMessage, res: ServerResponse, uri: string) => Promise<any>;
|
|
641
|
+
/**
|
|
642
|
+
* upload content
|
|
643
|
+
* @param req request (for authentication)
|
|
644
|
+
* @param res response (for authentication)
|
|
645
|
+
* @param uri key
|
|
646
|
+
* @return message
|
|
647
|
+
*/
|
|
648
|
+
export declare const putcontent: (req: IncomingMessage, res: ServerResponse, uri: string) => Promise<any>;
|
|
649
|
+
/**
|
|
650
|
+
* delete content
|
|
651
|
+
* @param req request (for authentication)
|
|
652
|
+
* @param res response (for authentication)
|
|
653
|
+
* @param uri key
|
|
654
|
+
* @return message
|
|
655
|
+
*/
|
|
656
|
+
export declare const deletecontent: (req: IncomingMessage, res: ServerResponse, uri: string) => Promise<any>;
|
|
657
|
+
/**
|
|
658
|
+
* get content.
|
|
659
|
+
* Writes a content to the response.
|
|
660
|
+
* @param req request (for authentication)
|
|
661
|
+
* @param res response (for authentication)
|
|
662
|
+
* @param uri key
|
|
663
|
+
* @return true
|
|
664
|
+
*/
|
|
665
|
+
export declare const getcontent: (req: IncomingMessage, res: ServerResponse, uri: string) => Promise<boolean>;
|
|
666
|
+
/**
|
|
667
|
+
* add acl
|
|
668
|
+
* @param req request (for authentication)
|
|
669
|
+
* @param res response (for authentication)
|
|
670
|
+
* @param feed entries
|
|
671
|
+
* @return message
|
|
672
|
+
*/
|
|
673
|
+
export declare const addacl: (req: IncomingMessage, res: ServerResponse, feed: any) => Promise<any>;
|
|
674
|
+
/**
|
|
675
|
+
* remove acl
|
|
676
|
+
* @param req request (for authentication)
|
|
677
|
+
* @param res response (for authentication)
|
|
678
|
+
* @param feed entries
|
|
679
|
+
* @return message
|
|
680
|
+
*/
|
|
681
|
+
export declare const removeacl: (req: IncomingMessage, res: ServerResponse, feed: any) => Promise<any>;
|
|
682
|
+
/**
|
|
683
|
+
* add alias
|
|
684
|
+
* @param req request (for authentication)
|
|
685
|
+
* @param res response (for authentication)
|
|
686
|
+
* @param feed entries
|
|
687
|
+
* @return message
|
|
688
|
+
*/
|
|
689
|
+
export declare const addalias: (req: IncomingMessage, res: ServerResponse, feed: any) => Promise<any>;
|
|
690
|
+
/**
|
|
691
|
+
* remove alias
|
|
692
|
+
* @param req request (for authentication)
|
|
693
|
+
* @param res response (for authentication)
|
|
694
|
+
* @param feed entries
|
|
695
|
+
* @return message
|
|
696
|
+
*/
|
|
697
|
+
export declare const removealias: (req: IncomingMessage, res: ServerResponse, feed: any) => Promise<any>;
|
|
698
|
+
/**
|
|
699
|
+
* OAuth authorization request to LINE
|
|
700
|
+
* @param req request (for authentication)
|
|
701
|
+
* @param res response (for authentication)
|
|
702
|
+
*/
|
|
703
|
+
export declare const oauthLine: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
|
|
704
|
+
/**
|
|
705
|
+
* OAuth authorization request to LINE
|
|
706
|
+
* @param req request (for authentication)
|
|
707
|
+
* @param res response (for authentication)
|
|
708
|
+
*/
|
|
709
|
+
export declare const oauthCallbackLine: (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
|
|
632
710
|
/**
|
|
633
711
|
* Error returned from vte.cx
|
|
634
712
|
*/
|
package/dist/vtecxnext.js
CHANGED
|
@@ -1,8 +1,37 @@
|
|
|
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
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
2
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
29
|
exports.deleteSignature = exports.putSignatures = exports.putSignature = exports.toPdf = exports.getBQCsv = exports.getBQ = exports.deleteBQ = exports.postBQ = exports.getPage = exports.pagination = exports.getSessionLong = exports.getSessionString = exports.getSessionEntry = exports.getSessionFeed = exports.deleteSessionLong = exports.deleteSessionString = exports.deleteSessionEntry = exports.deleteSessionFeed = exports.incrementSession = exports.setSessionLong = exports.setSessionString = exports.setSessionEntry = exports.setSessionFeed = exports.getRangeids = exports.rangeids = exports.setids = exports.getids = exports.addids = exports.allocids = exports.deleteFolder = exports.deleteEntry = exports.put = exports.post = exports.count = exports.getFeed = exports.getEntry = exports.log = exports.rxid = exports.service = exports.isLoggedin = exports.whoami = exports.account = exports.uid = exports.now = exports.logout = exports.loginWithRxid = exports.login = exports.sendMessage = exports.checkXRequestedWith = exports.hello = void 0;
|
|
4
|
-
exports.VtecxNextError = exports.deleteusers = exports.deleteuser = exports.canceluser = exports.activateusers = exports.activateuser = exports.revokeusers = exports.revokeuser = exports.userstatus = exports.changeaccount_verify = exports.changeaccount = exports.changepassByAdmin = exports.changepass = exports.passreset = exports.adduserByAdmin = exports.adduser = exports.noGroupMember = exports.leaveGroup = exports.joinGroup = exports.getMessageQueue = exports.setMessageQueue = exports.setMessageQueueStatus = exports.pushNotification = exports.sendMail = exports.checkSignature = void 0;
|
|
5
|
-
|
|
30
|
+
exports.VtecxNextError = exports.oauthCallbackLine = exports.oauthLine = exports.removealias = exports.addalias = exports.removeacl = exports.addacl = exports.getcontent = exports.deletecontent = exports.putcontent = exports.savefiles = exports.deleteusers = exports.deleteuser = exports.canceluser = exports.activateusers = exports.activateuser = exports.revokeusers = exports.revokeuser = exports.userstatus = exports.changeaccount_verify = exports.changeaccount = exports.changepassByAdmin = exports.changepass = exports.passreset = exports.adduserByAdmin = exports.adduser = exports.noGroupMember = exports.leaveGroup = exports.joinGroup = exports.getMessageQueue = exports.setMessageQueue = exports.setMessageQueueStatus = exports.pushNotification = exports.sendMail = exports.checkSignature = void 0;
|
|
31
|
+
const sqlstring_1 = __importDefault(require("sqlstring"));
|
|
32
|
+
const formidable_1 = __importDefault(require("formidable"));
|
|
33
|
+
const fs_1 = __importDefault(require("fs"));
|
|
34
|
+
const url_1 = __importStar(require("url"));
|
|
6
35
|
/**
|
|
7
36
|
* Hello world.
|
|
8
37
|
*/
|
|
@@ -61,7 +90,7 @@ const login = async (req, res, wsse, reCaptchaToken) => {
|
|
|
61
90
|
const url = `/d/?_login${param}`;
|
|
62
91
|
const headers = { 'X-WSSE': `${wsse}` };
|
|
63
92
|
const response = await fetchVtecx(method, url, headers);
|
|
64
|
-
const feed = await response.json()
|
|
93
|
+
//const feed = await response.json()
|
|
65
94
|
// vte.cxからのset-cookieを転記
|
|
66
95
|
setCookie(response, res);
|
|
67
96
|
// レスポンスのエラーチェック
|
|
@@ -317,7 +346,7 @@ const getEntry = async (req, res, uri, targetService) => {
|
|
|
317
346
|
// vte.cxへリクエスト
|
|
318
347
|
const method = 'GET';
|
|
319
348
|
const url = `/p${uri}?e`;
|
|
320
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
349
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
321
350
|
//console.log(`[vtecxnext getEntry] response=${response}`)
|
|
322
351
|
// vte.cxからのset-cookieを転記
|
|
323
352
|
setCookie(response, res);
|
|
@@ -341,7 +370,7 @@ const getFeed = async (req, res, uri, targetService) => {
|
|
|
341
370
|
// vte.cxへリクエスト
|
|
342
371
|
const method = 'GET';
|
|
343
372
|
const url = `/p${uri}${uri.includes('?') ? '&' : '?'}f`;
|
|
344
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
373
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
345
374
|
//console.log(`[vtecxnext getFeed] response=${response}`)
|
|
346
375
|
// vte.cxからのset-cookieを転記
|
|
347
376
|
setCookie(response, res);
|
|
@@ -365,7 +394,7 @@ const count = async (req, res, uri, targetService) => {
|
|
|
365
394
|
// vte.cxへリクエスト
|
|
366
395
|
const method = 'GET';
|
|
367
396
|
const url = `/p${uri}${uri.includes('?') ? '&' : '?'}c`;
|
|
368
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
397
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
369
398
|
//console.log(`[vtecxnext count] response=${response}`)
|
|
370
399
|
// vte.cxからのset-cookieを転記
|
|
371
400
|
setCookie(response, res);
|
|
@@ -395,7 +424,7 @@ const post = async (req, res, feed, uri, targetService) => {
|
|
|
395
424
|
// vte.cxへリクエスト
|
|
396
425
|
const method = 'POST';
|
|
397
426
|
const url = `/p${uri ? uri : '/'}?e`;
|
|
398
|
-
const response = await requestVtecx(method, url, req, JSON.stringify(feed), targetService);
|
|
427
|
+
const response = await requestVtecx(method, url, req, JSON.stringify(feed), null, targetService);
|
|
399
428
|
//console.log(`[vtecxnext post] response. status=${response.status}`)
|
|
400
429
|
// vte.cxからのset-cookieを転記
|
|
401
430
|
setCookie(response, res);
|
|
@@ -426,7 +455,7 @@ const put = async (req, res, feed, isbulk, parallel, async, targetService) => {
|
|
|
426
455
|
}
|
|
427
456
|
const url = `/p/?e${additionalParam}`;
|
|
428
457
|
//console.log(`[vtecxnext put] url=${url}`)
|
|
429
|
-
const response = await requestVtecx(method, url, req, JSON.stringify(feed), targetService);
|
|
458
|
+
const response = await requestVtecx(method, url, req, JSON.stringify(feed), null, targetService);
|
|
430
459
|
//console.log(`[vtecxnext put] response. status=${response.status}`)
|
|
431
460
|
// vte.cxからのset-cookieを転記
|
|
432
461
|
setCookie(response, res);
|
|
@@ -451,7 +480,7 @@ const deleteEntry = async (req, res, uri, revision, targetService) => {
|
|
|
451
480
|
const method = 'DELETE';
|
|
452
481
|
const param = revision ? `&r=${revision}` : '';
|
|
453
482
|
const url = `/p${uri}?e${param}`;
|
|
454
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
483
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
455
484
|
//console.log(`[vtecxnext deleteEntry] response. status=${response.status}`)
|
|
456
485
|
// vte.cxからのset-cookieを転記
|
|
457
486
|
setCookie(response, res);
|
|
@@ -475,7 +504,7 @@ const deleteFolder = async (req, res, uri, async, targetService) => {
|
|
|
475
504
|
// vte.cxへリクエスト
|
|
476
505
|
const method = 'DELETE';
|
|
477
506
|
const url = `/p${uri}?_rf${async ? '&_async' : ''}`;
|
|
478
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
507
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
479
508
|
//console.log(`[vtecxnext deleteFolder] response. status=${response.status}`)
|
|
480
509
|
// vte.cxからのset-cookieを転記
|
|
481
510
|
setCookie(response, res);
|
|
@@ -500,7 +529,7 @@ const allocids = async (req, res, uri, num, targetService) => {
|
|
|
500
529
|
// vte.cxへリクエスト
|
|
501
530
|
const method = 'GET';
|
|
502
531
|
const url = `/p${uri}?_allocids=${num}`;
|
|
503
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
532
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
504
533
|
//console.log(`[vtecxnext allocids] response=${response}`)
|
|
505
534
|
// vte.cxからのset-cookieを転記
|
|
506
535
|
setCookie(response, res);
|
|
@@ -527,7 +556,7 @@ const addids = async (req, res, uri, num, targetService) => {
|
|
|
527
556
|
// vte.cxへリクエスト
|
|
528
557
|
const method = 'PUT';
|
|
529
558
|
const url = `/p${uri}?_addids=${num}`;
|
|
530
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
559
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
531
560
|
//console.log(`[vtecxnext addids] response=${response}`)
|
|
532
561
|
// vte.cxからのset-cookieを転記
|
|
533
562
|
setCookie(response, res);
|
|
@@ -552,7 +581,7 @@ const getids = async (req, res, uri, targetService) => {
|
|
|
552
581
|
// vte.cxへリクエスト
|
|
553
582
|
const method = 'GET';
|
|
554
583
|
const url = `/p${uri}?_getids`;
|
|
555
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
584
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
556
585
|
//console.log(`[vtecxnext getids] response=${response}`)
|
|
557
586
|
// vte.cxからのset-cookieを転記
|
|
558
587
|
setCookie(response, res);
|
|
@@ -579,7 +608,7 @@ const setids = async (req, res, uri, num, targetService) => {
|
|
|
579
608
|
// vte.cxへリクエスト
|
|
580
609
|
const method = 'PUT';
|
|
581
610
|
const url = `/p${uri}?_setids=${num}`;
|
|
582
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
611
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
583
612
|
//console.log(`[vtecxnext setids] response=${response}`)
|
|
584
613
|
// vte.cxからのset-cookieを転記
|
|
585
614
|
setCookie(response, res);
|
|
@@ -988,7 +1017,7 @@ const pagination = async (req, res, uri, pagerange, targetService) => {
|
|
|
988
1017
|
// vte.cxへリクエスト
|
|
989
1018
|
const method = 'GET';
|
|
990
1019
|
const url = `/p${uri}${uri.includes('?') ? '&' : '?'}_pagination=${pagerange}`;
|
|
991
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
1020
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
992
1021
|
//console.log(`[vtecxnext pagination] response=${response}`)
|
|
993
1022
|
// vte.cxからのset-cookieを転記
|
|
994
1023
|
setCookie(response, res);
|
|
@@ -1014,7 +1043,7 @@ const getPage = async (req, res, uri, num, targetService) => {
|
|
|
1014
1043
|
// vte.cxへリクエスト
|
|
1015
1044
|
const method = 'GET';
|
|
1016
1045
|
const url = `/p${uri}${uri.includes('?') ? '&' : '?'}n=${num}`;
|
|
1017
|
-
const response = await requestVtecx(method, url, req, null, targetService);
|
|
1046
|
+
const response = await requestVtecx(method, url, req, null, null, targetService);
|
|
1018
1047
|
//console.log(`[vtecxnext getPage] response=${response}`)
|
|
1019
1048
|
// vte.cxからのset-cookieを転記
|
|
1020
1049
|
setCookie(response, res);
|
|
@@ -1163,7 +1192,8 @@ const getBQCsv = async (req, res, sql, values, filename, parent) => {
|
|
|
1163
1192
|
};
|
|
1164
1193
|
exports.getBQCsv = getBQCsv;
|
|
1165
1194
|
/**
|
|
1166
|
-
* Create PDF
|
|
1195
|
+
* Create PDF.
|
|
1196
|
+
* Writes a PDF to the response.
|
|
1167
1197
|
* @param req request (for authentication)
|
|
1168
1198
|
* @param res response
|
|
1169
1199
|
* @param htmlTemplate PDF layout
|
|
@@ -1907,6 +1937,306 @@ const deleteusers = async (req, res, feed) => {
|
|
|
1907
1937
|
return await getJson(response);
|
|
1908
1938
|
};
|
|
1909
1939
|
exports.deleteusers = deleteusers;
|
|
1940
|
+
/**
|
|
1941
|
+
* save files
|
|
1942
|
+
* @param req request
|
|
1943
|
+
* @param res respose (for authentication)
|
|
1944
|
+
* @param uri key
|
|
1945
|
+
* @returns message
|
|
1946
|
+
*/
|
|
1947
|
+
const savefiles = async (req, res, uri) => {
|
|
1948
|
+
//console.log(`[vtecxnext savefiles] start. uri=${uri}`)
|
|
1949
|
+
// キー入力値チェック
|
|
1950
|
+
checkUri(uri);
|
|
1951
|
+
/* Get files using formidable */
|
|
1952
|
+
const formidableFiles = await new Promise((resolve, reject) => {
|
|
1953
|
+
const form = new formidable_1.default.IncomingForm();
|
|
1954
|
+
const files = [];
|
|
1955
|
+
form.on('file', (field, file) => {
|
|
1956
|
+
const partFile = { 'file': file, 'field': field };
|
|
1957
|
+
files.push(partFile);
|
|
1958
|
+
});
|
|
1959
|
+
form.on('end', () => resolve(files));
|
|
1960
|
+
form.on('error', err => reject(err));
|
|
1961
|
+
form.parse(req, () => {
|
|
1962
|
+
//
|
|
1963
|
+
});
|
|
1964
|
+
}).catch(e => {
|
|
1965
|
+
//console.log(e)
|
|
1966
|
+
throw new VtecxNextError(400, `${e}`);
|
|
1967
|
+
});
|
|
1968
|
+
//console.log(`[vtecxnext savefiles] formidableFiles.length=${formidableFiles ? formidableFiles.length : 0}`)
|
|
1969
|
+
if (!formidableFiles || formidableFiles.length < 1) {
|
|
1970
|
+
throw new VtecxNextError(400, `An upload file is required.`);
|
|
1971
|
+
}
|
|
1972
|
+
let contentUris = '';
|
|
1973
|
+
const promises = [];
|
|
1974
|
+
for (const formidableFile of formidableFiles) {
|
|
1975
|
+
//console.log(`[vtecxnext savefiles] formidableFile field=${formidableFile.field} filepath=${formidableFile.file.filepath} size=${formidableFile.file.size} mymetype=${formidableFile.file.mimetype} newFilename=${formidableFile.file.newFilename} originalFilename=${formidableFile.file.originalFilename}`)
|
|
1976
|
+
const fileBuffer = fs_1.default.readFileSync(formidableFile.file.filepath);
|
|
1977
|
+
fs_1.default.unlink(formidableFile.file.filepath, () => {
|
|
1978
|
+
//console.log(`[vtecxnext savefiles] fs.unlink: ${formidableFile.file.filepath}`)
|
|
1979
|
+
});
|
|
1980
|
+
// vte.cxへリクエスト
|
|
1981
|
+
const method = 'PUT';
|
|
1982
|
+
const contentUri = `${uri}${uri.endsWith('/') ? '' : '/'}${formidableFile.field}`;
|
|
1983
|
+
const url = `/p${contentUri}?_content`;
|
|
1984
|
+
const headers = { 'Content-Type': formidableFile.file.mimetype };
|
|
1985
|
+
//console.log(`[vtecxnext savefiles] request. url=${url}`)
|
|
1986
|
+
const promiseResponse = requestVtecx(method, url, req, fileBuffer, headers);
|
|
1987
|
+
promises.push(promiseResponse);
|
|
1988
|
+
// 戻り値用
|
|
1989
|
+
contentUris += `${contentUris ? ', ' : ''}${contentUri}`;
|
|
1990
|
+
}
|
|
1991
|
+
const msg = '';
|
|
1992
|
+
for (const promise of promises) {
|
|
1993
|
+
const response = await promise;
|
|
1994
|
+
//console.log(`[vtecxnext savefiles] response. status=${response.status}`)
|
|
1995
|
+
// vte.cxからのset-cookieを転記
|
|
1996
|
+
setCookie(response, res);
|
|
1997
|
+
// レスポンスのエラーチェック
|
|
1998
|
+
await checkVtecxResponse(response);
|
|
1999
|
+
}
|
|
2000
|
+
return { 'feed': { 'title': contentUris } };
|
|
2001
|
+
/* API RouteでFormDataを使用するとうまくいかなかった。(リクエスト先の受信データサイズが0になる。)
|
|
2002
|
+
const formData = new FormData()
|
|
2003
|
+
if (formidableFiles?.length) {
|
|
2004
|
+
for (const formidableFile of formidableFiles) {
|
|
2005
|
+
//console.log(`[vtecxnext savefiles] formidableFile field=${formidableFile.field} filepath=${formidableFile.file.filepath} size=${formidableFile.file.size} mymetype=${formidableFile.file.mimetype} newFilename=${formidableFile.file.newFilename} originalFilename=${formidableFile.file.originalFilename}`)
|
|
2006
|
+
|
|
2007
|
+
const buffer:Buffer = fs.readFileSync(formidableFile.file.filepath)
|
|
2008
|
+
const file:Blob = new Blob([buffer])
|
|
2009
|
+
|
|
2010
|
+
//console.log(`[vtecxnext savefiles] file.size=${file.size} file.length=${file.length} file.name=${file.name} file.type=${file.type}`)
|
|
2011
|
+
|
|
2012
|
+
formData.append(formidableFile.field, file, formidableFile.file.originalFilename ? formidableFile.file.originalFilename : undefined)
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
// vte.cxへリクエスト
|
|
2017
|
+
const method = 'POST'
|
|
2018
|
+
const url = `/p${uri}?_content`
|
|
2019
|
+
//console.log(`[vtecxnext savefiles] request. url=${url}`)
|
|
2020
|
+
const response = await requestVtecx(method, url, req, formData)
|
|
2021
|
+
//console.log(`[vtecxnext savefiles] response. status=${response.status}`)
|
|
2022
|
+
// vte.cxからのset-cookieを転記
|
|
2023
|
+
setCookie(response, res)
|
|
2024
|
+
// レスポンスのエラーチェック
|
|
2025
|
+
await checkVtecxResponse(response)
|
|
2026
|
+
return await getJson(response)
|
|
2027
|
+
*/
|
|
2028
|
+
};
|
|
2029
|
+
exports.savefiles = savefiles;
|
|
2030
|
+
/**
|
|
2031
|
+
* upload content
|
|
2032
|
+
* @param req request (for authentication)
|
|
2033
|
+
* @param res response (for authentication)
|
|
2034
|
+
* @param uri key
|
|
2035
|
+
* @return message
|
|
2036
|
+
*/
|
|
2037
|
+
const putcontent = async (req, res, uri) => {
|
|
2038
|
+
//console.log(`[vtecxnext putcontent] start. uri=${uri} content-type:${req.headers['content-type']} content-length:${req.headers['content-length']}`)
|
|
2039
|
+
// キー入力値チェック
|
|
2040
|
+
checkUri(uri);
|
|
2041
|
+
// vte.cxへリクエスト
|
|
2042
|
+
const method = 'PUT';
|
|
2043
|
+
const url = `/p${uri}?_content`;
|
|
2044
|
+
//const headers = {'Content-Type' : req.headers['content-type'], 'Content-Length' : req.headers['content-length']}
|
|
2045
|
+
const headers = { 'Content-Type': req.headers['content-type'] };
|
|
2046
|
+
const buf = await buffer(req);
|
|
2047
|
+
const response = await requestVtecx(method, url, req, buf, headers);
|
|
2048
|
+
//console.log(`[vtecxnext putcontent] response. status=${response.status}`)
|
|
2049
|
+
// vte.cxからのset-cookieを転記
|
|
2050
|
+
setCookie(response, res);
|
|
2051
|
+
// レスポンスのエラーチェック
|
|
2052
|
+
await checkVtecxResponse(response);
|
|
2053
|
+
return await getJson(response);
|
|
2054
|
+
};
|
|
2055
|
+
exports.putcontent = putcontent;
|
|
2056
|
+
/**
|
|
2057
|
+
* delete content
|
|
2058
|
+
* @param req request (for authentication)
|
|
2059
|
+
* @param res response (for authentication)
|
|
2060
|
+
* @param uri key
|
|
2061
|
+
* @return message
|
|
2062
|
+
*/
|
|
2063
|
+
const deletecontent = async (req, res, uri) => {
|
|
2064
|
+
//console.log(`[vtecxnext deletecontent] start. uri=${uri}`)
|
|
2065
|
+
// キー入力値チェック
|
|
2066
|
+
checkUri(uri);
|
|
2067
|
+
// vte.cxへリクエスト
|
|
2068
|
+
const method = 'DELETE';
|
|
2069
|
+
const url = `/p${uri}?_content`;
|
|
2070
|
+
const response = await requestVtecx(method, url, req);
|
|
2071
|
+
//console.log(`[vtecxnext deletecontent] response. status=${response.status}`)
|
|
2072
|
+
// vte.cxからのset-cookieを転記
|
|
2073
|
+
setCookie(response, res);
|
|
2074
|
+
// レスポンスのエラーチェック
|
|
2075
|
+
await checkVtecxResponse(response);
|
|
2076
|
+
return await getJson(response);
|
|
2077
|
+
};
|
|
2078
|
+
exports.deletecontent = deletecontent;
|
|
2079
|
+
/**
|
|
2080
|
+
* get content.
|
|
2081
|
+
* Writes a content to the response.
|
|
2082
|
+
* @param req request (for authentication)
|
|
2083
|
+
* @param res response (for authentication)
|
|
2084
|
+
* @param uri key
|
|
2085
|
+
* @return true
|
|
2086
|
+
*/
|
|
2087
|
+
const getcontent = async (req, res, uri) => {
|
|
2088
|
+
//console.log(`[vtecxnext getcontent] start. uri=${uri}`)
|
|
2089
|
+
// キー入力値チェック
|
|
2090
|
+
checkUri(uri);
|
|
2091
|
+
// vte.cxへリクエスト
|
|
2092
|
+
const method = 'GET';
|
|
2093
|
+
const url = `/p${uri}?_content`;
|
|
2094
|
+
const response = await requestVtecx(method, url, req);
|
|
2095
|
+
//console.log(`[vtecxnext getcontent] response. status=${response.status}`)
|
|
2096
|
+
// vte.cxからのset-cookieを転記
|
|
2097
|
+
setCookie(response, res);
|
|
2098
|
+
//console.log(`[vtecxnext getcontent] setCookie end.`)
|
|
2099
|
+
// レスポンスのエラーチェック
|
|
2100
|
+
await checkVtecxResponse(response);
|
|
2101
|
+
//console.log(`[vtecxnext getcontent] checkVtecxResponse end.`)
|
|
2102
|
+
// 戻り値
|
|
2103
|
+
const resData = await response.blob();
|
|
2104
|
+
setResponseHeaders(response, res);
|
|
2105
|
+
res.statusCode = response.status;
|
|
2106
|
+
if (response.status !== 204) {
|
|
2107
|
+
const csvData = await resData.arrayBuffer();
|
|
2108
|
+
res.end(new Uint8Array(csvData));
|
|
2109
|
+
}
|
|
2110
|
+
else {
|
|
2111
|
+
res.end();
|
|
2112
|
+
}
|
|
2113
|
+
return true;
|
|
2114
|
+
};
|
|
2115
|
+
exports.getcontent = getcontent;
|
|
2116
|
+
/**
|
|
2117
|
+
* add acl
|
|
2118
|
+
* @param req request (for authentication)
|
|
2119
|
+
* @param res response (for authentication)
|
|
2120
|
+
* @param feed entries
|
|
2121
|
+
* @return message
|
|
2122
|
+
*/
|
|
2123
|
+
const addacl = async (req, res, feed) => {
|
|
2124
|
+
//console.log('[vtecxnext addacl] start.')
|
|
2125
|
+
// 入力チェック
|
|
2126
|
+
checkNotNull(feed, 'Feed');
|
|
2127
|
+
// vte.cxへリクエスト
|
|
2128
|
+
const method = 'PUT';
|
|
2129
|
+
const url = `/d/?_addacl`;
|
|
2130
|
+
const response = await requestVtecx(method, url, req, JSON.stringify(feed));
|
|
2131
|
+
//console.log(`[vtecxnext addacl] response=${response}`)
|
|
2132
|
+
// vte.cxからのset-cookieを転記
|
|
2133
|
+
setCookie(response, res);
|
|
2134
|
+
// レスポンスのエラーチェック
|
|
2135
|
+
await checkVtecxResponse(response);
|
|
2136
|
+
// 戻り値
|
|
2137
|
+
return await getJson(response);
|
|
2138
|
+
};
|
|
2139
|
+
exports.addacl = addacl;
|
|
2140
|
+
/**
|
|
2141
|
+
* remove acl
|
|
2142
|
+
* @param req request (for authentication)
|
|
2143
|
+
* @param res response (for authentication)
|
|
2144
|
+
* @param feed entries
|
|
2145
|
+
* @return message
|
|
2146
|
+
*/
|
|
2147
|
+
const removeacl = async (req, res, feed) => {
|
|
2148
|
+
//console.log('[vtecxnext removeacl] start.')
|
|
2149
|
+
// 入力チェック
|
|
2150
|
+
checkNotNull(feed, 'Feed');
|
|
2151
|
+
// vte.cxへリクエスト
|
|
2152
|
+
const method = 'PUT';
|
|
2153
|
+
const url = `/d/?_removeacl`;
|
|
2154
|
+
const response = await requestVtecx(method, url, req, JSON.stringify(feed));
|
|
2155
|
+
//console.log(`[vtecxnext removeacl] response=${response}`)
|
|
2156
|
+
// vte.cxからのset-cookieを転記
|
|
2157
|
+
setCookie(response, res);
|
|
2158
|
+
// レスポンスのエラーチェック
|
|
2159
|
+
await checkVtecxResponse(response);
|
|
2160
|
+
// 戻り値
|
|
2161
|
+
return await getJson(response);
|
|
2162
|
+
};
|
|
2163
|
+
exports.removeacl = removeacl;
|
|
2164
|
+
/**
|
|
2165
|
+
* add alias
|
|
2166
|
+
* @param req request (for authentication)
|
|
2167
|
+
* @param res response (for authentication)
|
|
2168
|
+
* @param feed entries
|
|
2169
|
+
* @return message
|
|
2170
|
+
*/
|
|
2171
|
+
const addalias = async (req, res, feed) => {
|
|
2172
|
+
//console.log('[vtecxnext addalias] start.')
|
|
2173
|
+
// 入力チェック
|
|
2174
|
+
checkNotNull(feed, 'Feed');
|
|
2175
|
+
// vte.cxへリクエスト
|
|
2176
|
+
const method = 'PUT';
|
|
2177
|
+
const url = `/d/?_addalias`;
|
|
2178
|
+
const response = await requestVtecx(method, url, req, JSON.stringify(feed));
|
|
2179
|
+
//console.log(`[vtecxnext addalias] response=${response}`)
|
|
2180
|
+
// vte.cxからのset-cookieを転記
|
|
2181
|
+
setCookie(response, res);
|
|
2182
|
+
// レスポンスのエラーチェック
|
|
2183
|
+
await checkVtecxResponse(response);
|
|
2184
|
+
// 戻り値
|
|
2185
|
+
return await getJson(response);
|
|
2186
|
+
};
|
|
2187
|
+
exports.addalias = addalias;
|
|
2188
|
+
/**
|
|
2189
|
+
* remove alias
|
|
2190
|
+
* @param req request (for authentication)
|
|
2191
|
+
* @param res response (for authentication)
|
|
2192
|
+
* @param feed entries
|
|
2193
|
+
* @return message
|
|
2194
|
+
*/
|
|
2195
|
+
const removealias = async (req, res, feed) => {
|
|
2196
|
+
//console.log('[vtecxnext removealias] start.')
|
|
2197
|
+
// 入力チェック
|
|
2198
|
+
checkNotNull(feed, 'Feed');
|
|
2199
|
+
// vte.cxへリクエスト
|
|
2200
|
+
const method = 'PUT';
|
|
2201
|
+
const url = `/d/?_removealias`;
|
|
2202
|
+
const response = await requestVtecx(method, url, req, JSON.stringify(feed));
|
|
2203
|
+
//console.log(`[vtecxnext removealias] response=${response}`)
|
|
2204
|
+
// vte.cxからのset-cookieを転記
|
|
2205
|
+
setCookie(response, res);
|
|
2206
|
+
// レスポンスのエラーチェック
|
|
2207
|
+
await checkVtecxResponse(response);
|
|
2208
|
+
// 戻り値
|
|
2209
|
+
return await getJson(response);
|
|
2210
|
+
};
|
|
2211
|
+
exports.removealias = removealias;
|
|
2212
|
+
/**
|
|
2213
|
+
* OAuth authorization request to LINE
|
|
2214
|
+
* @param req request (for authentication)
|
|
2215
|
+
* @param res response (for authentication)
|
|
2216
|
+
*/
|
|
2217
|
+
const oauthLine = async (req, res) => {
|
|
2218
|
+
const provider = 'line';
|
|
2219
|
+
const oauthUrl = 'https://access.line.me/oauth2/v2.1/authorize';
|
|
2220
|
+
return await oauth(req, res, provider, oauthUrl);
|
|
2221
|
+
};
|
|
2222
|
+
exports.oauthLine = oauthLine;
|
|
2223
|
+
/**
|
|
2224
|
+
* OAuth authorization request to LINE
|
|
2225
|
+
* @param req request (for authentication)
|
|
2226
|
+
* @param res response (for authentication)
|
|
2227
|
+
*/
|
|
2228
|
+
const oauthCallbackLine = async (req, res) => {
|
|
2229
|
+
// OAuthアクセストークン、OAuth情報を取得
|
|
2230
|
+
const provider = 'line';
|
|
2231
|
+
const accesstokenUrl = 'https://api.line.me/oauth2/v2.1/token';
|
|
2232
|
+
const oauthInfo = await oauthGetAccesstoken(req, res, provider, accesstokenUrl);
|
|
2233
|
+
// ユーザ識別情報を取得
|
|
2234
|
+
const userInfo = await oauthGetUserinfoLine(req, res, oauthInfo);
|
|
2235
|
+
// vte.cxユーザと連携・ログイン
|
|
2236
|
+
await oauthLink(req, res, provider, userInfo);
|
|
2237
|
+
return true;
|
|
2238
|
+
};
|
|
2239
|
+
exports.oauthCallbackLine = oauthCallbackLine;
|
|
1910
2240
|
//---------------------------------------------
|
|
1911
2241
|
/**
|
|
1912
2242
|
* Error returned from vte.cx
|
|
@@ -1927,13 +2257,20 @@ exports.VtecxNextError = VtecxNextError;
|
|
|
1927
2257
|
* @param url サーブレットパス以降のURL
|
|
1928
2258
|
* @param req リクエスト。認証情報設定に使用。
|
|
1929
2259
|
* @param body リクエストデータ
|
|
2260
|
+
* @param additionalHeaders リクエストヘッダ追加分
|
|
1930
2261
|
* @param targetService 連携サービス名
|
|
2262
|
+
* @param mode RequestMode ("cors" | "navigate" | "no-cors" | "same-origin")
|
|
1931
2263
|
* @returns promise
|
|
1932
2264
|
*/
|
|
1933
|
-
const requestVtecx = async (method, url, req, body, targetService) => {
|
|
2265
|
+
const requestVtecx = async (method, url, req, body, additionalHeaders, targetService, mode) => {
|
|
1934
2266
|
// cookieの値をvte.cxへのリクエストヘッダに設定
|
|
1935
2267
|
const cookie = req ? req.headers['cookie'] : undefined;
|
|
1936
2268
|
const headers = cookie ? { 'Cookie': cookie } : {};
|
|
2269
|
+
if (additionalHeaders) {
|
|
2270
|
+
for (const key in additionalHeaders) {
|
|
2271
|
+
headers[key] = additionalHeaders[key];
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
1937
2274
|
if (targetService) {
|
|
1938
2275
|
// サービス連携の場合
|
|
1939
2276
|
const servicekey = process.env[`SERVICEKEY_${targetService}`];
|
|
@@ -1943,7 +2280,7 @@ const requestVtecx = async (method, url, req, body, targetService) => {
|
|
|
1943
2280
|
headers['X-SERVICEKEY'] = servicekey;
|
|
1944
2281
|
}
|
|
1945
2282
|
}
|
|
1946
|
-
return fetchVtecx(method, url, headers, body);
|
|
2283
|
+
return fetchVtecx(method, url, headers, body, mode);
|
|
1947
2284
|
};
|
|
1948
2285
|
/**
|
|
1949
2286
|
* vte.cxへリクエスト
|
|
@@ -1951,9 +2288,10 @@ const requestVtecx = async (method, url, req, body, targetService) => {
|
|
|
1951
2288
|
* @param url サーブレットパス以降のURL
|
|
1952
2289
|
* @param headers リクエストヘッダ。連想配列で指定。
|
|
1953
2290
|
* @param body リクエストデータ
|
|
2291
|
+
* @param mode RequestMode ("cors" | "navigate" | "no-cors" | "same-origin")
|
|
1954
2292
|
* @returns promise
|
|
1955
2293
|
*/
|
|
1956
|
-
const fetchVtecx = async (method, url, headers, body) => {
|
|
2294
|
+
const fetchVtecx = async (method, url, headers, body, mode) => {
|
|
1957
2295
|
//console.log(`[vtecxnext fetchVtecx] url=${process.env.VTECX_URL}${url}`)
|
|
1958
2296
|
headers['X-Requested-With'] = 'XMLHttpRequest';
|
|
1959
2297
|
const apiKey = process.env.VTECX_APIKEY;
|
|
@@ -1965,6 +2303,9 @@ const fetchVtecx = async (method, url, headers, body) => {
|
|
|
1965
2303
|
method: method,
|
|
1966
2304
|
headers: headers
|
|
1967
2305
|
};
|
|
2306
|
+
if (mode) {
|
|
2307
|
+
requestInit['mode'] = mode;
|
|
2308
|
+
}
|
|
1968
2309
|
return fetch(`${process.env.VTECX_URL}${url}`, requestInit);
|
|
1969
2310
|
};
|
|
1970
2311
|
/**
|
|
@@ -1978,6 +2319,21 @@ const setCookie = (response, res) => {
|
|
|
1978
2319
|
res.setHeader('set-cookie', setCookieVal);
|
|
1979
2320
|
}
|
|
1980
2321
|
};
|
|
2322
|
+
/**
|
|
2323
|
+
* vte.cxからのallow-originを、ブラウザへレスポンスする。
|
|
2324
|
+
* @param response vte.cxからのレスポンス
|
|
2325
|
+
* @param res ブラウザへのレスポンス
|
|
2326
|
+
*/
|
|
2327
|
+
const setAllowOrigin = (response, res) => {
|
|
2328
|
+
let val = response.headers.get('access-control-allow-origin');
|
|
2329
|
+
val ? res.setHeader('access-control-allow-origin', val) : '';
|
|
2330
|
+
val = response.headers.get('access-control-allow-methods');
|
|
2331
|
+
val ? res.setHeader('access-control-allow-methods', val) : '';
|
|
2332
|
+
val = response.headers.get('access-control-allow-headers');
|
|
2333
|
+
val ? res.setHeader('access-control-allow-headers', val) : '';
|
|
2334
|
+
val = response.headers.get('access-control-allow-credentials');
|
|
2335
|
+
val ? res.setHeader('access-control-allow-credentials', val) : '';
|
|
2336
|
+
};
|
|
1981
2337
|
/**
|
|
1982
2338
|
* vte.cxからのレスポンスヘッダを、ブラウザへレスポンスする。
|
|
1983
2339
|
* コンテンツの戻し時に使用。
|
|
@@ -2076,7 +2432,7 @@ const editBqTableNames = (tablenames) => {
|
|
|
2076
2432
|
return null;
|
|
2077
2433
|
}
|
|
2078
2434
|
let result = '';
|
|
2079
|
-
for (
|
|
2435
|
+
for (const key in tablenames) {
|
|
2080
2436
|
const value = tablenames[key];
|
|
2081
2437
|
//console.log(`[editBqTableNames] ${key}=${value}`)
|
|
2082
2438
|
result = `${result ? result + ',' : ''}${key}:${value}`;
|
|
@@ -2112,7 +2468,7 @@ const formatSql = (sql, values) => {
|
|
|
2112
2468
|
if (!values) {
|
|
2113
2469
|
return sql;
|
|
2114
2470
|
}
|
|
2115
|
-
return
|
|
2471
|
+
return sqlstring_1.default.format(sql, values);
|
|
2116
2472
|
};
|
|
2117
2473
|
/**
|
|
2118
2474
|
* linkの編集
|
|
@@ -2134,3 +2490,229 @@ const getLinks = (rel, hrefs) => {
|
|
|
2134
2490
|
//console.log(`[vtecxnext getLinks] links=${JSON.stringify(links)}`)
|
|
2135
2491
|
return links;
|
|
2136
2492
|
};
|
|
2493
|
+
/**
|
|
2494
|
+
* ストリームからバイナリデータを取得
|
|
2495
|
+
* @param readable Readable
|
|
2496
|
+
* @returns バイナリデータ
|
|
2497
|
+
*/
|
|
2498
|
+
const buffer = async (readable) => {
|
|
2499
|
+
const chunks = [];
|
|
2500
|
+
for await (const chunk of readable) {
|
|
2501
|
+
chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
|
|
2502
|
+
}
|
|
2503
|
+
return Buffer.concat(chunks);
|
|
2504
|
+
};
|
|
2505
|
+
/**
|
|
2506
|
+
* OAuth authorization request
|
|
2507
|
+
* @param req request (for authentication)
|
|
2508
|
+
* @param res response (for authentication)
|
|
2509
|
+
* @param provider OAuth provider name
|
|
2510
|
+
* @param oauthUrl OAuth authorization request url
|
|
2511
|
+
* @return true
|
|
2512
|
+
*/
|
|
2513
|
+
const oauth = async (req, res, provider, oauthUrl) => {
|
|
2514
|
+
//console.log(`[vtecxnext oauth] start. provider=${provider} oauthUrl=${oauthUrl}`)
|
|
2515
|
+
// TODO reCAPTCHAを必須とすべき。
|
|
2516
|
+
// 入力チェック
|
|
2517
|
+
checkNotNull(provider, 'OAuth provider');
|
|
2518
|
+
// vte.cxへリクエスト (state取得)
|
|
2519
|
+
const method = 'POST';
|
|
2520
|
+
const url = `/o/${provider}/create_state`;
|
|
2521
|
+
const response = await requestVtecx(method, url, req);
|
|
2522
|
+
// レスポンスのエラーチェック
|
|
2523
|
+
await checkVtecxResponse(response);
|
|
2524
|
+
// 戻り値
|
|
2525
|
+
const data = await getJson(response);
|
|
2526
|
+
// state生成
|
|
2527
|
+
if (!data || !data.feed || !data.feed.title) {
|
|
2528
|
+
throw new VtecxNextError(401, `Could not generate state.`);
|
|
2529
|
+
}
|
|
2530
|
+
//console.log(`[vtecxnext oauth] response data=${JSON.stringify(data)}`)
|
|
2531
|
+
const state = data.feed.title;
|
|
2532
|
+
const client_id = data.feed.subtitle;
|
|
2533
|
+
const redirect_uri = data.feed.link[0].___href;
|
|
2534
|
+
const origin = getOrigin(oauthUrl);
|
|
2535
|
+
// 認可リクエストリダイレクトURL生成
|
|
2536
|
+
//console.log(`[vtecxnext oauth] redirect_uri=${redirect_uri}`)
|
|
2537
|
+
//console.log(`[vtecxnext oauth] origin=${origin}`)
|
|
2538
|
+
const authorizationUrl = `${oauthUrl}?response_type=code&client_id=${client_id}&redirect_uri=${encodeURI(redirect_uri)}&state=${state}&scope=profile`;
|
|
2539
|
+
//console.log(`[vtecxnext oauth] authorizationUrl=${authorizationUrl}`)
|
|
2540
|
+
res.setHeader('Location', authorizationUrl);
|
|
2541
|
+
//res.setHeader('Access-Control-Allow-Origin', origin)
|
|
2542
|
+
//res.setHeader('Access-Control-Allow-Method', 'GET, OPTIONS')
|
|
2543
|
+
//console.log(`[vtecxnext oauth] response headers=${JSON.stringify(res.getHeaders())}`)
|
|
2544
|
+
res.writeHead(302);
|
|
2545
|
+
res.end();
|
|
2546
|
+
return true;
|
|
2547
|
+
};
|
|
2548
|
+
/**
|
|
2549
|
+
* OAuth authorization request
|
|
2550
|
+
* @param req request (for authentication)
|
|
2551
|
+
* @param res response (for authentication)
|
|
2552
|
+
* @param provider OAuth provider name
|
|
2553
|
+
* @param oauthUrl OAuth get accesstoken request url
|
|
2554
|
+
* @return {'client_id', 'client_secret', 'redirect_uri', 'state', 'access_token'}
|
|
2555
|
+
*/
|
|
2556
|
+
const oauthGetAccesstoken = async (req, res, provider, accesstokenUrl) => {
|
|
2557
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] start. provider=${provider} oauthUrl=${accesstokenUrl}`)
|
|
2558
|
+
// stateチェック
|
|
2559
|
+
const parseUrl = url_1.default.parse(req.url ? req.url : '', true);
|
|
2560
|
+
const state = parseUrl.query.state;
|
|
2561
|
+
const code = parseUrl.query.code;
|
|
2562
|
+
if (!state) {
|
|
2563
|
+
throw new VtecxNextError(401, `Could not get state on redirect.`);
|
|
2564
|
+
}
|
|
2565
|
+
if (!code) {
|
|
2566
|
+
throw new VtecxNextError(401, `Could not get code on redirect.`);
|
|
2567
|
+
}
|
|
2568
|
+
// vte.cxへリクエスト (stateチェック)
|
|
2569
|
+
const vtecxMethod = 'POST';
|
|
2570
|
+
const vtecxUrl = `/o/${provider}/check_state?state=${state}`;
|
|
2571
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] vtecxUrl=${vtecxUrl}`)
|
|
2572
|
+
const vtecxResponse = await requestVtecx(vtecxMethod, vtecxUrl, req);
|
|
2573
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] check_state response status=${vtecxResponse.status}`)
|
|
2574
|
+
// vte.cxからのset-cookieを転記
|
|
2575
|
+
setCookie(vtecxResponse, res);
|
|
2576
|
+
// レスポンスのエラーチェック
|
|
2577
|
+
await checkVtecxResponse(vtecxResponse);
|
|
2578
|
+
// 戻り値
|
|
2579
|
+
const data = await getJson(vtecxResponse);
|
|
2580
|
+
// stateチェック
|
|
2581
|
+
if (!data || !data.feed || !data.feed.title) {
|
|
2582
|
+
throw new VtecxNextError(401, `Invalid state.`);
|
|
2583
|
+
}
|
|
2584
|
+
const client_id = data.feed.subtitle;
|
|
2585
|
+
const client_secret = data.feed.rights;
|
|
2586
|
+
const redirect_uri = data.feed.link[0].___href;
|
|
2587
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] client_id=${client_id}`)
|
|
2588
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] client_secret=${client_secret}`)
|
|
2589
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] redirect_uri=${redirect_uri}`)
|
|
2590
|
+
const encodeRedirect_uri = encodeURIComponent(redirect_uri);
|
|
2591
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] encode redirect_uri=${encodeRedirect_uri}`)
|
|
2592
|
+
// アクセストークン取得URL生成
|
|
2593
|
+
const accesstokenMethod = 'POST';
|
|
2594
|
+
const accessTokenData = {
|
|
2595
|
+
'grant_type': 'authorization_code',
|
|
2596
|
+
'code': code,
|
|
2597
|
+
'redirect_uri': redirect_uri,
|
|
2598
|
+
'client_id': client_id,
|
|
2599
|
+
'client_secret': client_secret
|
|
2600
|
+
};
|
|
2601
|
+
const accesstokenBody = createURLSearchParams(accessTokenData);
|
|
2602
|
+
//const accesstokenBodyStr = `grant_type=authorization_code&code=${code}&redirect_uri=${encodeRedirect_uri}&client_id=${client_id}&client_secret=${client_secret}`
|
|
2603
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] accesstokenUrl=${accesstokenUrl}`)
|
|
2604
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] accesstokenBodyStr=${accesstokenBodyStr}`)
|
|
2605
|
+
//const accesstokenBody = Buffer.from(accesstokenBodyStr, 'utf-8')
|
|
2606
|
+
const requestInit = {
|
|
2607
|
+
body: accesstokenBody,
|
|
2608
|
+
method: accesstokenMethod
|
|
2609
|
+
};
|
|
2610
|
+
const accesstokenResponse = await fetch(accesstokenUrl, requestInit);
|
|
2611
|
+
if (accesstokenResponse.status !== 200) {
|
|
2612
|
+
const errorInfo = await accesstokenResponse.json();
|
|
2613
|
+
//console.log(`[vtecxnext oauthGetAccesstoken] Get accesstoken failed. ${JSON.stringify(errorInfo)}`)
|
|
2614
|
+
const errMsg = `${'error' in errorInfo ? errorInfo.error + '. ' : ''} ${'error_description' in errorInfo ? errorInfo.error_description : ''}`;
|
|
2615
|
+
throw new VtecxNextError(401, `Get accesstoken failed. status=${accesstokenResponse.status} ${errMsg}`);
|
|
2616
|
+
}
|
|
2617
|
+
const accesstokenInfo = await accesstokenResponse.json();
|
|
2618
|
+
const access_token = accesstokenInfo.access_token;
|
|
2619
|
+
if (!access_token) {
|
|
2620
|
+
throw new VtecxNextError(401, `Get accesstoken failed.`);
|
|
2621
|
+
}
|
|
2622
|
+
return {
|
|
2623
|
+
'client_id': client_id,
|
|
2624
|
+
'client_secret': client_secret,
|
|
2625
|
+
'redirect_uri': redirect_uri,
|
|
2626
|
+
'state': state,
|
|
2627
|
+
'access_token': access_token
|
|
2628
|
+
};
|
|
2629
|
+
};
|
|
2630
|
+
/**
|
|
2631
|
+
* OAuth get userinfo request
|
|
2632
|
+
* @param req request (for authentication)
|
|
2633
|
+
* @param res response (for authentication)
|
|
2634
|
+
* @param oauthInfo OAuth info {'client_id', 'client_secret', 'redirect_uri', 'state', 'access_token'}
|
|
2635
|
+
* @return userinfo {'guid', 'nickname', 'state'}
|
|
2636
|
+
*/
|
|
2637
|
+
const oauthGetUserinfoLine = async (req, res, oauthInfo) => {
|
|
2638
|
+
//console.log(`[vtecxnext oauthGetUserinfoLine] start. oauthInfo=${JSON.stringify(oauthInfo)}`)
|
|
2639
|
+
// LINEユーザ識別情報取得リクエスト
|
|
2640
|
+
const url = 'https://api.line.me/v2/profile';
|
|
2641
|
+
const method = 'GET';
|
|
2642
|
+
const headers = { 'Authorization': `Bearer ${oauthInfo.access_token}` };
|
|
2643
|
+
//console.log(`[vtecxnext oauthGetUserinfoLine] url=${url}`)
|
|
2644
|
+
const requestInit = {
|
|
2645
|
+
headers: headers,
|
|
2646
|
+
method: method
|
|
2647
|
+
};
|
|
2648
|
+
const response = await fetch(url, requestInit);
|
|
2649
|
+
if (response.status !== 200) {
|
|
2650
|
+
throw new VtecxNextError(401, `Get user information failed. status=${response.status}`);
|
|
2651
|
+
}
|
|
2652
|
+
const userInfo = await response.json();
|
|
2653
|
+
const guid = 'userId' in userInfo ? userInfo.userId : undefined;
|
|
2654
|
+
const nickname = 'displayName' in userInfo ? userInfo.displayName : '';
|
|
2655
|
+
if (!guid) {
|
|
2656
|
+
throw new VtecxNextError(401, `Get user information failed. `);
|
|
2657
|
+
}
|
|
2658
|
+
return {
|
|
2659
|
+
'guid': guid,
|
|
2660
|
+
'nickname': nickname,
|
|
2661
|
+
'state': oauthInfo.state
|
|
2662
|
+
};
|
|
2663
|
+
};
|
|
2664
|
+
/**
|
|
2665
|
+
* OAuth user link.
|
|
2666
|
+
* @param req request
|
|
2667
|
+
* @param res response
|
|
2668
|
+
* @param provider OAuth provider name
|
|
2669
|
+
* @param userInfo user info
|
|
2670
|
+
* @return true if log in has been successful.
|
|
2671
|
+
*/
|
|
2672
|
+
const oauthLink = async (req, res, provider, userInfo) => {
|
|
2673
|
+
//console.log(`[vtecxnext oauthLink] start. userInfo=${JSON.stringify(userInfo)}`)
|
|
2674
|
+
// OAuthリンク・ログイン
|
|
2675
|
+
// reCAPTCHA tokenは任意
|
|
2676
|
+
//const param = reCaptchaToken ? `&g-recaptcha-token=${reCaptchaToken}` : ''
|
|
2677
|
+
const param = '';
|
|
2678
|
+
const method = 'POST';
|
|
2679
|
+
const url = `/o/${provider}/link?state=${userInfo.state}${param}`;
|
|
2680
|
+
const reqFeed = [{ 'title': userInfo.guid, 'subtitle': userInfo.nickname }];
|
|
2681
|
+
const response = await fetchVtecx(method, url, {}, JSON.stringify(reqFeed));
|
|
2682
|
+
const feed = await response.json();
|
|
2683
|
+
// vte.cxからのset-cookieを転記
|
|
2684
|
+
setCookie(response, res);
|
|
2685
|
+
// レスポンスのエラーチェック
|
|
2686
|
+
let isLoggedin;
|
|
2687
|
+
if (response.status < 400) {
|
|
2688
|
+
isLoggedin = true;
|
|
2689
|
+
}
|
|
2690
|
+
else {
|
|
2691
|
+
isLoggedin = false;
|
|
2692
|
+
}
|
|
2693
|
+
//console.log(`[vtecxnext oauthLink] end. status=${response.status} message=${feed.feed.title}`)
|
|
2694
|
+
return isLoggedin;
|
|
2695
|
+
};
|
|
2696
|
+
/**
|
|
2697
|
+
* URLからOriginを取得
|
|
2698
|
+
* @param oauthUrl URL
|
|
2699
|
+
* @returns Origin
|
|
2700
|
+
*/
|
|
2701
|
+
const getOrigin = (oauthUrl) => {
|
|
2702
|
+
const tmpIdx = oauthUrl.indexOf('://') + 3;
|
|
2703
|
+
let idx = oauthUrl.indexOf('/', tmpIdx);
|
|
2704
|
+
if (idx < 0) {
|
|
2705
|
+
idx = oauthUrl.length;
|
|
2706
|
+
}
|
|
2707
|
+
return oauthUrl.substring(0, idx);
|
|
2708
|
+
};
|
|
2709
|
+
/**
|
|
2710
|
+
* URLSearchParamsを生成.
|
|
2711
|
+
* @param data JSON
|
|
2712
|
+
* @returns URLSearchParams
|
|
2713
|
+
*/
|
|
2714
|
+
const createURLSearchParams = (data) => {
|
|
2715
|
+
const params = new url_1.URLSearchParams();
|
|
2716
|
+
Object.keys(data).forEach(key => params.append(key, data[key]));
|
|
2717
|
+
return params;
|
|
2718
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vtecx/vtecxnext",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "vte.cx Next.js api",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -22,12 +22,14 @@
|
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/reflexworks/vtecxnext#readme",
|
|
24
24
|
"devDependencies": {
|
|
25
|
+
"@types/formidable": "^2.0.5",
|
|
25
26
|
"@types/node": "^18.11.17",
|
|
26
27
|
"@types/sqlstring": "^2.3.0",
|
|
27
28
|
"ts-node": "^10.9.1",
|
|
28
29
|
"typescript": "^4.9.4"
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
32
|
+
"formidable": "^2.1.1",
|
|
31
33
|
"sqlstring": "^2.3.3"
|
|
32
34
|
}
|
|
33
35
|
}
|