• Mahmoud Aglan's avatar
    fix(cache): stop refusing to restore the objects we cache on purpose · 905ffefc
    Mahmoud Aglan authored
    Every branded page on the live tenant answered 500 with
    "BrandingService::for(): Return value must be of type BrandProfile,
    __PHP_Incomplete_Class returned".
    
    config/cache.php shipped Laravel's default serializable_classes => false,
    which unserializes cache values with allowed_classes: false. That is safe for
    an app that caches only scalars and arrays, and fatal for one that does not.
    We cache whole value objects deliberately: BrandProfile is the entire tenant
    brand, resolved once and held until branding changes, and read by every admin,
    portal and print layout. With classes refused it came back as
    __PHP_Incomplete_Class, the return type threw, and the admin went dark.
    
    The setting exists to stop a gadget chain in a cache an attacker can already
    write to. Ours is the tenant's own Postgres, reachable only by the app;
    anyone who can write there can do worse directly. CACHE_SERIALIZABLE_CLASSES
    lets a deployment pass its own allowlist without a code change.
    
    BrandingService now also checks what the cache handed back before trusting it,
    and rebuilds when it is not a profile. A cache that cannot return this class
    should cost a rebuild per request, never a 500 — the failure has to degrade,
    not detonate.
    
    Verified: every admin screen and the group roster render against a restored
    copy of the live tenant with CACHE_STORE=database.
    Co-Authored-By: 's avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    905ffefc
Name
Last commit
Last update
Screenshots Loading commit data...
app Loading commit data...
bootstrap Loading commit data...
config Loading commit data...
database Loading commit data...
docker Loading commit data...
docs Loading commit data...
docs-site Loading commit data...
flutter_shell Loading commit data...
gap-filling-plans Loading commit data...
lang Loading commit data...
marketing-site Loading commit data...
plans Loading commit data...
public Loading commit data...
reference/oc-sport Loading commit data...
resources Loading commit data...
routes Loading commit data...
scripts Loading commit data...
storage Loading commit data...
tests Loading commit data...
.dockerignore Loading commit data...
.editorconfig Loading commit data...
.env.example Loading commit data...
.gitattributes Loading commit data...
.gitignore Loading commit data...
.npmrc Loading commit data...
Beanding Guide.txt Loading commit data...
CLAUDE.md Loading commit data...
Dockerfile Loading commit data...
README.md Loading commit data...
artisan Loading commit data...
captain-definition Loading commit data...
composer.json Loading commit data...
composer.lock Loading commit data...
deploy.sh Loading commit data...
elcaptain-sportsonly-db.md Loading commit data...
one-click-app.yml Loading commit data...
package-lock.json Loading commit data...
package.json Loading commit data...
phpunit.xml Loading commit data...
system info.txt Loading commit data...
vite.config.js Loading commit data...
نادى الشيخ زايد كشف بيانات اللاعبين (2).html Loading commit data...