Skip to content

Commit eef6536

Browse files
committed
docs: update AGENTS.md, README.md, and readme.txt to reflect current architecture
Rewrite all three documentation files to accurately document the plugin's current state: bootstrap via Plugin::bootstrap(), all 55 source files, 23 test files, bun build system, and features added since initial docs (activity logging, login button, login bypass, entitlement gate, onboarding wizard, diagnostics, logout redirects, admin bar badge).
1 parent c913241 commit eef6536

3 files changed

Lines changed: 285 additions & 46 deletions

File tree

‎AGENTS.md‎

Lines changed: 113 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,35 @@ Enterprise identity management for WordPress powered by WorkOS. SSO, directory s
99
- **PHP Requirement:** 7.4+
1010
- **WordPress Requirement:** 5.9+
1111
- **Text Domain:** `integration-workos`
12-
- **Author:** LiquidWeb Software
12+
- **Author:** Gustavo Bordoni
1313

1414
## Architecture
1515

1616
### Bootstrap Process
1717

1818
The plugin uses a deferred loading pattern:
19-
1. `integration-workos.php` manually requires `Bootstrap.php` (no autoloader yet)
20-
2. `Bootstrap::set_plugin_file()` registers activation/deactivation hooks and returns a callback for `plugins_loaded`
21-
3. On `plugins_loaded`, `Bootstrap::load_plugin()` defines constants, loads Composer autoloader, requires global helpers, and boots `Plugin::instance()`
19+
1. `integration-workos.php` manually requires `src/WorkOS/Plugin.php` (no autoloader yet)
20+
2. `Plugin::bootstrap(__FILE__)` stores the plugin file path, registers activation/deactivation hooks, and returns `[$plugin, 'init']` as the callback for `plugins_loaded`
21+
3. On `plugins_loaded`, `Plugin::init()` defines constants, loads the Composer autoloader, requires global helpers, loads the text domain, initializes the DI container, and bootstraps the application
2222

2323
```php
2424
// integration-workos.php
25-
require_once __DIR__ . '/src/WorkOS/Bootstrap.php';
26-
add_action( 'plugins_loaded', WorkOS\Bootstrap::set_plugin_file( __FILE__ ) );
25+
require_once __DIR__ . '/src/WorkOS/Plugin.php';
26+
add_action( 'plugins_loaded', WorkOS\Plugin::bootstrap( __FILE__ ) );
2727
```
2828

2929
### Plugin Singleton
3030

31-
`Plugin::instance()` is the main orchestrator. Its constructor calls:
32-
- `init_hooks()` — registers core WordPress hooks (textdomain loading)
33-
- `init_components()` — boots all subsystems (Admin, Auth, REST, Sync, etc.)
31+
`Plugin::instance()` is a getter that returns the current instance (or `null` if not yet initialized). `Plugin::init()` does the actual work:
32+
- Sets plugin paths and defines constants
33+
- Loads Composer autoloader and prefixed autoloader
34+
- Requires global helper functions
35+
- Calls `initializeContainer()` — sets up the DI container with singletons for `Api\Client`, Options classes, and the `App` facade
36+
- Calls `bootstrapApp()` — runs schema upgrades and registers the main `Controller`
3437

3538
### Constants
3639

37-
Defined in `Bootstrap::load_plugin()`:
40+
Defined in `Plugin::init()`:
3841
- `WORKOS_VERSION` — Plugin version string
3942
- `WORKOS_FILE` — Absolute path to main plugin file
4043
- `WORKOS_DIR` — Plugin directory path (trailing slash)
@@ -47,47 +50,107 @@ Defined in `Bootstrap::load_plugin()`:
4750
- `WORKOS_API_KEY` — API key (overrides DB option)
4851
- `WORKOS_CLIENT_ID` — Client ID (overrides DB option)
4952
- `WORKOS_WEBHOOK_SECRET` — Webhook secret (overrides DB option)
53+
- `WORKOS_ORGANIZATION_ID` — Organization ID (overrides DB option)
54+
- `WORKOS_ENVIRONMENT_ID` — Environment ID (overrides DB option)
55+
- `WORKOS_ENVIRONMENT` — Lock active environment (`production` or `staging`)
56+
57+
Per-environment constants (take priority over generic):
58+
- `WORKOS_PRODUCTION_API_KEY`, `WORKOS_PRODUCTION_CLIENT_ID`, etc.
59+
- `WORKOS_STAGING_API_KEY`, `WORKOS_STAGING_CLIENT_ID`, etc.
5060

