# Verifying a commenter's file

Source: https://docx-editor.portone.io/docs/core/verifying-a-commenters-file

Check on the server that a file returned by a comment editor differs from the original in comments alone.

A file returned by a `comment` editor should differ from the original in comments alone.
The editor enforces that in the browser only, so check it again where the file arrives:

```ts
import { onlyCommentsChangedBy } from "@portone/docx-editor/core";

const verdict = onlyCommentsChangedBy(original, submitted, user.id);
if (!verdict.ok) console.warn(verdict.reason);
```

When the verdict is `body-changed` or `part-changed`, [`compareDocx`](https://docx-editor.portone.io/docs/core/comparing-two-files.md) lists the blocks and parts that differ.
It compares comment text alone, so it shows nothing for a refusal over a comment's author, anchor, or markup.

## What must hold [#what-must-hold]

The comparison checks the whole package within the [limits below](#how-files-are-compared):

* Every part is byte-identical, except the comment parts: comments, extended comments, people, and
  the parts Word records a comment's time in (`commentsIds.xml` and `commentsExtensible.xml`).
* The main document part is unchanged outside its body blocks.
* Its relationships and `[Content_Types].xml` gain only what the comment parts need: a relationship to each and an override naming each part the file holds.
* The story reads as it did with the comments taken out, and every changed comment is this author's.
* Every entry of the comment parts is unchanged, or is one this editor writes and this author could
  have written; adding a person cannot claim an existing unattributed comment.
* An entry of a comment that is still there is not removed, and a comment's recorded time can be
  added only to a comment that is new, within fourteen hours of the clock time on the comment.
* XML comments, processing instructions, and the extension list that may close
  `commentsExtensible.xml` are unchanged outside those entries; layout whitespace may differ.

Both files are read through `importDocx` first, so a package that spelled the namespaces under
other prefixes is compared respelled on both sides and the verdict is unaffected.

`editableComments` in the options says whose comments may have changed: `"own"` (the default) is
this author's and the unattributed ones, `"all"` is every comment.

## The verdict [#the-verdict]

```ts
type CommentOnlyVerdict =
  | { ok: true }
  | {
      ok: false;
      reason: "body-changed" | "comment-not-owned" | "comment-author-forged";
    }
  | {
      ok: false;
      reason:
        | "part-changed"
        | "relationship-changed"
        | "comment-markup-rejected";
      part: string;
    };
```

| `reason`                  | What it means                                                                                                                                  |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `body-changed`            | The document differs in something other than its comments, including a body edit that deleted commented text.                                  |
| `comment-not-owned`       | Somebody else's comment or reply was rewritten, re-anchored, or deleted.                                                                       |
| `comment-author-forged`   | A new comment claims another identity, or an existing comment's author was rewritten.                                                          |
| `part-changed`            | A part outside the comment parts differs, or the main part changed outside its body. `part` names it.                                          |
| `relationship-changed`    | The main part's relationships changed beyond what a comment part needs. `part` names the relationship part.                                    |
| `comment-markup-rejected` | A comment part holds an entry this editor would not write for this author, or lacks the entry of a comment still in the file. `part` names it. |

## How files are compared [#how-files-are-compared]

The story is compared as this editor would write it, so two spellings of the same markup (attribute
order, `100%` against `5000`, split runs) are accepted.
The comparison does not cover markup inside `w:tblGrid` beyond the column widths, the size a
picture's own transform states, or table properties the model no longer needs.
It also cannot detect changes inside cells that continue a vertical merge.
Where integrity must hold to the byte, compare the parts yourself, after opening both files
through the editor: a returned file whose original spelled the namespaces under other prefixes
carries every markup part respelled, so a comparison against the original bytes differs throughout.

Run the verifier on a package at least as new as the editor that wrote the file.
Unreadable bytes throw `DocxImportError`.
[Who may edit a comment](https://docx-editor.portone.io/docs/editor-api/comments-and-notes.md#who-may-edit-a-comment) describes the
ownership rule the verdict holds to. Use an author name that is not already recorded for another
identity; a conflict can produce `comment-author-forged`.