- Add GetToken() as unified auth entry point with method selection
- Prompt [1] OAuth / [2] API token on first launch, save choice
- Validate API tokens against /api/v1/users/self before saving
- Check saved API token validity on reuse; fallback to re-prompt on failure
- Add HTTP status check to GetCourseInfo and GetEnrolledCourses
- Remove --api flag, auth method is now persistent and interactive
For ExternalUrl module items, the Canvas API returns url=null and
html_url=.../module_item_redirect/<id>. We were passing item.URL (empty)
causing the session_token call to return no session_url.
The Canvas app authenticates ExternalUrl items via:
GET session_token?return_to=<module_item_redirect>?display=borderless
→ GET session_url → OAuth2 confirm
→ POST /login/oauth2/accept
→ Panopto Login.aspx?code= → CookieCheck.aspx (sets Panopto cookies)
Our previous code used sessionless_launch (the course-level Panopto tool)
for direct Panopto links, which gave wrong/incomplete Panopto cookies.
Added DownloadExternalPanoptoURL() that replicates the exact app flow.
Falls back to DownloadVideo if no Panopto cookies are obtained.
Both List.aspx (folder playlists) and Viewer.aspx (single videos) are
handled with the correct yt-dlp flags and output templates.