Repository navigation
feat: real OAuth login (Discord/GitHub/Twitch) + JWT session - #7
Open
tecrodrigocastro wants to merge 4 commits into
Open
tecrodrigocastro wants to merge 4 commits into
tecrodrigocastro wants to merge 4 commits into
Conversation
AuthTokenStore wraps SecureStorage as the single source of truth for "is the user logged in"; He4rtApi is a thin client for the mobile JWT endpoints (exchange/refresh/logout/me) documented in docs/plans/2026-09-22-api-mobile-jwt.md on heartdevs.com.
Login is mobile-native (gradient brand hero, no literal web-form
clone) and OAuth-only — Discord/GitHub/Twitch via Browser::auth(),
since the mobile API doesn't expose an email/password endpoint yet.
OAuthCallback lands on the he4rtapp://oauth/{action} deep link, trades
the one-time code for a token pair, and bounces back to Login with a
friendly message on failure.
Known risk inherited from the API side (documented in
docs/plans/2026-09-22-api-mobile-jwt.md on heartdevs.com): the custom
URL scheme isn't exclusive to this app, so another app registering the
same scheme could race to consume the exchange code first. The code is
single-use and expires in 60s, which bounds the damage; the real fix
(PKCE or a verified HTTPS App Link) needs coordinated changes on both
repos and is tracked as follow-up, not fixed in this PR.
Added a fakeSecureStorage() test helper (tests/Pest.php) — FakeBridge
records SecureStorage calls but doesn't persist them, so this replays
the latest Set/Delete per key to make AuthTokenStore round-trip in
tests.
Routes to /home when a token is already in secure storage, /login otherwise. Token validity itself isn't checked here — that's lazy, left to whichever screen calls the API first (see Perfil).
Drops the hardcoded POC Sanctum token — Perfil now reads the real stored JWT, calls GET /api/mobile/me, and shows the actual username and avatar. A 401 triggers one refresh attempt before giving up and bouncing to Login; a working Logout button calls POST /api/mobile/auth/logout and clears the stored token either way.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This connects to the real backend — unlike the Home/Timeline mockups, this is live: login actually authenticates against the heartdevs.com mobile API (JWT), per
docs/plans/2026-09-22-api-mobile-jwt.mdon that repo.Browser::auth()) — the mobile API has no email/password endpoint yet, so that form from the web reference was deliberately left out rather than built non-functional.OAuthCallbackscreen handles thehe4rtapp://oauth/{action}deep link, trades the one-time code for a token pair (POST /api/mobile/auth/exchange), and bounces back to Login with a friendly message on failure.AuthTokenStore(SecureStorage-backed) is the single source of truth for "is the user logged in".He4rtApiis a thin client for the four JWT endpoints (exchange/refresh/logout/me).Splashnow routes to/homeor/logindepending on whether a token is stored.Perfilis connected for real: shows the actual username/avatar fromGET /api/mobile/me, attempts one token refresh on a 401, and has a working Logout button (POST /api/mobile/auth/logout). Drops the old hardcoded POC Sanctum token entirely.NATIVEPHP_DEEPLINK_SCHEMEnow defaults tohe4rtapp, matching the API'sHE4RT_APP_DEEPLINK_SCHEMEdefault.Known risk (not fixed here, by design)
The API side's plan doc flags a real, documented security debt: the custom URL scheme (
he4rtapp://) isn't exclusive to this app — another app registering the same scheme could race to intercept the OAuth exchange code. The code is single-use and expires in 60s, which bounds the blast radius, but the correct fix is PKCE or a verified HTTPS App Link, and that needs coordinated changes on both repos. Tracked as follow-up, discussed and explicitly accepted for this PR rather than blocking login on it.Test plan
php artisan test --compact— 31 passed (new: Login, OAuthCallback, token-refresh/logout flows on Perfil, Splash's two branches)vendor/bin/pint --dirty— cleanphp artisan native:validate— passes (pre-existing warnings only)php artisan native:run ios)php artisan native:run android)HE4RT_APP_DEEPLINK_SCHEMEon heartdevs.com matcheshe4rtapp(or update.env/NATIVEPHP_DEEPLINK_SCHEMEhere to match whatever it's actually set to)