Prevent editing of form field data by flattening PDFs in Adobe Acrobat #

Adobe's 8-step guide on How to flatten a PDF file ends with the instruction to "Print document"; sadly, this feature is missing in the macOS version:

Here's a 3-step alternative:

  1. Tools → Print Production → Preflight (or use the keyboard shortcut Cmd+Shift+X to save a few clicks)

  2. In PDF Fixups, double-click Flatten annotations and form fields

  3. Save the new PDF when prompted

and similarly-concise console approach:

  1. Press Cmd+J to open the JavaScript Debugger console

  2. Enter this.flattenPages(); and press Cmd+Return

  3. Save the PDF as desired

Notes

/mac | Oct 18, 2024

Free, offline watermark removal #

with IOPaint's erase models:

  1. Install: pip3 install iopaint (see Quick Start for GPU instructions)

  2. Run: iopaint start --model=lama --device=cpu --port=8080

  3. Access: open http://localhost:8080 in your web browser

Removing watermarks from image via IOPaint
Seated Buddha, courtesy of The Cleveland Museum of Art

Besides watermark/object removal, IOPaint also supports inpainting, outpainting, paint-by-example, and text generation.

Related

/nix | Sep 28, 2024

One-click DFU mode #

Twocanoes (developer of Winclone) has updated DFU Blaster Pro, which reduces the process of entering DFU mode on a Mac to a single click. After connecting to the target Mac's DFU port, simply press the "DFU Mode" button on the host Mac. The tool can also retrieve the target Mac's model type, serial number, and ECID.

/mac | Sep 25, 2024

Disable Sequoia's monthly screen recording permission prompt #

See update below for important change in macOS 15.1.

The widely-reported "foo is requesting to bypass the system private window picker and directly access your screen and audio" prompt in Sequoia (which Apple has moved from daily to weekly to monthly (though for some apparently it is minute-by-minute)) can be disabled by quitting the app, setting the system date far into the future, opening and using the affected app to trigger the nag, clicking "Allow For One Month", then restoring the correct date.

Tested by setting the date to 1/1/2040 then clicking "Allow For One Month"; no amount of changing to dates before 1/1/2040 triggered the nag, while setting the date to a month after 1/1/2040 or anytime thereafter triggered it again.

Apple's latest security enhancement defeated by a "hack" from the '90s shareware scene?

requesting to bypass the system private window picker and directly access your screen and audio

Updates

/mac | Sep 18, 2024

Delete all Dropbox shared links #

via JavaScript:

// This script automates the removal of all shared links from your Dropbox account. 
// Navigate to https://www.dropbox.com/share/links, open the browser console, and paste the JavaScript code below.
// Optional: To delete only specific types of links (i.e., View or Edit links), 
// edit the `deleteLinkTexts` array to include only the types of links you want to remove.
// By default, the script will target both "Delete view link" and "Delete edit link" options.
// Script source: https://www.dropboxforum.com/t5/Create-upload-and-share/remove-all-shared-links/m-p/710562/highlight/true#M73731

async function pause(ms) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve();
        }, ms);
    });
}

async function deleteLinks() {
    const deleteLinkTexts = ["Delete view link", "Delete edit link"]; // Both options
    let items = document.querySelectorAll('.share-page-row-actions [data-testid="open-menu-button"]');

    for (let i = 0; i < items.length; i++) {
        items[i].click(); // Click the submenu button to open the menu
        await pause(1000); // Adjust the pause duration as needed

        // Find and click the appropriate delete link option
        const deleteLinkOption = Array.from(document.querySelectorAll('.dig-Menu-row-title')).find(item => deleteLinkTexts.includes(item.textContent));
        if (deleteLinkOption) {
            deleteLinkOption.click(); // Click the delete link option
            await pause(1000); // Adjust the pause duration as needed

            // Find and click the delete button
            const deleteButton = document.getElementsByClassName("dbmodal-button");
            if (deleteButton.length > 0) {
                deleteButton[0].click();
                await pause(1000); // Adjust the pause duration as needed
            }
        }

        items = document.querySelectorAll('.share-page-row-actions [data-testid="open-menu-button"]'); // Refresh items
    }
}

deleteLinks();

or via watermint toolbox:

  1. Install watermint toolbox

  2. List shared links:

    % tbx dropbox file sharedlink list
    ...  
    | tag    | url                        | name    | expires | path_lower      | visibility |
    |--------|----------------------------|---------|---------|-----------------|------------|
    | file   | https://www.dropbox.com... | foo.jpg |         | /photos/foo.jpg | public     |
    | file   | https://www.dropbox.com... | bar.jpg |         | /photos/bar.jpg | public     |
    | folder | https://www.dropbox.com... | Baz     |         | /baz            | public     |
    
    The report generated: /Users/user/.toolbox/jobs/20240913-094617.OPY/report/shared_link.csv
    The report generated: /Users/user/.toolbox/jobs/20240913-094617.OPY/report/shared_link.json
    The report generated: /Users/user/.toolbox/jobs/20240913-094617.OPY/report/shared_link.xlsx
    The command finished: 2.16s
  3. Delete a single shared link:

    % tbx dropbox file sharedlink delete -path /photos/foo.jpg
    
    Removing link `https://www.dropbox.com...` that point to `/photos/foo.jpg`
    
    | status  | reason | input.tag | input.url                  | input.name | input.expires | input.path_lower | input.visibility | result |
    |---------|--------|-----------|----------------------------|------------|---------------|------------------|------------------|--------|
    | Success |        | file      | https://www.dropbox.com... | foo.jpg    |               | /photos/foo.jpg  | public           |        |
    ...

    or all shared links by extracting the paths from the path_lower column in shared_link.csv with awk and feeding them to tbx via xargs:

    % awk -F ',' 'NR>1 {print $5}' shared_link.csv | xargs -I {} tbx dropbox file sharedlink delete -path "{}"

    (tbx includes a dropbox team sharedlink delete links command to batch delete shared links for Teams accounts.)