5161
## Key Files
5262

5363
| File | Purpose |
5464
|------|---------|
5565
| `integration-workos.php` | Main plugin entry point (minimal — require + hook) |
56-
| `src/WorkOS/Bootstrap.php` | Constants, autoloader, lifecycle hooks |
57-
| `src/WorkOS/Plugin.php` | Singleton orchestrator, boots all subsystems |
66+
| `src/WorkOS/Plugin.php` | Bootstrap, constants, container init, app boot |
67+
| `src/WorkOS/App.php` | Static facade for the DI container |
5868
| `src/WorkOS/Config.php` | Centralized config with constant overrides |
59-
| `src/WorkOS/Admin/Settings.php` | Admin settings page |
60-
| `src/WorkOS/Admin/UserList.php` | Admin user list integration |
61-
| `src/WorkOS/Auth/Login.php` | SSO login flow |
62-
| `src/WorkOS/Auth/Registration.php` | User registration |
69+
| `src/WorkOS/Controller.php` | Main controller, registers all feature controllers |
70+
| `src/WorkOS/Contracts/Container.php` | DI container (di52-based) |
71+
| `src/WorkOS/Contracts/Controller.php` | Abstract base controller with `isActive()` |
72+
| `src/WorkOS/Contracts/ServiceProvider.php` | Service provider contract |
73+
| **Admin** | |
74+
| `src/WorkOS/Admin/Controller.php` | Admin controller, registers settings/user list/onboarding/diagnostics |
75+
| `src/WorkOS/Admin/Settings.php` | Admin settings page (tabs: Settings, Organization, Users) |
76+
| `src/WorkOS/Admin/UserList.php` | Admin user list integration (WorkOS columns) |
77+
| `src/WorkOS/Admin/UserProfile.php` | User profile page WorkOS metadata |
78+
| `src/WorkOS/Admin/AdminBar.php` | Admin bar environment badge |
79+
| `src/WorkOS/Admin/DiagnosticsPage.php` | System diagnostics page |
80+
| `src/WorkOS/Admin/OnboardingPage.php` | Onboarding wizard UI |
81+
| `src/WorkOS/Admin/OnboardingAjax.php` | Onboarding wizard AJAX handlers |
82+
| **Auth** | |
83+
| `src/WorkOS/Auth/Controller.php` | Auth controller (login, registration, password reset, redirects) |
84+
| `src/WorkOS/Auth/Login.php` | SSO login flow (redirect + headless modes) |
85+
| `src/WorkOS/Auth/LoginBypass.php` | Login bypass (`?fallback=1`) when WorkOS is unavailable |
86+
| `src/WorkOS/Auth/Registration.php` | User registration redirect |
6387
| `src/WorkOS/Auth/PasswordReset.php` | Password reset flow |
64-
| `src/WorkOS/REST/TokenAuth.php` | REST API token authentication |
65-
| `src/WorkOS/Webhook/Receiver.php` | Webhook event processing |
88+
| `src/WorkOS/Auth/Redirect.php` | Role-based login redirects |
89+
| `src/WorkOS/Auth/LogoutRedirect.php` | Role-based logout redirects |
90+
| **Organization** | |
91+
| `src/WorkOS/Organization/Controller.php` | Organization controller |
92+
| `src/WorkOS/Organization/Manager.php` | Organization CRUD and caching |
93+
| `src/WorkOS/Organization/EntitlementGate.php` | Require org membership for login |
94+
| **Activity Log** | |
95+
| `src/WorkOS/ActivityLog/Controller.php` | Activity log controller |
96+
| `src/WorkOS/ActivityLog/EventLogger.php` | Logs WordPress events to local DB table |
97+
| `src/WorkOS/ActivityLog/AdminPage.php` | Activity log viewer in admin |
98+
| **UI (Login Button)** | |
99+
| `src/WorkOS/UI/Controller.php` | UI controller, registers shortcode/block/widget |
100+
| `src/WorkOS/UI/Shortcode.php` | `[workos_login]` shortcode |
101+
| `src/WorkOS/UI/Block.php` | Gutenberg block registration |
102+
| `src/WorkOS/UI/Widget.php` | Classic widget |
103+
| `src/WorkOS/UI/Renderer.php` | Shared login button renderer |
104+
| `src/WorkOS/UI/Ajax.php` | AJAX handlers for login button |
105+
| **Options** | |
106+
| `src/WorkOS/Options/Options.php` | Abstract options base class |
107+
| `src/WorkOS/Options/Production.php` | Production environment options |
108+
| `src/WorkOS/Options/Staging.php` | Staging environment options |
109+
| `src/WorkOS/Options/Global_Options.php` | Environment-independent options |
110+
| **API** | |
111+
| `src/WorkOS/Api/Client.php` | WorkOS API client wrapper |
112+
| **Sync** | |
113+
| `src/WorkOS/Sync/Controller.php` | Sync controller |
66114
| `src/WorkOS/Sync/UserSync.php` | User sync (inbound/outbound) |
67115
| `src/WorkOS/Sync/RoleMapper.php` | WorkOS role → WP role mapping |
68-
| `src/WorkOS/Sync/DirectorySync.php` | Directory sync |
69-
| `src/WorkOS/Sync/AuditLog.php` | Audit logging |
70-
| `src/WorkOS/Organization/Manager.php` | Organization management |
116+
| `src/WorkOS/Sync/DirectorySync.php` | Directory sync (SCIM) |
117+
| `src/WorkOS/Sync/AuditLog.php` | Forward WP events to WorkOS Audit Logs |
118+
| `src/WorkOS/Sync/AuditLogController.php` | Audit log controller |
119+
| **REST** | |
120+
| `src/WorkOS/REST/Controller.php` | REST controller |
121+
| `src/WorkOS/REST/TokenAuth.php` | REST API Bearer token authentication |
122+
| **Webhook** | |
123+
| `src/WorkOS/Webhook/Controller.php` | Webhook controller |
124+
| `src/WorkOS/Webhook/Receiver.php` | Webhook event processing and signature verification |
125+
| **CLI** | |
126+
| `src/WorkOS/CLI/Controller.php` | CLI controller, registers WP-CLI commands |
127+
| `src/WorkOS/CLI/StatusCommand.php` | `wp workos status` command |
128+
| `src/WorkOS/CLI/UserCommand.php` | `wp workos user` commands |
129+
| `src/WorkOS/CLI/OrgCommand.php` | `wp workos org` commands |
130+
| `src/WorkOS/CLI/SyncCommand.php` | `wp workos sync` commands |
131+
| **Database** | |
71132
| `src/WorkOS/Database/Schema.php` | DB schema creation and upgrades |
133+
| **Helpers** | |
72134
| `src/includes/functions-helpers.php` | Global `workos()` and `workos_log()` helpers |
135+
| **Build** | |
73136
| `composer.json` | PHP dependencies |
74-
| `package.json` | Node.js dependencies |
137+
| `package.json` | JS dependencies (bun) |
75138

