Admin Panel

EasyAdmin backoffice for managing users and subscriptions

Admin Panel

The admin panel is built with EasyAdmin and provides a backoffice for managing users and subscriptions.

What's Included

  • User management with search, filter, and role editing
  • Subscription management with status tracking
  • Secure form-based login with rate limiting

Access

The admin panel is available at /admin. You must have the ROLE_ADMIN role to access it.

Creating an Admin User

  1. Register a user through the API
  2. Promote them to admin:
docker compose exec php bin/console app:user:promote-admin user@example.com

Login

The admin panel uses form-based login at /admin/login (separate from the API's JWT auth). Login is protected by rate limiting: 5 attempts per 15 minutes.

Dashboard

  • Title: Backoffice
  • Default view: Redirects to the Users list
  • Menu sections: User Management (Users) and Subscriptions (Subscriptions)

Users

Fields

FieldTypeEditableNotes
idIDNoHidden on forms
nameTextNoDisplayed but disabled
emailEmailNoAlways disabled
emailValidatedBooleanNoRendered as icon, not switch
providerTextNoemail, google, apple, etc.
rolesChoiceYesROLE_USER, ROLE_ADMIN — editable on edit page
createdAtDateTimeNoHidden on forms
updatedAtDateTimeNoVisible on detail page only

Search by name or email.

Filters

FilterTypeOptions
EmailTextFree text
NameTextFree text
Email ValidatedBooleanYes / No
ProviderTextFree text
RolesChoiceROLE_USER, ROLE_ADMIN

Disabled Actions

  • Delete — users cannot be deleted from the admin panel
  • Create — users must register through the API

Subscriptions

Fields

FieldTypeEditableNotes
idIDNoHidden on forms
userIdTextNoAlways disabled
planTypeTextNoFree Plan, Starter, Pro
paymentTypeTextNoRecurring or One-Time
statusChoiceYesActive, Past Due, Canceled, Expired
billingIntervalTextNoMonthly or Yearly
stripeCustomerIdTextNoVisible on detail/edit pages
stripeSubscriptionIdTextNoVisible on detail/edit pages
stripePaymentIntentIdTextNoVisible on detail/edit pages only
currentPeriodEndDateTimeNoAlways disabled
createdAtDateTimeNoHidden on forms
updatedAtDateTimeNoVisible on detail page only

Search

Search by userId, stripeCustomerId, or stripeSubscriptionId.

Filters

FilterTypeOptions
StatusChoiceActive, Past Due, Canceled, Expired
Plan TypeChoiceFree Plan, Starter Plan, Pro Plan
Billing IntervalChoiceMonthly, Yearly
Payment TypeChoiceRecurring, One-Time

Disabled Actions

  • Delete — subscriptions cannot be deleted from the admin panel
  • Create — subscriptions are created through Stripe checkout

Security

  • Access control — requires ROLE_ADMIN role
  • Authentication — form-based login (separate from API JWT auth)
  • Login throttling — 5 attempts per 15 minutes per IP
  • CSRF protection — enabled on login form
  • Password hashing — bcrypt with cost factor 12 (same as API)