A Chrome extension (Manifest V3) for the California State University Accessible Technology Initiative (ATI). It bulk-downloads files flagged for accessibility issues by UDOIT inside Canvas LMS, then helps you upload the remediated versions back to Canvas with verification — across one course or hundreds.
Author: Zach Oshri, ATI Coordinator — CSU East Bay Version: 2.4.0 License: GNU AGPL v3.0
UDOIT identifies files with accessibility problems in a Canvas course, but it has no built-in way to export those files in bulk for remediation, or to push corrected files back at scale. Coordinators end up downloading files one at a time and re-uploading them by hand — impractical for a single large course, and impossible across a campus or the whole CSU system.
This extension automates the full loop: scan → download → remediate (offline) → upload → verify, for one course or for many at once.
The extension has three modes, all reachable from the toolbar popup.
Opens directly on a UDOIT page inside a Canvas course. The extension triggers a full UDOIT rescan, waits for per-file scanning to finish, scrapes every file that has confirmed accessibility issues across all paginated pages, matches each file to the Canvas Files API to get a download link, downloads them, and packages everything into one ZIP — together with a CSV report mapping each file to its issue type(s).
Processes many courses in one run. Provide courses by pasting course URLs or numeric IDs, uploading a CSV with a course-ID column, or entering a Canvas account / sub-account ID to auto-discover every course beneath it. A single reusable worker tab steps through each course, runs the same scan-and-scrape flow, and downloads a per-course ZIP as soon as it completes — freeing memory before moving on, so large batches don't exhaust the browser. A results panel lists every ZIP with re-download links. A Skip rescan option reuses existing scan results to cut per-course time from minutes to seconds when courses were already scanned recently.
Pushes corrected files back into Canvas. Upload the ZIP produced by the batch downloader; the extension parses its per-course folders, matches each file to its Canvas original by display name, and lets you manually map any files that were renamed during remediation. Selected files are uploaded through Canvas's three-step file-upload API with on_duplicate: overwrite, so they replace the originals in place. Optionally, the extension then re-runs a UDOIT scan to verify the issues are resolved and reports which files are fixed versus which still have issues.
Each downloaded ZIP contains:
- Every file UDOIT flagged with one or more accessibility issues
UDOIT_Remediation_Report.csv, one row per file + issue, with columns: File Name, Issue Type, Course, Export Date
In batch mode, each course is packaged into its own ZIP (or grouped into chunked ZIPs that flush at ~500 MB) so the folder structure stays organized and memory stays bounded.
This extension is distributed as source, not yet through the Chrome Web Store, so you install it manually in "developer mode." You only have to do this once; it takes about a minute and requires no command line or coding.
-
Get the files. Clone the repository or download it as a ZIP:
- Clone:
git clone https://github.com/oshrizak/UDOITOrchestrator.git - Or download: green Code button → Download ZIP, then unzip it.
Either way you'll end up with a project folder containing
manifest.jsonat its top level — that folder is the extension you'll load in the next steps. - Clone:
-
Open the extensions page. In Chrome, type
chrome://extensions/in the address bar and press Enter. (Or use the menu: ⋮ → Extensions → Manage Extensions.) -
Enable Developer mode. Flip the Developer mode toggle in the top-right corner of that page. A new row of buttons (Load unpacked, Pack extension, Update) appears — this is what lets Chrome run an extension straight from a folder.
-
Load the extension. Click Load unpacked, then select the project folder from step 1 (the one containing
manifest.json) and confirm. -
Pin it. The "CSU UDOIT Accessibility Remediation Downloader" card now appears on the page and its icon is added to your toolbar. Click the puzzle-piece icon in the toolbar and pin the extension so it's always visible.
Note: Keep the unzipped folder where it is — Chrome loads the extension directly from that location, so deleting or moving the folder removes the extension. After pulling code updates, return to
chrome://extensions/and click the circular refresh icon on the extension's card to reload it. If Chrome warns about developer-mode extensions on startup, that's expected for unpacked extensions and is safe to dismiss.
Single course: Open a Canvas course, launch UDOIT, click the Review Course Files tab. A navy CSU UDOIT Downloader button appears at the bottom-right. Click it, then Download Files with Issues, and wait for the ZIP. Progress shows in the panel.
Batch: Click the toolbar icon → Open Batch Processor. Add courses by URL/ID, CSV, or sub-account discovery, optionally check Skip rescan, and start. ZIPs download automatically as each course finishes.
Upload: Click the toolbar icon → Upload Remediated Files. Upload your remediated ZIP, confirm or correct the file-to-Canvas matches, and run the upload. Optionally run post-upload verification.
- Google Chrome 100+ (Manifest V3) and Chromium-based browsers (e.g., Edge)
- Any Canvas LMS instance on
*.instructure.com - UDOIT hosted at
udoit3.ciditools.com
The extension requests only what it needs to do its job:
downloads— to save the ZIP filesactiveTab,tabs,scripting— to drive the UDOIT scan, scrape results, and run the batch/upload worker tab- Host access to
*.instructure.comandudoit3.ciditools.com
It authenticates to the Canvas API using your existing browser session cookie (credentials: 'same-origin') — no API token is stored or required. All processing happens locally in your browser. No course data, file contents, or credentials are sent to any third-party server; downloads go straight to your machine and uploads go straight back to your Canvas instance.
To roll this out beyond a single machine:
- Test against each campus's
*.instructure.comsubdomain — Canvas configurations and the LTI iframe vary slightly. - Package as a
.crxor publish to the Chrome Web Store for easier distribution. - For managed fleets, force-install via Chrome Enterprise policy (
ExtensionInstallForcelist).
udoit-downloader-extension/
├── manifest.json # MV3 manifest (v2.4.0)
├── background.js # Service worker (lifecycle + batch progress relay)
├── content-canvas.js # Canvas-page orchestrator: UI, Canvas API, ZIP build
├── content-udoit.js # Runs inside the UDOIT iframe: rescan, navigation, scraping
├── zip-util.js # Dependency-free SimpleZip / SimpleZipReader
├── styles.css # ATI-branded styles for the single-course UI
├── popup.html / popup.js # Toolbar popup + mode buttons
├── batch.html / batch.js # Batch downloader page and orchestration
├── upload.html / upload.js# Upload-remediated-files page and orchestration
├── images/ # Extension icons (16/48/128)
├── CONTRIBUTING.md # How to report bugs and contribute
├── LICENSE # GNU AGPL v3.0
└── README.md # This file
Canvas and UDOIT live on different origins, so the extension runs two content scripts that talk over postMessage: content-canvas.js owns the UI and the Canvas REST calls, while content-udoit.js runs inside the cross-origin UDOIT iframe to trigger rescans, detect when scanning is complete, and scrape the file table. Batch and upload modes reuse this machinery through a single worker tab driven by chrome.scripting.executeScript. The ZIP format is implemented from scratch (store-only) with no external dependencies.
- UDOIT database lock errors (
SQLSTATE[HY000]/ error 1205) can occur when a full rescan stresses the server. The extension auto-retries up to three times. - Files stuck on "Scanning…" after a rescan are excluded from the download — only files with confirmed issues are included.
- The scraper reads whatever UDOIT currently displays, so UDOIT's "Hide Reviewed" toggle affects what gets exported.
Issues and pull requests are welcome — bug reports from other CSU campuses are especially helpful for hardening the LTI-iframe detection and scan-completion logic across different Canvas configurations. See CONTRIBUTING.md for how to report bugs (including capturing the [CSU-UDOIT] console logs), set up the extension for development, and submit changes. Because this project is licensed under the AGPL v3.0, any modifications you distribute (or run as a network service) must also be made available under the same license.
Copyright (C) 2025 Zach Oshri.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PU