Refactor ticket verification and installation scripts
All checks were successful
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 3s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Successful in 1m17s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Successful in 4s
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Successful in 1s
All checks were successful
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 3s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Successful in 1m17s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Successful in 4s
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Successful in 1s
- Split `verifyAddinTicket` into two functions: `verifyAddinTicketHmac` (ignores expiration) and `verifyAddinTicket` (checks expiration). - Add `hasVersionByUser` function to check if a document has been previously worked on by a user, allowing expired tickets to be accepted if the user has a history with the document. - Update OpenAPI specification to reflect changes in ticket expiration handling. - Introduce new scripts for installing and uninstalling the Word add-in on Windows and macOS, providing a streamlined process for sideloading the add-in. - Enhance tests for ticket verification to cover new functionality regarding expired tickets and user history.
This commit is contained in:
parent
3726cb742f
commit
b1449ab668
14 changed files with 727 additions and 75 deletions
246
scripts/install-wordaddin.mjs
Normal file
246
scripts/install-wordaddin.mjs
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
#!/usr/bin/env node
|
||||
// Dev tool ติดตั้ง (sideload) / ถอด Word add-in "e-Court Documents Versioning"
|
||||
// บนเครื่องทดสอบ Windows + macOS — โหลด manifest จาก server (default ตัวทดสอบ
|
||||
// ecourt-note.chamomind.com ที่ app/wordaddin/manifest.xml/route.ts rewrite origin
|
||||
// ให้ตรงโฮสต์ผู้ขออยู่แล้ว) แล้วจดทะเบียนให้ Word Desktop เห็น add-in
|
||||
//
|
||||
// กลไกตรงตาม office-addin-dev-settings@4 (อ่านจาก source ใน node_modules) แต่
|
||||
// เขียนเองด้วย node builtins ล้วน เพื่อใช้ได้ทั้งรันใน repo (npm run addin:install)
|
||||
// และ copy ไฟล์เดี่ยวนี้ไปรัน `node install-wordaddin.mjs` บนเครื่องที่ไม่มี repo:
|
||||
// - Windows: registry HKCU\Software\Microsoft\Office\16.0\Wef\Developer
|
||||
// value ชื่อ = GUID ของ add-in, REG_SZ, data = path manifest บนดิสก์ (ต้องอยู่ถาวร)
|
||||
// - macOS: วางไฟล์ <GUID>.manifest.xml ใน
|
||||
// ~/Library/Containers/com.microsoft.Word/Data/Documents/wef/ (Word สแกน *.xml ทุกไฟล์)
|
||||
//
|
||||
// ใช้: node scripts/install-wordaddin.mjs [options]
|
||||
// --url <manifest-url> default https://ecourt-note.chamomind.com/docedit/wordaddin/manifest.xml
|
||||
// (dev: https://localhost:3000/docedit/wordaddin/manifest.xml — ต้อง npm run dev:https ก่อน)
|
||||
// --remove ถอดการติดตั้ง (ไม่ต้องต่อเน็ต — ใช้ manifest ที่เก็บไว้ตอนลง)
|
||||
// --help | -h
|
||||
//
|
||||
// หลังลง/ถอดต้อง restart Word ทุกครั้ง · รายละเอียดเต็ม: docs/WORDADDIN-DEV.md
|
||||
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
const PREFIX = "[install-addin]";
|
||||
const DEFAULT_MANIFEST_URL = "https://ecourt-note.chamomind.com/docedit/wordaddin/manifest.xml";
|
||||
/** ตรงคีย์ที่ office-addin-dev-settings ใช้ (Office 2016+ ทุกรุ่นอยู่ภายใต้ 16.0) */
|
||||
const WIN_DEV_KEY = "HKCU\\Software\\Microsoft\\Office\\16.0\\Wef\\Developer";
|
||||
/** โฟลเดอร์เก็บ manifest ถาวรบน Windows — path เดียวกับที่ docs/WORDADDIN-DEV.md สอน manual */
|
||||
const winManifestDir = () => path.join(os.homedir(), "Documents", "wordaddin-manifest");
|
||||
const winManifestPath = () => path.join(winManifestDir(), "manifest.xml");
|
||||
/** โฟลเดอร์ที่ Word for Mac สแกนหา add-in ที่ sideload */
|
||||
const macWefDir = () =>
|
||||
path.join(os.homedir(), "Library", "Containers", "com.microsoft.Word", "Data", "Documents", "wef");
|
||||
|
||||
function usage(code = 1) {
|
||||
console.log(`ใช้: node scripts/install-wordaddin.mjs [options]
|
||||
--url <manifest-url> default ${DEFAULT_MANIFEST_URL}
|
||||
--remove ถอดการติดตั้ง
|
||||
--help | -h`);
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const options = { url: DEFAULT_MANIFEST_URL, remove: false };
|
||||
for (let i = 0; i < argv.length; i++) {
|
||||
const arg = argv[i];
|
||||
const next = () => {
|
||||
const value = argv[++i];
|
||||
if (value === undefined) usage();
|
||||
return value;
|
||||
};
|
||||
switch (arg) {
|
||||
case "--url": options.url = next(); break;
|
||||
case "--remove": options.remove = true; break;
|
||||
case "--help": case "-h": usage(0); break;
|
||||
default: usage();
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
function fail(message) {
|
||||
console.error(`${PREFIX} ✗ ${message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
/** โหลด manifest จาก server แล้วดึง GUID ของ add-in จาก <Id> — ไม่ hardcode เพราะเปลี่ยน environment ได้ */
|
||||
async function downloadManifest(url) {
|
||||
let response;
|
||||
try {
|
||||
response = await fetch(url, { redirect: "follow", signal: AbortSignal.timeout(30_000) });
|
||||
} catch (error) {
|
||||
fail(`โหลด manifest จาก ${url} ไม่ได้ (${error instanceof Error ? error.message : String(error)})`);
|
||||
}
|
||||
if (!response.ok) {
|
||||
fail(`server ตอบ HTTP ${response.status} จาก ${url} — เช็คว่า environment นั้นรันอยู่`);
|
||||
}
|
||||
const xml = await response.text();
|
||||
if (!xml.includes("<OfficeApp")) {
|
||||
fail(`response จาก ${url} ไม่ใช่ manifest ของ Office add-in (ไม่มี <OfficeApp)`);
|
||||
}
|
||||
const idMatch = xml.match(/<Id>([0-9a-fA-F-]{36})<\/Id>/);
|
||||
if (!idMatch) {
|
||||
fail(`หา <Id> (GUID) ใน manifest ไม่เจอจาก ${url}`);
|
||||
}
|
||||
return { xml, guid: idMatch[1].toLowerCase() };
|
||||
}
|
||||
|
||||
/** อ่าน GUID จากไฟล์ manifest ที่เก็บไว้ตอนติดตั้ง (สำหรับ --remove ที่ไม่ต้องต่อเน็ต) */
|
||||
function readStoredGuid(manifestPath) {
|
||||
try {
|
||||
const xml = readFileSync(manifestPath, "utf8");
|
||||
const idMatch = xml.match(/<Id>([0-9a-fA-F-]{36})<\/Id>/);
|
||||
return idMatch ? idMatch[1].toLowerCase() : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** reg.exe ผ่าน args array เสมอ (ไม่ใช่ shell string — path มี space ก็ไม่พัง) */
|
||||
function reg(args) {
|
||||
return spawnSync("reg", args, { encoding: "utf8" });
|
||||
}
|
||||
|
||||
function installWindows(xml, guid) {
|
||||
const dest = winManifestPath();
|
||||
mkdirSync(winManifestDir(), { recursive: true });
|
||||
writeFileSync(dest, xml);
|
||||
console.log(`${PREFIX} ✓ เก็บ manifest ไว้ที่ ${dest}`);
|
||||
|
||||
const add = reg(["add", WIN_DEV_KEY, "/v", guid, "/t", "REG_SZ", "/d", dest, "/f"]);
|
||||
if (add.status !== 0) {
|
||||
fail(`เขียน registry ไม่สำเร็จ (reg add exit ${add.status}): ${add.stderr?.trim() ?? "ไม่มี stderr"}`);
|
||||
}
|
||||
const query = reg(["query", WIN_DEV_KEY, "/v", guid]);
|
||||
if (query.status !== 0) {
|
||||
fail(`reg add สำเร็จแต่ยืนยันด้วย reg query ไม่ผ่าน (exit ${query.status})`);
|
||||
}
|
||||
console.log(`${PREFIX} ✓ จดทะเบียน add-in ใน registry (${WIN_DEV_KEY} → ${guid})`);
|
||||
return dest;
|
||||
}
|
||||
|
||||
function removeWindows() {
|
||||
const stored = winManifestPath();
|
||||
const guid = readStoredGuid(stored);
|
||||
if (!guid) {
|
||||
fail(
|
||||
`ไม่พบ manifest ที่เก็บไว้ (${stored}) จึงไม่รู้ GUID ของ add-in — ` +
|
||||
`ลบเองได้ที่ reg delete "${WIN_DEV_KEY}" /v <GUID> /f`,
|
||||
);
|
||||
}
|
||||
const del = reg(["delete", WIN_DEV_KEY, "/v", guid, "/f"]);
|
||||
if (del.status !== 0) {
|
||||
fail(`reg delete ไม่สำเร็จ (exit ${del.status}): ${del.stderr?.trim() ?? "ไม่มี stderr"}`);
|
||||
}
|
||||
try {
|
||||
unlinkSync(stored);
|
||||
} catch {
|
||||
// registry ถอดแล้ว — ไฟล์ค้างไม่ทำให้ Word เห็น add-in
|
||||
}
|
||||
console.log(`${PREFIX} ✓ ถอดการติดตั้งแล้ว (registry ${guid} + ไฟล์ ${stored})`);
|
||||
}
|
||||
|
||||
/** ไฟล์ sideload ของ GUID นี้ทั้งหมดใน wef — ทั้งของเราและชื่อ basename เก่า ๆ ที่เคยใช้ */
|
||||
function macSideloadFiles(guid) {
|
||||
const dir = macWefDir();
|
||||
try {
|
||||
return readdirSync(dir)
|
||||
.filter((name) => name === `${guid}.manifest.xml` || name.startsWith(`${guid}.`))
|
||||
.map((name) => path.join(dir, name));
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function installMac(xml, guid) {
|
||||
const dir = macWefDir();
|
||||
mkdirSync(dir, { recursive: true });
|
||||
// ลบของเก่าก่อนเขียนใหม่ — idempotent และไม่มีไฟล์ซ้ำ GUID ค้างในโฟลเดอร์
|
||||
for (const stale of macSideloadFiles(guid)) {
|
||||
try {
|
||||
unlinkSync(stale);
|
||||
} catch {
|
||||
console.warn(`${PREFIX} ⚠ ลบไฟล์เก่าไม่ได้: ${stale}`);
|
||||
}
|
||||
}
|
||||
const dest = path.join(dir, `${guid}.manifest.xml`);
|
||||
writeFileSync(dest, xml);
|
||||
console.log(`${PREFIX} ✓ วาง manifest ไว้ที่ ${dest}`);
|
||||
return dest;
|
||||
}
|
||||
|
||||
function removeMac() {
|
||||
const dir = macWefDir();
|
||||
// บน Mac ไม่มี manifest เก็บแยกที่อื่น (ตัวไฟล์ใน wef คือของที่ลงไว้) — หาทุก *.xml
|
||||
// ในโฟลเดอร์ที่เป็น manifest ของ add-in นี้จากชื่อในไฟล์เอง จึงไม่ต้อง hardcode GUID
|
||||
let files;
|
||||
try {
|
||||
files = readdirSync(dir)
|
||||
.filter((name) => name.toLowerCase().endsWith(".xml"))
|
||||
.map((name) => path.join(dir, name))
|
||||
.filter((file) => {
|
||||
try {
|
||||
const xml = readFileSync(file, "utf8");
|
||||
return xml.includes("<OfficeApp") && xml.includes("e-Court Documents Versioning");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
files = [];
|
||||
}
|
||||
if (files.length === 0) {
|
||||
console.log(`${PREFIX} ไม่พบไฟล์ sideload ของ add-in นี้ใน ${dir} — ถือว่าถอดแล้ว`);
|
||||
return;
|
||||
}
|
||||
for (const file of files) {
|
||||
unlinkSync(file);
|
||||
console.log(`${PREFIX} ✓ ลบ ${file}`);
|
||||
}
|
||||
}
|
||||
|
||||
function printNextSteps() {
|
||||
const where = process.platform === "win32" ? "Insert > My Add-ins > SHARED FOLDER" : "Insert > My Add-ins";
|
||||
console.log(`
|
||||
ขั้นต่อไป:
|
||||
1. restart Word ให้ครบทุกหน้าต่าง (จำเป็นทุกครั้งหลังลง/ถอด)
|
||||
2. ${where} > เปิด "e-Court Documents Versioning"
|
||||
3. เปิดไฟล์ .docx ที่มี ticket เพื่อทดสอบ เช่นสร้างใหม่ด้วย:
|
||||
node scripts/make-ticket-docx.mjs file.docx --fid DEMO_FID_001 --tid T12
|
||||
รายละเอียด: docs/WORDADDIN-DEV.md`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const options = parseArgs(process.argv.slice(2));
|
||||
console.log(`${PREFIX} platform: ${process.platform}${options.remove ? " · โหมดถอดการติดตั้ง" : ""}`);
|
||||
|
||||
if (process.platform === "win32") {
|
||||
if (options.remove) {
|
||||
removeWindows();
|
||||
} else {
|
||||
const { xml, guid } = await downloadManifest(options.url);
|
||||
installWindows(xml, guid);
|
||||
}
|
||||
} else if (process.platform === "darwin") {
|
||||
if (options.remove) {
|
||||
removeMac();
|
||||
} else {
|
||||
const { xml, guid } = await downloadManifest(options.url);
|
||||
installMac(xml, guid);
|
||||
}
|
||||
} else {
|
||||
fail(`รองรับเฉพาะ Windows (win32) และ macOS (darwin) — platform นี้คือ ${process.platform}`);
|
||||
}
|
||||
|
||||
console.log(`${PREFIX} ✓ เสร็จ`);
|
||||
printNextSteps();
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
fail(error instanceof Error ? error.stack ?? error.message : String(error));
|
||||
});
|
||||
92
scripts/install-wordaddin.ps1
Normal file
92
scripts/install-wordaddin.ps1
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# ติดตั้ง (sideload) / ถอด Word add-in "e-Court Documents Versioning" บน Windows
|
||||
# เวอร์ชัน PowerShell แบบส่งให้เครื่องทดสอบที่ไม่มี Node/repo — คู่หูของ
|
||||
# scripts/install-wordaddin.mjs (รันใน repo) และ scripts/install-wordaddin.sh (macOS)
|
||||
# กลไกเดียวกันทั้งสามไฟล์: โหลด manifest จาก server เก็บไว้
|
||||
# %USERPROFILE%\Documents\wordaddin-manifest\ แล้วจดทะเบียน registry
|
||||
# HKCU\Software\Microsoft\Office\16.0\Wef\Developer (กลไกเดียวกับ office-addin-dev-settings)
|
||||
#
|
||||
# ใช้: powershell -ExecutionPolicy Bypass -File install-wordaddin.ps1 [-Url <manifest-url>] [-Remove]
|
||||
# -Url default https://ecourt-note.chamomind.com/docedit/wordaddin/manifest.xml
|
||||
# -Remove ถอดการติดตั้ง
|
||||
#
|
||||
# (ไฟล์นี้ต้องมี BOM — Windows PowerShell 5.1 อ่าน UTF-8 ไม่มี BOM เป็น ANSI แล้วข้อความไทยพัง)
|
||||
# หลังลง/ถอดต้อง restart Word ทุกครั้ง · รายละเอียดเต็ม: docs/WORDADDIN-DEV.md
|
||||
|
||||
param(
|
||||
[string]$Url = "https://ecourt-note.chamomind.com/docedit/wordaddin/manifest.xml",
|
||||
[switch]$Remove
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
# ให้ console พิมพ์ไทย/✓ ถูกต้อง และบังคับ TLS 1.2 (PS 5.1 บางเครื่อง default ยังเป็น TLS 1.0)
|
||||
try { [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 } catch { }
|
||||
[Net.ServicePointManager]::SecurityProtocol = `
|
||||
[Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
$Prefix = "[install-addin]"
|
||||
$DevKeyCmd = "HKCU\Software\Microsoft\Office\16.0\Wef\Developer"
|
||||
$ManifestDir = Join-Path $env:USERPROFILE "Documents\wordaddin-manifest"
|
||||
$ManifestPath = Join-Path $ManifestDir "manifest.xml"
|
||||
|
||||
function Fail($message) {
|
||||
Write-Host "$Prefix ✗ $message" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
function Print-NextSteps {
|
||||
Write-Host ""
|
||||
Write-Host "ขั้นต่อไป:"
|
||||
Write-Host " 1. restart Word ให้ครบทุกหน้าต่าง (จำเป็นทุกครั้งหลังลง/ถอด)"
|
||||
Write-Host ' 2. Insert > My Add-ins > SHARED FOLDER > เปิด "e-Court Documents Versioning"'
|
||||
Write-Host " 3. เปิดไฟล์ .docx ที่มี ticket ของ e-Court (ขอจากทีม) เพื่อเริ่มทดสอบ"
|
||||
}
|
||||
|
||||
if ($Remove) {
|
||||
Write-Host "$Prefix platform: win32 · โหมดถอดการติดตั้ง"
|
||||
if (-not (Test-Path $ManifestPath)) {
|
||||
Fail "ไม่พบ manifest ที่เก็บไว้ ($ManifestPath) จึงไม่รู้ GUID ของ add-in — ลบเองได้ที่: reg delete `"$DevKeyCmd`" /v <GUID> /f"
|
||||
}
|
||||
$stored = Get-Content -Raw -Encoding UTF8 $ManifestPath
|
||||
if ($stored -notmatch "<Id>([0-9a-fA-F-]{36})</Id>") {
|
||||
Fail "อ่าน GUID จาก $ManifestPath ไม่ได้"
|
||||
}
|
||||
$guid = $Matches[1].ToLower()
|
||||
& reg.exe delete $DevKeyCmd /v $guid /f | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Fail "reg delete ไม่สำเร็จ (exit $LASTEXITCODE) — ลบเองได้ที่: reg delete `"$DevKeyCmd`" /v $guid /f"
|
||||
}
|
||||
Remove-Item $ManifestPath -ErrorAction SilentlyContinue
|
||||
Write-Host "$Prefix ✓ ถอดการติดตั้งแล้ว (registry $guid + ไฟล์ $ManifestPath)"
|
||||
Write-Host "$Prefix ✓ เสร็จ"
|
||||
Print-NextSteps
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Host "$Prefix platform: win32"
|
||||
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec 30
|
||||
} catch {
|
||||
Fail "โหลด manifest จาก $Url ไม่ได้ ($_)"
|
||||
}
|
||||
$xml = $response.Content
|
||||
if ($xml -notmatch "<OfficeApp") {
|
||||
Fail "response จาก $Url ไม่ใช่ manifest ของ Office add-in (ไม่มี <OfficeApp)"
|
||||
}
|
||||
if ($xml -notmatch "<Id>([0-9a-fA-F-]{36})</Id>") {
|
||||
Fail "หา <Id> (GUID) ใน manifest ไม่เจอจาก $Url"
|
||||
}
|
||||
$guid = $Matches[1].ToLower()
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $ManifestDir | Out-Null
|
||||
# เขียน UTF-8 ไม่มี BOM — ให้ manifest เหมือนต้นฉบับบน server เป๊ะ
|
||||
[System.IO.File]::WriteAllText($ManifestPath, $xml, (New-Object System.Text.UTF8Encoding($false)))
|
||||
Write-Host "$Prefix ✓ เก็บ manifest ไว้ที่ $ManifestPath"
|
||||
|
||||
& reg.exe add $DevKeyCmd /v $guid /t REG_SZ /d $ManifestPath /f | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Fail "เขียน registry ไม่สำเร็จ (exit $LASTEXITCODE)"
|
||||
}
|
||||
Write-Host "$Prefix ✓ จดทะเบียน add-in ใน registry ($DevKeyCmd → $guid)"
|
||||
Write-Host "$Prefix ✓ เสร็จ"
|
||||
Print-NextSteps
|
||||
95
scripts/install-wordaddin.sh
Executable file
95
scripts/install-wordaddin.sh
Executable file
|
|
@ -0,0 +1,95 @@
|
|||
#!/bin/bash
|
||||
# ติดตั้ง (sideload) / ถอด Word add-in "e-Court Documents Versioning" บน macOS
|
||||
# เวอร์ชัน shell แบบส่งให้เครื่องทดสอบที่ไม่มี Node/repo — คู่หูของ
|
||||
# scripts/install-wordaddin.mjs (รันใน repo) และ scripts/install-wordaddin.ps1 (Windows)
|
||||
# กลไกเดียวกันทั้งสามไฟล์: โหลด manifest จาก server แล้ววางเป็น <GUID>.manifest.xml
|
||||
# ใน ~/Library/Containers/com.microsoft.Word/Data/Documents/wef/ ของ Word
|
||||
#
|
||||
# ใช้: ./install-wordaddin.sh [--url <manifest-url>] [--remove]
|
||||
# --url default https://ecourt-note.chamomind.com/docedit/wordaddin/manifest.xml
|
||||
# --remove ถอดการติดตั้ง
|
||||
# --help | -h
|
||||
#
|
||||
# หลังลง/ถอดต้อง restart Word ทุกครั้ง · รายละเอียดเต็ม: docs/WORDADDIN-DEV.md
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PREFIX="[install-addin]"
|
||||
DEFAULT_URL="https://ecourt-note.chamomind.com/docedit/wordaddin/manifest.xml"
|
||||
WEF_DIR="$HOME/Library/Containers/com.microsoft.Word/Data/Documents/wef"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
ใช้: ./install-wordaddin.sh [options]
|
||||
--url <manifest-url> default ${DEFAULT_URL}
|
||||
--remove ถอดการติดตั้ง
|
||||
--help | -h
|
||||
EOF
|
||||
exit "${1:-1}"
|
||||
}
|
||||
|
||||
fail() {
|
||||
echo "${PREFIX} ✗ $1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
URL="$DEFAULT_URL"
|
||||
REMOVE=0
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--url) [ $# -ge 2 ] || usage; URL="$2"; shift 2 ;;
|
||||
--remove) REMOVE=1; shift ;;
|
||||
--help | -h) usage 0 ;;
|
||||
*) usage 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$(uname)" = "Darwin" ] || fail "สคริปต์นี้สำหรับ macOS — Windows ใช้ install-wordaddin.ps1"
|
||||
|
||||
next_steps() {
|
||||
cat <<EOF
|
||||
|
||||
ขั้นต่อไป:
|
||||
1. restart Word ให้ครบทุกหน้าต่าง (จำเป็นทุกครั้งหลังลง/ถอด)
|
||||
2. Insert > My Add-ins > เปิด "e-Court Documents Versioning"
|
||||
3. เปิดไฟล์ .docx ที่มี ticket ของ e-Court (ขอจากทีม) เพื่อเริ่มทดสอบ
|
||||
EOF
|
||||
}
|
||||
|
||||
if [ "$REMOVE" = "1" ]; then
|
||||
echo "${PREFIX} platform: $(uname) · โหมดถอดการติดตั้ง"
|
||||
found=0
|
||||
# บน Mac ไม่มี manifest เก็บแยกที่อื่น — หาทุก *.xml ใน wef ที่เป็นของ add-in
|
||||
# นี้จากชื่อในไฟล์เอง จึงไม่ต้อง hardcode GUID
|
||||
for file in "$WEF_DIR"/*.xml; do
|
||||
[ -f "$file" ] || continue
|
||||
if grep -q "e-Court Documents Versioning" "$file" && grep -q "<OfficeApp" "$file"; then
|
||||
rm -f "$file"
|
||||
echo "${PREFIX} ✓ ลบ $file"
|
||||
found=1
|
||||
fi
|
||||
done
|
||||
if [ "$found" = "0" ]; then
|
||||
echo "${PREFIX} ไม่พบไฟล์ sideload ของ add-in นี้ใน $WEF_DIR — ถือว่าถอดแล้ว"
|
||||
fi
|
||||
echo "${PREFIX} ✓ เสร็จ"
|
||||
next_steps
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "${PREFIX} platform: $(uname)"
|
||||
|
||||
TMP="$(mktemp)"
|
||||
trap 'rm -f "$TMP"' EXIT
|
||||
curl -fsSL --max-time 30 "$URL" -o "$TMP" || fail "โหลด manifest จาก $URL ไม่ได้ — เช็คเน็ต และว่า environment นั้นรันอยู่"
|
||||
grep -q "<OfficeApp" "$TMP" || fail "response จาก $URL ไม่ใช่ manifest ของ Office add-in"
|
||||
GUID="$(sed -nE 's/.*<Id>([0-9a-fA-F-]{36})<\/Id>.*/\1/p' "$TMP" | head -n 1 | tr '[:upper:]' '[:lower:]')"
|
||||
[ -n "$GUID" ] || fail "หา <Id> (GUID) ใน manifest ไม่เจอจาก $URL"
|
||||
|
||||
mkdir -p "$WEF_DIR"
|
||||
rm -f "$WEF_DIR/$GUID".* # ลบของรอบก่อน — idempotent ไม่มีไฟล์ GUID เดียวค้างสองชื่อ
|
||||
DEST="$WEF_DIR/$GUID.manifest.xml"
|
||||
cp "$TMP" "$DEST"
|
||||
echo "${PREFIX} ✓ วาง manifest ไว้ที่ $DEST"
|
||||
echo "${PREFIX} ✓ เสร็จ"
|
||||
next_steps
|
||||
Loading…
Add table
Add a link
Reference in a new issue