GitHub Authentication
Cartographer supports two GitHub authentication mechanisms. Browser builds use OAuth redirect authentication, while Android and desktop Tauri builds use GitHub Device Flow.
Browser OAuth flow
src/views/Auth.vue provides the AuthCallback view mounted at /callback. The flow is:
auth/logingenerates a random OAuthstate, stores it insessionStorage, and redirects the browser to GitHub.- GitHub redirects to
/callbackwith an authorizationcodeandstate. AuthCallbackverifies that the returned state matches the stored value.- The view dispatches
auth/authenticatewith the authorization code. - The store calls the same-origin
/authendpoint. The development proxy or nginx forwards the request to GitHub and injects the client secret on the server side. - The access token is stored in
sessionStorage, the user profile is loaded, and the router returns to the home page.
Authentication errors are displayed in the callback view. The token has a one-hour local expiry and is removed when it expires or the user logs out.
Browser configuration
| Variable | Purpose |
|---|---|
GH_APP_CLIENT_ID | Public GitHub OAuth App client ID |
GH_APP_CALL_BACK | Registered browser callback URL |
GH_APP_CLIENT_SECRET | Server-side token-exchange secret; never expose it in the browser bundle |
Native Tauri Device Flow
Android and desktop Tauri builds cannot rely on the browser callback flow. The auth/loginDevice action instead uses GitHub Device Flow:
MainMenu.vuedetects the Tauri runtime and dispatchesauth/loginDevice.- The store invokes the Rust
gh_device_codecommand. - The command requests a device code from
https://github.com/login/device/codewith therepo user:emailscopes. - The store publishes the verification URL and user code through
auth.state.devicePrompt. MainMenu.vuedisplays the code and a copy button while the user authorizes the request at https://github.com/login/device.- The store periodically invokes
gh_poll_token. The Rust command polls GitHub's access-token endpoint until authorization succeeds. - The token is stored,
auth/fetchUserloads the authenticated profile, and the device prompt is cleared after successful authorization.
GitHub may return authorization_pending while waiting or slow_down when the polling interval must be increased. The store handles both responses.
Native configuration
- Enable Device Flow in the GitHub OAuth App settings.
- Set
GH_APP_CLIENT_IDin.env.localbefore running or building Tauri. - Rebuild the native application when changing the client ID because it is included at build time.
Native builds do not require GH_APP_CLIENT_SECRET or GH_APP_CALL_BACK. Never bundle a GitHub client secret into a native application.
Relevant files
| File | Responsibility |
|---|---|
src/views/Auth.vue | Validates and completes the browser OAuth callback |
src/store/modules/auth.js | Manages browser and Device Flow authentication state |
src/components/MainMenu.vue | Starts login and displays the native device prompt |
src-tauri/src/lib.rs | Sends native Device Flow requests to GitHub |
vue.config.js | Configures browser OAuth values and the development token proxy |
nginx.conf | Performs the production browser token exchange |
Security considerations
- Browser OAuth state is validated to reduce CSRF risk.
- The browser client secret remains in the development proxy or nginx and is never sent in the frontend bundle.
- Native applications use Device Flow and must not contain a client secret.
- Users should enter a device code only when they initiated login in Cartographer.
- Access tokens are stored in
sessionStorage, cleared on logout, and given a one-hour local expiry.