@vtecx/vtecxnext 1.0.4 → 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 +12 -0
- package/dist/vtecxnext.js +292 -5
- package/package.json +1 -1
package/dist/vtecxnext.d.ts
CHANGED
|
@@ -695,6 +695,18 @@ export declare const addalias: (req: IncomingMessage, res: ServerResponse, feed:
|
|
|
695
695
|
* @return message
|
|
696
696
|
*/
|
|
697
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>;
|
|
698
710
|
/**
|
|
699
711
|
* Error returned from vte.cx
|
|
700
712
|
*/
|
package/dist/vtecxnext.js
CHANGED
|
@@ -1,13 +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
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
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;
|
|
7
|
-
exports.VtecxNextError = 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;
|
|
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;
|
|
8
31
|
const sqlstring_1 = __importDefault(require("sqlstring"));
|
|
9
32
|
const formidable_1 = __importDefault(require("formidable"));
|
|
10
33
|
const fs_1 = __importDefault(require("fs"));
|
|
34
|
+
const url_1 = __importStar(require("url"));
|
|
11
35
|
/**
|
|
12
36
|
* Hello world.
|
|
13
37
|
*/
|
|
@@ -66,7 +90,7 @@ const login = async (req, res, wsse, reCaptchaToken) => {
|
|
|
66
90
|
const url = `/d/?_login${param}`;
|
|
67
91
|
const headers = { 'X-WSSE': `${wsse}` };
|
|
68
92
|
const response = await fetchVtecx(method, url, headers);
|
|
69
|
-
const feed = await response.json()
|
|
93
|
+
//const feed = await response.json()
|
|
70
94
|
// vte.cxからのset-cookieを転記
|
|
71
95
|
setCookie(response, res);
|
|
72
96
|
// レスポンスのエラーチェック
|
|
@@ -2185,6 +2209,34 @@ const removealias = async (req, res, feed) => {
|
|
|
2185
2209
|
return await getJson(response);
|
|
2186
2210
|
};
|
|
2187
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;
|
|
2188
2240
|
//---------------------------------------------
|
|
2189
2241
|
/**
|
|
2190
2242
|
* Error returned from vte.cx
|
|
@@ -2205,10 +2257,12 @@ exports.VtecxNextError = VtecxNextError;
|
|
|
2205
2257
|
* @param url サーブレットパス以降のURL
|
|
2206
2258
|
* @param req リクエスト。認証情報設定に使用。
|
|
2207
2259
|
* @param body リクエストデータ
|
|
2260
|
+
* @param additionalHeaders リクエストヘッダ追加分
|
|
2208
2261
|
* @param targetService 連携サービス名
|
|
2262
|
+
* @param mode RequestMode ("cors" | "navigate" | "no-cors" | "same-origin")
|
|
2209
2263
|
* @returns promise
|
|
2210
2264
|
*/
|
|
2211
|
-
const requestVtecx = async (method, url, req, body, additionalHeaders, targetService) => {
|
|
2265
|
+
const requestVtecx = async (method, url, req, body, additionalHeaders, targetService, mode) => {
|
|
2212
2266
|
// cookieの値をvte.cxへのリクエストヘッダに設定
|
|
2213
2267
|
const cookie = req ? req.headers['cookie'] : undefined;
|
|
2214
2268
|
const headers = cookie ? { 'Cookie': cookie } : {};
|
|
@@ -2226,7 +2280,7 @@ const requestVtecx = async (method, url, req, body, additionalHeaders, targetSer
|
|
|
2226
2280
|
headers['X-SERVICEKEY'] = servicekey;
|
|
2227
2281
|
}
|
|
2228
2282
|
}
|
|
2229
|
-
return fetchVtecx(method, url, headers, body);
|
|
2283
|
+
return fetchVtecx(method, url, headers, body, mode);
|
|
2230
2284
|
};
|
|
2231
2285
|
/**
|
|
2232
2286
|
* vte.cxへリクエスト
|
|
@@ -2234,9 +2288,10 @@ const requestVtecx = async (method, url, req, body, additionalHeaders, targetSer
|
|
|
2234
2288
|
* @param url サーブレットパス以降のURL
|
|
2235
2289
|
* @param headers リクエストヘッダ。連想配列で指定。
|
|
2236
2290
|
* @param body リクエストデータ
|
|
2291
|
+
* @param mode RequestMode ("cors" | "navigate" | "no-cors" | "same-origin")
|
|
2237
2292
|
* @returns promise
|
|
2238
2293
|
*/
|
|
2239
|
-
const fetchVtecx = async (method, url, headers, body) => {
|
|
2294
|
+
const fetchVtecx = async (method, url, headers, body, mode) => {
|
|
2240
2295
|
//console.log(`[vtecxnext fetchVtecx] url=${process.env.VTECX_URL}${url}`)
|
|
2241
2296
|
headers['X-Requested-With'] = 'XMLHttpRequest';
|
|
2242
2297
|
const apiKey = process.env.VTECX_APIKEY;
|
|
@@ -2248,6 +2303,9 @@ const fetchVtecx = async (method, url, headers, body) => {
|
|
|
2248
2303
|
method: method,
|
|
2249
2304
|
headers: headers
|
|
2250
2305
|
};
|
|
2306
|
+
if (mode) {
|
|
2307
|
+
requestInit['mode'] = mode;
|
|
2308
|
+
}
|
|
2251
2309
|
return fetch(`${process.env.VTECX_URL}${url}`, requestInit);
|
|
2252
2310
|
};
|
|
2253
2311
|
/**
|
|
@@ -2261,6 +2319,21 @@ const setCookie = (response, res) => {
|
|
|
2261
2319
|
res.setHeader('set-cookie', setCookieVal);
|
|
2262
2320
|
}
|
|
2263
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
|
+
};
|
|
2264
2337
|
/**
|
|
2265
2338
|
* vte.cxからのレスポンスヘッダを、ブラウザへレスポンスする。
|
|
2266
2339
|
* コンテンツの戻し時に使用。
|
|
@@ -2429,3 +2502,217 @@ const buffer = async (readable) => {
|
|
|
2429
2502
|
}
|
|
2430
2503
|
return Buffer.concat(chunks);
|
|
2431
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
|
+
};
|