A Chrome extension that gathers — exhaustively — every piece of evidence a student has access to in support of a university due process hearing.
It scrapes:
- Canvas LMS — every course, module, page, assignment, submission, discussion, announcement, quiz, file, grade, calendar event, and Canvas inbox conversation.
- Email — Gmail and Outlook 365 (and Outlook.live.com), filtered by
domain (e.g.
@herzing.edu), folder/label, and/or date range. - Arbitrary web pages — one-click full-page screenshot + raw DOM.
Output is a single master PDF (cover page, section bookmarks, every artifact rendered or embedded as a paperclip attachment) plus a parallel ZIP with the unmodified raw bytes for chain-of-custody integrity.
Everything stays on the user's machine. No data is sent to any server.
chrome-extension/
├── manifest.json
├── background/service-worker.js - orchestrator
├── popup/ - the toolbar UI
├── options/ - settings page
├── content/
│ ├── canvas.js - canvas page detector
│ ├── gmail.js - gmail DOM scraper
│ ├── outlook.js - outlook 365 REST scraper
│ └── snapshot.js - generic page snapshot
├── scrapers/
│ ├── canvas-api.js - Canvas REST API walker (the bulk)
│ ├── email-common.js - shared email helpers
│ └── snapshot-engine.js - injects html2canvas
├── storage/artifact-store.js - IndexedDB wrapper
├── pdf/ - (reserved for future renderers)
├── offscreen/ - PDF + ZIP assembly (offscreen doc)
├── lib/ - vendored third-party libs
└── icons/
- Open Chrome and visit
chrome://extensions. - Enable Developer mode (top-right).
- Click Load unpacked and pick the
chrome-extension/folder. - Pin the extension to your toolbar.
- Open the extension popup → Settings.
- Enter your school's Canvas origin (e.g.
https://canvas.herzing.edu). - Click Grant access to current Canvas origin and approve the prompt.
- Sign in to Canvas in another tab.
- Open the extension popup → Canvas tab.
- Click Use current Canvas tab to autofill, or paste the URL.
- Click Start Canvas scrape. Watch the service worker console (right-click the extension → "Inspect service worker") for live progress.
- Open and sign in to mail.google.com or outlook.office.com in a tab. Leave that tab open.
- In the popup → Email tab, pick the provider.
- Enter domain(s), e.g.
herzing.edu, somecompany.com— matches both senders and recipients at those domains. - Optionally pick a folder/label (click Refresh to populate the list from the live tab).
- Optionally add a date range and message cap.
- Click Start email scrape. Progress reports come from the provider tab's DevTools console.
- Click the extension icon → Snapshot tab → Snapshot active tab, or
- Press ⌘⇧S (macOS) / Ctrl+Shift+S (other) on any page.
In the popup → Export tab → Build master PDF + raw ZIP. Two files are saved to your Downloads folder:
defense-bundle-<timestamp>.pdfdefense-bundle-<timestamp>.zip
Open the PDF, expand the bookmark sidebar, and you'll see one section per
source. The paperclip / "attachments" icon in any PDF reader will list every
embedded file. The ZIP holds the unmodified raw bytes plus a MANIFEST.json
with SHA-256 hashes for every artifact.
- Every artifact has a SHA-256 of its raw bytes recorded in the manifest.
- Capture timestamps, source URLs, and the scraper version are stamped on every artifact.
- The raw ZIP contains unmodified bytes — re-hashing any file there should match the manifest entry exactly. Use the ZIP, not the PDF, for any signature/integrity verification.
- Canvas: Requires the standard
/api/v1/*REST surface, which every hosted Canvas instance exposes by default. Some institutions disable the API; if a fetch returns 401, you'll see it in the SW console. - Gmail: Driven by DOM + the legacy
?view=omraw-message endpoint. Robust but sensitive to Gmail UI changes. If a page layout changes, update the row/thread selectors incontent/gmail.js. - Outlook: Uses the same REST API the OWA web app uses, authorized by
your existing session cookie. If your tenant disables OWA REST, fall
back to scraping the rendered DOM (not yet implemented — extend
content/outlook.js). - Storage: Uses the
unlimitedStoragepermission. Canvas exports for graduate students can run multi-GB.
After loading the extension:
- Popup opens without console errors.
- Service worker console (chrome://extensions → "Inspect views: service worker") is silent on idle.
- Canvas scrape populates the Export tab's run list.
- Gmail/Outlook scrape captures at least one message with a non-empty
headersRawand any expected attachments. - Snapshot on a public page (e.g. example.com) produces both the HTML artifact and a screenshot.
- Build PDF produces a viewable PDF with bookmarks, and the ZIP opens to reveal the raw artifacts and MANIFEST.json.