{"openapi":"3.0.0","paths":{"/api/apps":{"post":{"operationId":"AppsController_create","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAppDto"}}}},"responses":{"201":{"description":"App Secret is returned once and stored only as a bcrypt hash.","content":{"application/json":{"schema":{"example":{"app_id":"11111111-1111-4111-8111-111111111111","app_secret":"generated-app-secret"}}}}},"401":{"description":"Invalid admin API key."}},"summary":"Create consumer app credentials","tags":["Apps"]}},"/api/oauth-credentials":{"post":{"operationId":"OAuthCredentialsController_create","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOAuthCredentialDto"}}}},"responses":{"201":{"description":"Client Secret is encrypted and never returned."},"401":{"description":"Invalid admin API key."}},"summary":"Create OAuth provider credential","tags":["OAuth Credentials"]},"get":{"operationId":"OAuthCredentialsController_findAll","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Client Secrets are omitted."},"401":{"description":"Invalid admin API key."}},"summary":"List OAuth provider credentials","tags":["OAuth Credentials"]}},"/api/oauth-credentials/{oauthCredentialId}":{"get":{"operationId":"OAuthCredentialsController_findOne","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"oauthCredentialId","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"Client Secret is omitted."},"401":{"description":"Invalid admin API key."},"404":{"description":"OAuth credential not found."}},"summary":"Get OAuth provider credential","tags":["OAuth Credentials"]},"patch":{"operationId":"OAuthCredentialsController_update","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"oauthCredentialId","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOAuthCredentialDto"}}}},"responses":{"200":{"description":"Updated credential without Client Secret."},"401":{"description":"Invalid admin API key."},"404":{"description":"OAuth credential not found."}},"summary":"Update OAuth provider credential","tags":["OAuth Credentials"]},"delete":{"operationId":"OAuthCredentialsController_remove","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"oauthCredentialId","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"OAuth credential deleted."},"401":{"description":"Invalid admin API key."},"404":{"description":"OAuth credential not found."}},"summary":"Delete OAuth provider credential","tags":["OAuth Credentials"]}},"/api/auth-sessions":{"post":{"operationId":"AuthSessionsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAuthSessionDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"example":{"auth_session_id":"33333333-3333-4333-8333-333333333333","auth_url":"https://gateway.example.com/auth/google/start?session_id=33333333-3333-4333-8333-333333333333"}}}}},"401":{"description":"Invalid App Secret."}},"security":[{"app-secret":[]}],"summary":"Start OAuth2 connection session","tags":["Auth Sessions"]}},"/api/auth-sessions/{authSessionId}/status":{"get":{"operationId":"AuthSessionsController_getStatus","parameters":[{"name":"authSessionId","required":true,"in":"path","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"example":{"status":"completed"}}}}},"401":{"description":"Invalid App Secret."}},"security":[{"app-secret":[]}],"summary":"Poll OAuth2 connection session status","tags":["Auth Sessions"]}},"/auth/google/start":{"get":{"operationId":"GoogleController_start","parameters":[{"name":"session_id","required":true,"in":"query","schema":{"format":"uuid","type":"string"}}],"responses":{"302":{"description":"Redirects to Google OAuth2."}},"summary":"Redirect browser to Google authorization page","tags":["Google OAuth2"]}},"/auth/google/callback":{"get":{"operationId":"GoogleController_callback","parameters":[{"name":"code","required":false,"in":"query","schema":{"type":"string"}},{"name":"state","required":true,"in":"query","schema":{"type":"string"}},{"name":"error","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"302":{"description":"Redirects back to WordPress admin."}},"summary":"Receive Google OAuth2 callback","tags":["Google OAuth2"]}},"/api/apps/{appId}/providers/google/token":{"get":{"operationId":"GoogleController_getToken","parameters":[{"name":"appId","required":true,"in":"path","schema":{"format":"uuid","type":"string"}},{"name":"oauth_credential_id","required":true,"in":"query","schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"description":"Refresh token is never returned.","content":{"application/json":{"schema":{"example":{"access_token":"temporary-google-access-token","token_type":"Bearer","expires_in":3600}}}}},"401":{"description":"Invalid App Secret."}},"security":[{"app-secret":[]}],"summary":"Issue temporary Google Drive access token","tags":["Google OAuth2"]}},"/api/users/login":{"post":{"description":"Consumer apps must authenticate themselves with app_id and app_secret before exchanging user email and password for a scoped user token.","operationId":"UsersController_login","parameters":[{"name":"x-app-id","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginUserDto"}}}},"responses":{"200":{"description":"Returns a user bearer token scoped to the authenticated app.","content":{"application/json":{"schema":{"example":{"access_token":"signed-user-jwt","token_type":"Bearer","expires_in":28800,"user":{"user_id":"11111111-1111-4111-8111-111111111111","name":"Usuario Principal","email":"usuario@example.com","phone":"5514997068523","is_active":true,"is_admin":false,"created_at":"2026-06-08T12:00:00.000Z","updated_at":"2026-06-08T12:00:00.000Z"}}}}}},"401":{"description":"Invalid app credentials or user credentials."}},"security":[{"app-secret":[]}],"summary":"Authenticate unified user credentials","tags":["Users"]}},"/api/users/me":{"get":{"description":"Consumer apps use this endpoint to verify a user JWT against the same app that issued it.","operationId":"UsersController_me","parameters":[{"name":"x-app-authorization","in":"header","description":"Bearer APP_SECRET issued when the consumer app is created.","required":true,"schema":{"type":"string"}},{"name":"x-app-id","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Returns the authenticated user profile.","content":{"application/json":{"schema":{"example":{"user_id":"11111111-1111-4111-8111-111111111111","name":"Usuario Principal","email":"usuario@example.com","phone":"5514997068523","is_active":true,"is_admin":false,"created_at":"2026-06-08T12:00:00.000Z","updated_at":"2026-06-08T12:00:00.000Z"}}}}},"401":{"description":"Invalid user token."}},"security":[{"user-token":[]}],"summary":"Validate unified user token","tags":["Users"]}},"/api/users":{"post":{"operationId":"AdminUsersController_create[0]","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserDto"}}}},"responses":{"201":{"description":"Created user."},"401":{"description":"Invalid admin API key."},"409":{"description":"User email already exists."}},"summary":"Create unified user login credentials","tags":["Users"]},"get":{"operationId":"AdminUsersController_findAll[0]","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Password hashes are omitted."},"401":{"description":"Invalid admin API key."}},"summary":"List unified users","tags":["Users"]}},"/admin/users":{"post":{"operationId":"AdminUsersController_create[1]","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserDto"}}}},"responses":{"201":{"description":"Created user."},"401":{"description":"Invalid admin API key."},"409":{"description":"User email already exists."}},"summary":"Create unified user login credentials","tags":["Users"]},"get":{"operationId":"AdminUsersController_findAll[1]","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Password hashes are omitted."},"401":{"description":"Invalid admin API key."}},"summary":"List unified users","tags":["Users"]}},"/api/users/{userId}":{"patch":{"operationId":"AdminUsersController_update[0]","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":"Updated user."},"401":{"description":"Invalid admin API key."},"404":{"description":"User not found."},"409":{"description":"User email already exists."}},"summary":"Update unified user","tags":["Users"]},"delete":{"operationId":"AdminUsersController_remove[0]","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":"User deleted."},"401":{"description":"Invalid admin API key."},"404":{"description":"User not found."}},"summary":"Delete unified user","tags":["Users"]}},"/admin/users/{userId}":{"patch":{"operationId":"AdminUsersController_update[1]","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":"Updated user."},"401":{"description":"Invalid admin API key."},"404":{"description":"User not found."},"409":{"description":"User email already exists."}},"summary":"Update unified user","tags":["Users"]},"delete":{"operationId":"AdminUsersController_remove[1]","parameters":[{"name":"x-admin-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":"User deleted."},"401":{"description":"Invalid admin API key."},"404":{"description":"User not found."}},"summary":"Delete unified user","tags":["Users"]}}},"info":{"title":"Actio Auth Gateway API","description":"API-only OAuth2 gateway.Consumer apps use an App Secret; administrative endpoints use x-admin-api-key.","version":"0.1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"admin-api-key":{"type":"apiKey","in":"header","name":"x-admin-api-key"},"app-secret":{"scheme":"bearer","bearerFormat":"App Secret","type":"http","description":"App Secret issued when the consumer app is created."},"user-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"Unified user access token issued by /api/users/login."}},"schemas":{"CreateAppDto":{"type":"object","properties":{"name":{"type":"string","example":"WordPress site principal"}},"required":["name"]},"CreateOAuthCredentialDto":{"type":"object","properties":{"client_id":{"type":"string","example":"google-client-id.apps.googleusercontent.com"},"client_secret":{"type":"string","example":"google-client-secret","writeOnly":true},"type":{"type":"string","enum":["google"],"example":"google"},"application":{"type":"string","example":"Actio Backup"}},"required":["client_id","client_secret","type","application"]},"UpdateOAuthCredentialDto":{"type":"object","properties":{"client_id":{"type":"string","example":"google-client-id.apps.googleusercontent.com"},"client_secret":{"type":"string","example":"new-google-client-secret","writeOnly":true},"type":{"type":"string","enum":["google"],"example":"google"},"application":{"type":"string","example":"Actio Backup"}}},"CreateAuthSessionDto":{"type":"object","properties":{"app_id":{"type":"string","format":"uuid","example":"11111111-1111-4111-8111-111111111111"},"oauth_credential_id":{"type":"string","format":"uuid","example":"22222222-2222-4222-8222-222222222222"},"provider":{"type":"string","enum":["google"],"example":"google"},"redirect_uri":{"type":"string","example":"https://wordpress.example.com/wp-admin/options-general.php?page=actio-backup"}},"required":["app_id","oauth_credential_id","provider","redirect_uri"]},"LoginUserDto":{"type":"object","properties":{"email":{"type":"string","example":"usuario@example.com","maxLength":190},"password":{"type":"string","example":"senha-forte-com-8-ou-mais-caracteres","minLength":8,"maxLength":128,"writeOnly":true}},"required":["email","password"]},"CreateUserDto":{"type":"object","properties":{"name":{"type":"string","example":"Usuario Principal","minLength":2,"maxLength":120},"email":{"type":"string","example":"usuario@example.com","maxLength":190},"password":{"type":"string","example":"senha-forte-com-8-ou-mais-caracteres","minLength":8,"maxLength":128,"writeOnly":true},"phone":{"type":"object","example":"5514997068523","nullable":true,"maxLength":20},"is_admin":{"type":"boolean","example":false,"default":false}},"required":["name","email","password"]},"UpdateUserDto":{"type":"object","properties":{"name":{"type":"string","example":"Usuario Principal","minLength":2,"maxLength":120},"email":{"type":"string","example":"usuario@example.com","maxLength":190},"password":{"type":"string","example":"nova-senha-com-8-ou-mais-caracteres","minLength":8,"maxLength":128,"writeOnly":true},"phone":{"type":"object","example":"5514997068523","nullable":true,"maxLength":20},"is_active":{"type":"boolean","example":true},"is_admin":{"type":"boolean","example":false}}}}}}