Skip to content

Conversation

@chittolinag
Copy link
Contributor

@chittolinag chittolinag commented Jan 22, 2026

Introduced a new setProtectionMode command that lets SuperDoc callers toggle DOCX protection settings directly from the editor. The command normalizes supported modes (no protection, revisions-only, comments-only, form-fields-only, and read-only), patches the w:documentProtection node inside word/settings.xml.

Examples:

editor.commands.setProtectionMode('allowOnlyRevisions'); // tracked-changes only
editor.commands.setProtectionMode('allowOnlyComments'); // comment-only edits
editor.commands.setProtectionMode('allowOnlyReading'); // read-only document
editor.commands.setProtectionMode('allowOnlyFormFields'); // form fields only
editor.commands.setProtectionMode('noProtection'); // remove protection

@linear
Copy link

linear bot commented Jan 22, 2026

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2bd621bc25

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +55 to +57
console.log('normalizedMode', normalizedMode);
console.log('PROTECTION_VALUE_MAP', PROTECTION_VALUE_MAP, normalizedMode in PROTECTION_VALUE_MAP);
if (!(normalizedMode in PROTECTION_VALUE_MAP)) return false;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject prototype keys when validating protection modes

The validation uses normalizedMode in PROTECTION_VALUE_MAP, which also accepts prototype properties. If a caller passes a string like "toString" or "__proto__", the check passes even though it is not a supported mode, and mappedValue becomes the inherited function/object. That results in a w:edit attribute set to a non-string value (likely serialized as [object Function]), corrupting settings.xml instead of returning false. Consider using Object.hasOwn/hasOwnProperty to restrict to defined keys.

Useful? React with 👍 / 👎.

@caio-pizzol caio-pizzol self-requested a review January 23, 2026 22:28
Copy link
Contributor

@caio-pizzol caio-pizzol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently looking into STD locks - decided to review this one :)

Nice work @chittolinag

*/
function normalizeMode(mode = '') {
const normalized = typeof mode === 'string' ? mode.trim() : '';
console.log('normalized', normalized);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like that's debug - remove?

const mappedValue = PROTECTION_VALUE_MAP[normalizedMode];
if (mappedValue) {
const protectionNode = createDocProtectionNode(mappedValue);
const insertIndex = existingIndex >= 0 ? existingIndex : 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When no existing protection node exists, this inserts at index 0 which puts it before w:zoom.

OOXML spec says documentProtection should come at position 35, after zoom/trackRevisions/etc which might cause schema validation issues.

* @returns {keyof typeof PROTECTION_VALUE_MAP}
*/
function normalizeMode(mode = '') {
const normalized = typeof mode === 'string' ? mode.trim() : '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing null/undefined here becomes empty string, which then falls back to noProtection via the default.

Means invalid input silently removes protection instead of erroring.

Maybe we should return false for non-strings instead?

});

const editor = buildEditor(base);
const command = setProtectionMode('allowOnlyFormFields');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test name says it tests casing but only uses one case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants