Skip to content

Added Playwright Token Refresher Service#224

Merged
PianoNic merged 1 commit intomainfrom
feature/220_PlaywrightRefresher
Apr 28, 2026
Merged

Added Playwright Token Refresher Service#224
PianoNic merged 1 commit intomainfrom
feature/220_PlaywrightRefresher

Conversation

@PianoNic
Copy link
Copy Markdown
Owner

Summary

Standalone FastAPI + Playwright service that refreshes Schulnetz tokens and web sessions automatically.

Refresher service (plugins/Schuly.Plugin.Schulware/refresher/)

  • POST /refresh — opens Schulnetz in headless Chromium, re-does Microsoft SSO, returns fresh tokens + PHPSESSID
  • Persists Playwright browser contexts per user (Microsoft SSO session cached)
  • GET /health — status check
  • DELETE /contexts/{user_id} — clear cached session
  • Docker-ready with compose.yml

Sync task update

  • TryRefreshToken now falls back to Playwright refresher when token.php returns biometric_required
  • Gets both mobile tokens AND web session in one refresh
  • Configurable via SCHULWARE_REFRESHER_URL env var

Test plan

  • Build passes (0 errors)
  • Refresher service starts and responds to /health
  • End-to-end: token expires → sync task calls refresher → fresh tokens stored

@PianoNic PianoNic force-pushed the feature/220_PlaywrightRefresher branch from e92bcdb to d120a02 Compare April 28, 2026 15:55
…ation

- Refresher FastAPI + Playwright service with /refresh, /seed, /health, /contexts endpoints
- /seed accepts cookies from mobile app WebView to bootstrap Playwright browser context
- /refresh navigates Schulnetz with seeded cookies, Microsoft SSO auto-passes, captures code
- Route interception catches schulnetz.web.app redirect to extract PKCE code
- Exchanges code for mobile tokens via token.php + captures PHPSESSID via loginto.php
- Docker container with Playwright + Chromium headless (playwright install --with-deps)
- Sync task: falls back to Playwright refresher when token.php returns biometric_required
- Uses account ID as refresher context key (consistent between app and sync task)
- Fixed entity tracking: db.Accounts.Update() for reliable persistence
- Fixed FindOrCreateExam: creates Class from grade course when no classes exist

Tested end-to-end:
- Forced token expiry in DB (set to 2020)
- Sync task detected expiry, called Playwright refresher
- Refresher returned fresh access_token + refresh_token + PHPSESSID
- Token expiry updated to 1 hour from now
- Sync continued with fresh tokens, grades synced to main DB

resolve #79
@PianoNic PianoNic force-pushed the feature/220_PlaywrightRefresher branch from d120a02 to f5948c6 Compare April 28, 2026 16:58
@PianoNic PianoNic merged commit d6393d7 into main Apr 28, 2026
@PianoNic PianoNic deleted the feature/220_PlaywrightRefresher branch April 28, 2026 16:58
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.

1 participant