76139
## Build System
77140

78141
### Requirements
79142

80143
- Node.js >= 20 (see `.nvmrc`)
81-
- npm
144+
- bun
82145

83146
### Commands
84147

85148
```bash
86-
npm install # Install dependencies
87-
npm run build # Production build (wp-scripts)
88-
npm run start # Development with watch
89-
npm run lint:php # Lint PHP via PHPCS
90-
npm run lint:php:fix # Auto-fix PHP lint issues
149+
bun install # Install dependencies
150+
bun run build # Production build (wp-scripts)
151+
bun run start # Development with watch
152+
bun run lint:php # Lint PHP via PHPCS
153+
bun run lint:php:fix # Auto-fix PHP lint issues
91154
```
92155

93156
## Testing
@@ -109,7 +172,7 @@ cd ~/workspace/srv/wp-content/plugins
109172
```
110173

111174
- `slic here` registers the current directory as the plugins root
112-
- `slic use workos` selects the workos plugin as the active target
175+
- `slic use integration-workos` selects the plugin as the active target
113176
- `slic composer install` installs PHP dependencies inside the container
114177

115178
### Running Tests
@@ -147,8 +210,28 @@ tests/
147210
└── wpunit/
148211
├── _bootstrap.php # Suite-level bootstrap
149212
├── ConfigTest.php # Config class tests
213+
├── DirectorySyncTest.php # Directory sync tests
214+
├── EntitlementGateTest.php # Entitlement gate tests
215+
├── EventLoggerTest.php # Activity log event logger tests
216+
├── LoginBypassTest.php # Login bypass tests
217+
├── LoginSessionTest.php # Login session tests
218+
├── LoginTokensTest.php # Login tokens tests
219+
├── LogoutRedirectTest.php # Logout redirect tests
220+
├── OnboardingSyncTest.php # Onboarding sync tests
221+
├── OptionsTest.php # Options classes tests
222+
├── OrganizationManagerTest.php # Organization manager tests
223+
├── PasswordResetTest.php # Password reset tests
150224
├── PluginTest.php # Plugin singleton + constants tests
151-
└── UserSyncPushTest.php # Outbound user sync tests
225+
├── RedirectTest.php # Login redirect tests
226+
├── RoleMapperTest.php # Role mapper tests
227+
├── SchemaTest.php # Database schema tests
228+
├── UserSyncDeprovisionTest.php # User deprovisioning tests
229+
├── UserSyncFindOrCreateTest.php # User find-or-create tests
230+
├── UserSyncLinkTest.php # User linking tests
231+
├── UserSyncPushTest.php # Outbound user sync tests
232+
├── UserSyncResyncTest.php # User re-sync tests
233+
├── WebhookReceiverTest.php # Webhook receiver tests
234+
└── WebhookSignatureTest.php # Webhook signature verification tests
152235
```
153236

