Repository navigation
feat(oauth-server): Sign in with Fleetbase (OAuth 2.0 / OpenID Connect provider) - #324
Merged
Merged
Conversation
Apple and Google reviewers can't receive a texted sign-in code. Extensions register what their app signs reviewers in to (a Storefront store, an organization's Navigator app) with a review number from the 555-0100-0199 range reserved for fiction; the owner turns access on in the Console and gives the app store that number and a six-digit code, stored hashed and accepted only for that subject. New review_accesses table, Fleetbase\Support\AppReview, and GET|PUT int/v1/review-access/{type}/{id}.
Numbers in the fictional range are never texted: SmsService answers as sent without calling a provider, and SMS verification codes are saved without reserving or sending. Tests that sent to 555-01xx numbers use other test numbers.
…nect provider Registered apps can offer "Continue with Fleetbase" and, with the user's consent, act on one organization they administer. Built on league/oauth2-server: authorization code with PKCE (S256, every client), rotating refresh tokens, RFC 7009 revocation, ID tokens, userinfo, JWKS and discovery. Codes and tokens are bound to a grant and its organization, which every refresh and API call re-checks. Consent runs on the console session; admins manage apps and users manage connected apps.
…sole sandbox mode The consent screen runs on the console session, which switches models to the sandbox connection when test mode is on. OAuth rows and the organization checks now always use the core connection. Also raise the per-IP limit on the token and resource endpoints, since an app's server makes every call from one address.
…ints, commands and edge cases core-api CI requires full coverage. Adds tests for the console endpoints, the authorize redirect, the artisan commands, the authorized-app notice, real spatie roles in the organization check, and the protocol edge cases. The authorize endpoint builds its RedirectResponse directly.
…permission check Unknown types, any type's number, a custom resolver, an unsaved or unregistered subject, the table before migration, an unreadable table, and the Console endpoint for nobody, a viewer, a permission or wildcard holder, an administrator and an unseeded permission. Brings both files to the 100% coverage gate.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## release/v1.6.74 #324 +/- ##
=====================================================
Coverage 100.00% 100.00%
- Complexity 8999 9507 +508
=====================================================
Files 476 514 +38
Lines 28231 29566 +1335
=====================================================
+ Hits 28231 29566 +1335
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This was referenced Oct 25, 2026
Merged
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.
Makes Fleetbase an OAuth 2.0 / OpenID Connect provider, so registered apps can offer Continue with Fleetbase and, with the user's consent, act on one organization they administer. AppHelm is the first app to use it.
Includes #323 (App Review access). This branch is based on it, so merge #323 first. After that, this PR shows only its own two commits.
Library
league/oauth2-server 8.5, used directly, does the protocol and the crypto:
The plan was Laravel Passport 12 with jeremy379/laravel-openid-connect. Neither works here:
phpseclib ^2|^3, and Socialite 5.31 (used for the sign-in work) needs^4. Passport 13 needs Laravel 11.Fleetbase's code is the glue around league: repositories, a 100-line ID token response on lcobucci/jwt (already a dependency), and controllers.
What's in it
S256required for every client. Refresh tokens rotate on every use. Also: RFC 7009 revocation, OIDC ID tokens (nonce,auth_time,at_hash,kid),/oauth/userinfo,/oauth/jwks,/.well-known/openid-configuration, andisson the authorization response (RFC 9207).GET /oauth/authorizechecks the request and sends the user to the console's consent screen.int/v1/oauth-server/authorization(GET/POST/DELETE) runs on the console session, so sign-in and two-factor rules apply. Nothing creates an account.oauth_grants: user, client, organization, scopes).openid,profile,email,organization:read(GET /oauth/v1/organization). Extensions register more withOAuthScopes::register().GET|PUT|DELETE /oauth/v1/review-access/{type}/{id}on top of feat(app-review): App Review access for apps built on Fleetbase #323'sAppReview.int/v1/oauth-server/apps, system admins): register an app (secret hashed, shown once), edit, rotate the secret (the old one stops at once), turn off (revokes every grant), list grants and revoke one.int/v1/oauth-server/connected-apps): list and remove their apps. The account holder gets an email whenever they authorize a new app.oauth-server:keys(or--showfor env),oauth-server:client create|rotate|list,oauth-server:prune(scheduled daily).Upgrade
php artisan migrate. It adds theoauth_clients,oauth_grants,oauth_auth_codes,oauth_access_tokensandoauth_refresh_tokenstables.php artisan oauth-server:keys, or setOAUTH_SERVER_PRIVATE_KEY/OAUTH_SERVER_PUBLIC_KEY.OAUTH_SERVER_ISSUERif the public API URL isn'tAPP_URL. On Cloud it should behttps://api.fleetbase.io.Tests
tests/Unit/Auth/OAuthServerhas 42 tests. They run league's server with the real repositories over sqlite and the real migration:plainrefused, wrong or missing verifier;httpand token-time redirect URIs;promptandmax_age;The full core-api suite passes.
CoreProviderContractsTestis updated for the new scheduled prune.Not yet run end to end: the local Docker stack's MySQL keeps being killed for memory.
Related: console fleetbase/fleetbase (consent screen, OAuth Apps, Connected apps), fleetbase/storefront (storefront scopes), fleetbase/fleetbase.io (docs).