ken_nogi/PleasanterSystem/dbbackup/lineworks-authorize.js
Kenichiro NOGI 67cc3da6c8 up
2026-07-13 19:02:04 +09:00

95 lines
3.5 KiB
JavaScript

"use strict";
/*
* User Account認証(OAuth 2.0 認可コードフロー)の一回限りのセットアップスクリプト。
* Drive/共有ドライブAPIはService Account認証では利用できないため、実ユーザーの
* 認可を一度だけ行い、refresh_tokenを.envに保存する。以降のbackup.js実行は
* このrefresh_tokenからaccess_tokenを自動再発行する(ユーザー操作不要)。
*
* 事前準備:
* Developer Consoleの「User Account認証」欄の Redirect URL に、
* .env の LW_REDIRECT_URI と完全一致する値を登録しておくこと。
*
* 使い方:
* node lineworks-authorize.js
*/
const crypto = require("crypto");
const readline = require("readline");
const { loadEnv, updateEnvValue } = require("./lib/env");
loadEnv();
const { buildAuthorizeUrl, exchangeCodeForToken } = require("./lib/lineworksUserAuth");
function prompt(question) {
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
return new Promise((resolve) => {
rl.question(question, (answer) => {
rl.close();
resolve(answer.trim());
});
});
}
// リダイレクト後のURL全体、または code の値そのものが貼り付けられるケースの両方に対応する。
function extractCode(input) {
if (input.includes("code=")) {
try {
const url = new URL(input);
const code = url.searchParams.get("code");
if (code) return code;
} catch (_err) {
const match = input.match(/[?&]code=([^&\s]+)/);
if (match) return decodeURIComponent(match[1]);
}
}
return input;
}
async function main() {
const state = crypto.randomBytes(16).toString("hex");
const authorizeUrl = buildAuthorizeUrl({ state });
console.log("以下のURLをブラウザで開き、対象のLINE WORKSアカウントでログイン・同意してください:");
console.log("");
console.log(authorizeUrl);
console.log("");
console.log("同意後、Redirect URLへ遷移します(ページ自体が表示されなくても問題ありません)。");
console.log("遷移後のブラウザのアドレスバーのURL全体(または code= の値だけ)をコピーしてください。");
console.log("");
const input = await prompt("リダイレクト後のURL(またはcode)を貼り付けてEnter: ");
const code = extractCode(input);
if (!code) {
console.error("codeを取得できませんでした。");
process.exitCode = 1;
return;
}
console.log("アクセストークンに交換しています...");
const tokenData = await exchangeCodeForToken(code);
if (!tokenData.refresh_token) {
console.error("レスポンスに refresh_token が含まれていませんでした。");
process.exitCode = 1;
return;
}
updateEnvValue("LW_USER_REFRESH_TOKEN", tokenData.refresh_token);
console.log("");
console.log("成功しました。");
console.log(` scope: ${tokenData.scope}`);
console.log(` access_tokenの有効期限: ${tokenData.expires_in}`);
console.log(" refresh_token を .env の LW_USER_REFRESH_TOKEN に保存しました。");
console.log("");
console.log("これで 'node backup.js run' が共有ドライブへアクセスできるようになります。");
}
main().catch((err) => {
console.error(`セットアップに失敗しました: ${err.message}`);
process.exitCode = 1;
});