154237
### Writing Tests

‎README.md‎

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,20 @@ Enterprise identity management for WordPress powered by [WorkOS](https://workos.
1212
- **Directory Sync (SCIM)** — automatic user provisioning and deprovisioning from your identity provider
1313
- **Role Mapping** — map WorkOS organization roles to WordPress roles
1414
- **Organization Management** — local caching of WorkOS organizations with multisite support
15+
- **Entitlement Gate** — require organization membership to log in
1516
- **Webhook Processing** — real-time sync of user, organization, and directory events
1617
- **REST API Authentication** — Bearer token auth for headless/decoupled WordPress
18+
- **Login Button** — shortcode (`[workos_login]`), Gutenberg block, and classic widget
19+
- **Login Bypass** — access the native WordPress login form via `?fallback=1` when WorkOS is unavailable
20+
- **Activity Logging** — local database table with admin viewer for tracking authentication and sync events
1721
- **Audit Logging** — forward WordPress events (login, logout, post changes, user changes) to WorkOS Audit Logs
22+
- **Role-Based Login Redirects** — send users to different URLs after login based on their WordPress role
23+
- **Role-Based Logout Redirects** — send users to different URLs after logout based on their WordPress role
24+
- **Password Reset Integration** — redirect password reset to WorkOS or fall back to WordPress
25+
- **Registration Redirect** — redirect registration to WorkOS AuthKit
26+
- **Admin Bar Badge** — shows the active WorkOS environment (production/staging) in the admin bar
27+
- **Diagnostics Page** — system health checks and configuration status
28+
- **Onboarding Wizard** — guided setup for initial plugin configuration and user sync
1829
- **WP-CLI Commands** — full CLI access for scripting, bulk operations, and diagnostics
1930

2031
## Installation
@@ -70,6 +81,10 @@ The plugin intercepts WordPress's `authenticate` filter and validates credential
7081

7182
When enabled, WordPress native password authentication remains available alongside WorkOS. Password reset and registration forms fall back to WordPress defaults.
7283

84+
### Login Bypass
85+
86+
If WorkOS is down or misconfigured, users can access the native WordPress login form by appending `?fallback=1` to the login URL. This bypasses the WorkOS redirect entirely.
87+
7388
## Webhooks
7489

7590
Configure your WorkOS dashboard to send webhooks to:
@@ -103,13 +118,14 @@ The token is verified using WorkOS JWKS and mapped to a WordPress user via their
103118

104119
## Database Tables
105120

106-
The plugin creates three custom tables on activation:
121+
The plugin creates four custom tables on activation:
107122

108123
| Table | Purpose |
109124
|---|---|
110125
| `{prefix}_workos_organizations` | Cached WorkOS organization data (name, slug, domains) |
111126
| `{prefix}_workos_org_memberships` | User-to-organization memberships with roles |
112127
| `{prefix}_workos_org_sites` | Organization-to-site mapping (multisite) |
128+
| `{prefix}_workos_activity_log` | Local activity log for authentication and sync events |
113129

114130
User linking is stored in standard WordPress usermeta (`_workos_user_id`, `_workos_org_id`, `_workos_last_synced_at`, `_workos_deactivated`).
115131

@@ -283,12 +299,15 @@ All commands that display data support these output formats:
283299

284300
- PHP 7.4+
285301
- Composer
302+
- bun (for JS/CSS assets)
286303
- [slic](https://github.com/developer-starter/slic) (for running tests)
287304

288305
### Setup
289306

290307
```bash
291308
composer install
309+
bun install # Install JS dependencies
310+
bun run build # Build JS/CSS assets
292311
```
293312

294313
### Running Tests
@@ -319,18 +338,20 @@ composer lint:fix
319338
The plugin uses a DI container (di52) with a feature-controller pattern:
320339

321340
```
322-
integration-workos.php # Entry point
323-
src/WorkOS/Plugin.php # Bootstrap, container init
324-
src/WorkOS/Controller.php # Main controller, registers feature controllers
325-
src/WorkOS/Config.php # Centralized config with constant overrides
341+
integration-workos.php # Entry point
342+
src/WorkOS/Plugin.php # Bootstrap, container init
343+
src/WorkOS/Controller.php # Main controller, registers feature controllers
344+
src/WorkOS/Config.php # Centralized config with constant overrides
326345
src/WorkOS/
327-
Admin/Controller.php # Settings UI, user list enhancements
328-
Auth/Controller.php # Login, registration, password reset
329-
Sync/Controller.php # UserSync, RoleMapper, DirectorySync, AuditLog
330-
REST/Controller.php # Bearer token authentication
331-
Webhook/Controller.php # Webhook receiver
332-
Organization/Controller.php # Organization management
333-
CLI/Controller.php # WP-CLI commands
346+
Admin/Controller.php # Settings UI, user list, onboarding, diagnostics
347+
Auth/Controller.php # Login, registration, password reset, redirects
348+
Sync/Controller.php # UserSync, RoleMapper, DirectorySync, AuditLog
349+
REST/Controller.php # Bearer token authentication
350+
Webhook/Controller.php # Webhook receiver
351+
Organization/Controller.php # Organization management, entitlement gate
352+
CLI/Controller.php # WP-CLI commands
353+
UI/Controller.php # Login button (shortcode, block, widget)
354+
ActivityLog/Controller.php # Local activity logging
334355
```
335356

336357
Each controller extends `Contracts\Controller` and implements `isActive()` for conditional activation (e.g., `Admin\Controller` only activates in `is_admin()`, `CLI\Controller` only activates under `WP_CLI`).

0 commit comments

Comments
 (0)