💡 Plně funkční příklad je k dispozici na GitHubu:
office-metadata-pii-cleanup-nodejs
Úvod
Endpoint pro nahrávání přijímá soubor DOCX od zaměstnance a ukládá jej k zákaznickému ticketu. Text je v pořádku. Vlastnosti ne: soubor obsahuje jméno osoby, která jej vytvořila, kolegu, který jej naposledy uložil, manažera oddělení z firemní šablony a, protože přišel ze SharePointu, schvalovatele, který jej odsouhlasil.
Sanitizér metadat je malý skript, který před uložením souboru smaže tyto vlastnosti a poté zkontroluje svou práci. Tento tutoriál vytvoří takový skript v Node.js s GroupDocs.Metadata ve čtyřech krocích: výběr vlastností podle značky, výběr podle názvu, vymazání všeho, když selektivita přestane pomáhat, a ověření, co zůstalo. Každý krok má jen několik řádků a hotový skript má méně než sto řádků.
Proč je sanitizace metadat důležitá
Data se hromadí, aniž by si je někdo vybral. Word zapisuje Author a LastSavedBy z účtu operačního systému při každém uložení, udržuje čítač revizí, sleduje TotalEditingTime a zaznamenává LastPrinted. Servery pro dokumenty přidávají cesty pracovních postupů, identifikátory schvalovatelů a URI typů obsahu při check‑in. Žádná z těchto informací se neobjeví při čtení nebo tisku dokumentu, takže korektura je nikdy neodhalí.
Smyslem provádět to v Node.js místo ručně je, že skript vrací čísla: každý volání removeProperties hlásí, kolik vlastností bylo smazáno, a tento počet lze zapsat do logu, ověřit v testu nebo připojit k záznamu, ke kterému dokument patří.
Existuje i druhý důvod, který není zřejmý, dokud neběží dávková úloha. Ruční úklid je rozhodnutí učiněné jednou na soubor tím, kdo jej právě zpracovává, takže dva lidé sanitizující stejný typ dokumentu dosáhnou různých výsledků. Skript stanoví pravidlo na jednom místě: stejné čtyři značky, stejné seznamy podřetězců, aplikované identicky, ať už fronta obsahuje tři soubory nebo tři tisíce.
Požadavky
Balíček je Node.js přes Java, takže stroj potřebuje Java runtime vedle Node.
Instalace
npm install @groupdocs/groupdocs.metadata
Ukázkový projekt fixuje verzi na 26.7 a přidává položku overrides nastavující nan na ^2.22.0, což udržuje nativní vazbu funkční na aktuálních verzích Node. Bez licenčního souboru knihovna běží v režimu hodnocení, což stačí k provedení všech kroků v tomto tutoriálu.
Krok 1 – Výběr vlastností podle jejich významu
Názvy vlastností se liší mezi formáty a balíčky, takže první pravidlo odpovídá na základě značek. ContainsTagSpecification přijímá značku a odpovídá jakékoli vlastnosti, která ji nese; .or() sloučí specifikace do jedné.
const T = groupdocs.Tags;
const spec = new groupdocs.ContainsTagSpecification(T.getPerson().getCreator())
.or(new groupdocs.ContainsTagSpecification(T.getPerson().getEditor()))
.or(new groupdocs.ContainsTagSpecification(T.getPerson().getManager()))
.or(new groupdocs.ContainsTagSpecification(T.getCorporate().getCompany()));
const affected = metadata.removeProperties(spec);
metadata.save(outputPath);
Klíčové body:
- Čtyři značky pokrývají skupinu identity: tvůrce, editor, manažer a firemní pole společnosti.
- Název, Předmět a Klíčová slova zůstávají nedotčena, takže index záznamů, který je používá, nadále funguje.
removePropertiesvrací počet ovlivněných položek místo booleanu.
Zabalte celý kód do try/finally s metadata.close() v bloku finally. Vazba drží soubor otevřený až do té chvíle a smyčka bez ní vyčerpá handly.
Krok 2 – Výběr vlastností podle názvu
Komentářové vlákna, čítače revizí a serverová pole nemají žádnou značku. Pro ně WithNameSpecification(needle, false) odpovídá jakékoli vlastnosti, jejíž název obsahuje daný podřetězec, a čtyřřádkový builder řetězí jeden builder na každý podřetězec:
let spec = null;
for (const needle of needles) {
const s = new groupdocs.WithNameSpecification(needle, false /* fullMatch */);
spec = spec ? spec.or(s) : s;
}
return spec;
Tři průchody znovu použijí tento builder s různými seznamy. Nejprve komentáře:
const affected = metadata.removeProperties(
nameContainsSpec(['Comment', 'Reviewer', 'Reviewed']));
metadata.save(outputPath);
Časová osa úprav je skupina, která bývá zapomenuta, a je to právě ona, která popisuje, jak byl dokument vytvořen:
const affected = metadata.removeProperties(nameContainsSpec([
'Revision', 'TrackedChange', 'LastPrinted', 'TotalEditingTime', 'EditTime',
]));
metadata.save(outputPath);
Průchod pro SharePoint je stejný volání s Server, Workflow, Approver, ContentType a Template. Shodování podřetězců je úmyslné: zachytí CommentsCount spolu s Comment bez nutnosti udržovat přesný seznam názvů pro každý formát.
Krok 3 – Vymazání všeho, když selektivita přestane pomáhat
Pro kopii, která opouští organizaci, jedno volání nahrazuje čtyři předchozí průchody:
const affected = metadata.sanitize();
metadata.save(outputPath);
sanitize() vymaže každý balíček metadat, který knihovna detekuje, včetně vlastních částí OOXML, a jeho počet obvykle převyšuje součet počtů cílených průchodů. Také odstraní Název a Předmět, což je důvod, proč by se mělo volat na konci, nikoli uvnitř revizní smyčky.
Krok 4 – Ověření, protože tichý omyl vypadá jako úspěch
Sken znovu použije stejné specifikace přes findProperties, který čte bez zápisu. Výsledek je Java kolekce, takže se prochází pomocí indexu:
const props = metadata.findProperties(tagSpec.or(nameSpec));
for (let i = 0; i < props.getCount(); i++) {
const p = props.get_Item(i);
const val = p.getValue && p.getValue();
const value = val ? String(val.getRawValue ? val.getRawValue() : val) : '';
if (!value || value === '0' || value === '0.0') continue;
leaks.push(`${p.getName()}=${value}`);
}
Filtr prázdných a nulových hodnot si zaslouží své místo. Přidal jsem jej poté, co jeden běh selhal na čítači revizí, který byl vymazán na 0, a sken to poctivě hlásil jako přeživší vlastnost.
Kompletní funkční příklad
Repozitář propojuje šest funkcí v index.js, který načte licenci, spustí každý průchod proti resources/pii-sample.docx, ověří, že každý výstupní soubor existuje, a nakonec potvrdí, že seznam úniků je prázdný. Selhání aserce ukončí proces s nenulovým kódem, takže celý skript funguje jako kontrola v CI místo pouhého demopříkladu.
Jedna podrobnost stojí za to zkopírovat do vlastní verze: každý průchod čte stejný zdrojový soubor a zapisuje samostatný výstup, místo aby řetězil jeden vyčištěný soubor do dalšího. To udržuje počty ovlivněných položek nezávislé, takže řádek logu pro průchod komentářů uvádí, co pravidlo komentářů našlo, nikoli co zbylo po pravidle identity.
Kdy spustit cílený průchod místo sanitize()?
Vždy, když je dokument stále v používání. Soubory cirkulující mezi recenzenty se spoléhají na Název, Předmět a Klíčová slova pro vyhledávání a klasifikaci, a sanitize() odstraňuje všechny tři spolu s osobními údaji. Spusťte průchody identity a komentářů během spolupráce, nechte popisná pole nedotčena a kompletní vymazání nechte až pro kopii, která skutečně opouští organizaci.
Reálné aplikace
Zpracování nahrávání
Expressová cesta sanitizuje přílohu před jejím zápisem do úložiště, zaznamená počty ovlivněných položek na ticket a odmítne nahrání, pokud je seznam úniků neprázdný.
Noční exportní úloha
Worker prochází exportní složku, aplikuje průchody identity a serveru a selže úlohu místo pouhého varování, pokud dokument stále hlásí zbylé PII.
Brána před publikací
Krok ve build procesu sanitizuje dokumentační přílohy před vydáním, používá sanitize(), protože v těch souborech není potřeba zachovat metadata.
Nejlepší postupy a tipy
- Vždy zapisujte do nové cesty, aby originál přežil pro případné spory.
- Zavřete objekt metadat v bloku
finally, zejména v smyčkách. - Sloučte specifikace pomocí
.or()v dávkových úlohách; jedno otevření a jeden zápis překoná čtyři. - Logujte počet ovlivněných položek pro každý průchod, včetně nul, aby byl vidět neznámý formát.
Řešení běžných problémů
Počet ovlivněných položek je nula u dokumentu, o kterém víte, že je „špinavý“
Zkontrolujte, že vstupní formát je rozpoznán, než usoudíte, že soubor byl čistý; nečtený soubor a čistý soubor produkují stejný nulový výsledek.
Kontrola úniku hlásí vlastnosti, které jste právě odstranili
Ukazujte na uloženou výstupní cestu, ne na vstupní. Sken čte soubor, který mu předáte.
Bubliny komentářů jsou stále viditelné ve Wordu
Text komentáře žije v těle dokumentu, ne v balíčku metadat. GroupDocs.Metadata vymaže vlastnosti související s komentáři; odstranění samotných bublin vyžaduje knihovnu pro úpravu obsahu, např. Aspose.Words.
Závěr
Čtyři kroky, šest funkcí, jeden skript, který hlásí, co udělal. Specifikace značek řeší skupinu identity napříč formáty, specifikace názvů pokrývají rodiny, které značky neklasifikují, sanitize() řeší hranice a sken úniku převádí celý proces na kontrolu. Naklonujte repozitář, spusťte jej na dokumentu, který prošel reálným recenzním kolem, a podívejte se na počty, než se rozhodnete, které průchody vaše pipeline potřebuje.