Related

/misc | Sep 14, 2024

macOS: Capture app window screenshot with drop-down menu and cursor after a delay #

Tried the native Screenshot.app, Shottr, CleanShot X, Flameshot, ksnip, Skitch, Xnapper, among others to no avail.

Snagit 2024's Capture Multiple Areas on the Screen did the trick:

  1. In the Capture window, select the All-in-One tab (rather than the usual Image for screenshots)

  2. Enable Capture Cursor and 5 Second Delay:

    Snagit 2024 Capture window

  3. Click the Capture button or press Control+Shift+C

  4. When the orange crosshairs appear, position your cursor over the main application window and click to capture it, including any context menus, drop-downs, or other elements that appear within the frame

  5. Click the camera icon in the popup menu to edit or save the screenshot

/mac | Sep 08, 2024

UTM: Add removable disk to HVF-based macOS guest VM #

(Spent way too much time in UTM's Drives → New… and mucking about in config.plist before this brain-wave):

  1. Create a new blank image in Disk Utility (Cmd+N)

  2. Set filename, size, format, etc. as desired

  3. Select the VM in UTM's sidebar → click the "Edit selected VM" button in the toolbar

  4. Under "Drives" click New… → check "Removable" → click "Create" then "Save" to close the settings window

  5. In the VM's main pane, scroll down to the "External Drive" dropdown menu (which has now appeared) → select Browse… → double click the DMG file created in step 2

/mac | Sep 07, 2024

Remote Desktop: Enable concurrent interactive and remote sessions #

(without hack workarounds) via RDP shadowing.

Warning: Do not proceed without fully understanding the steps involved and how to secure your network.

1. On Windows 10 Professional ("server")

  1. System Properties (sysdm.cpl) → Remote

  2. Enable "Allow remote connections to this computer" → OK

  3. Group Policy Editor (gpedit.msc) → Local Computer Policy → Computer Configuration → Administrative Templates → Windows Components → Remote Desktop Services → Remote Desktop Session Host → Connections

  4. Double click "Set rules for remote control of Remote Desktop Services user sessions" → select "Enabled" → set "Options:" to "Full Control without user's permission" → OK

  5. Windows Defender Firewall with Advanced Security (wf.msc) → check "File and Printer Sharing (SMB-In)" and "Remote Desktop - Shadow (TCP-In)" are enabled for LAN connections (see Restrict Windows Remote Desktop connections to LAN only)

2. On Windows 11 Home ("client")

  1. If the local and remote credentials differ, store the remote username and password in Windows Credential Manager:

    cmdkey /add:<hostname|IP> /user:<remote_user> /pass:<remote_pass>

2a. Manual method

  1. Retrieve the remote user's session ID (will generally be "1" or "2" on single-user systems):

    qwinsta /server:<hostname|IP>

  2. Connect:

    mstsc.exe /shadow:<sessionID> /v:<hostname|IP> /noconsentprompt /control

2b. Automatic method

  1. Modify and save this batch file, then run it to automatically retrieve the user session ID and establish a connection:

    @echo off
    setlocal enabledelayedexpansion
    
    :: Set your remote username and hostname or IP address
    set remote_user=<USERNAME>
    set remote_host=<HOSTNAME|IP>
    
    :: Get the session ID for the specified username where the session state is Active
    for /f "tokens=2,3,4" %%a in ('qwinsta /server:%remote_host% ^| findstr /R "^ %remote_user%"') do (
        if "%%c"=="Active" (
            set session_id=%%b
        )
    )
    
    :: If an active session ID was found for the specified user, connect automatically
    if defined session_id (
        start "" mstsc /v:%remote_host% /shadow:%session_id% /control /noConsentPrompt
    ) else (
        echo No active session found for user "%remote_user%".
    )
    
    exit

3. Notes

4. Further reading

/windows | Sep 04, 2024

Restrict TightVNC connections to LAN only #

  1. TightVNC Service Configuration → Access Control

  2. Click Add… → set "First matching" and "Last matching IP" values to cover desired LAN range (e.g., 192.168.0.1 and 192.168.0.254) → set "Action" to Allow → click OK

  3. Click Add… → set "First matching" to 0.0.0.0 and "Last matching IP" to 255.255.255.255 → set "Action" to Deny → click OK

  4. Click Apply

  5. Optionally adjust local and remote IP address scope for TightVNC's default inbound rule in Windows Defender Firewall with Advanced Security; see Restrict Windows Remote Desktop connections to LAN only.

/windows | Aug 31, 2024

Restrict Windows Remote Desktop connections to LAN only #

  1. Open Windows Defender Firewall with Advanced Security (Win+R → wf.msc → Enter)

  2. Click "Inbound Rules" under "Windows Defender Firewall with Advanced Security on Local Computer"

  3. For each Remote Desktop entry, double click to open Properties then select the "Scope" tab

  4. Under "Remote IP address" select "These IP addresses:"

  5. Click Add…

  6. Select "Predefined set of computers", choose "Local subnet", then click OK twice

Thanks to @void_in for the pointer.

/windows | Aug 31, 2024


Subscribe or visit the archives.