add OAUth2.0
This commit is contained in:
@@ -291,8 +291,11 @@ if (!empty($contatto['individuo_id'])) { create }
|
||||
```
|
||||
|
||||
## Prossimi Passi
|
||||
- [DONE] ... (existing items)
|
||||
- Verificare end-to-end su remote: tutte le nuove mass action, mailing list con contatti senza email, ricerca multi-tag
|
||||
- Test end-to-end OAuth con credenziali Google reali (configurare Google Cloud Console, registrare callback URI, ottenere refresh token)
|
||||
- Verificare EmailSetting::isOauth() integration in email sync flow
|
||||
- Verificare StorageRepositoryService::buildGoogleDrive() OAuth fallback con repos esistenti
|
||||
- Verificare GoogleCalendarSyncService::buildClient() OAuth fallback con connessioni esistenti
|
||||
- [DONE] Fix performance: spostata query `VistaReport::where(...)->get()` da `@php` nel partial `table-settings.blade.php` a tutti i 5 controller (prima veniva eseguita 1 query per ogni pagina load per ogni entity, anche senza mai aprire la modale)
|
||||
- [DONE] Rimosse vecchie modal legacy (`#saveVistaModal`, `#colonneModal`, `#vistaListModal`) da `individui` e `gruppi` — duplicate rispetto al nuovo modal unificato
|
||||
- [DONE] Rimosse vecchie funzioni JS (`saveVista()`, `toggleColumn()`, `showSaveVistaModal()`) da `individui` e `gruppi`
|
||||
@@ -380,3 +383,102 @@ if (!empty($contatto['individuo_id'])) { create }
|
||||
**Fix**:
|
||||
1. `VistaReportController@update` (linea 101-103): aggiunto `if ($request->expectsJson()) { return response()->json([...]); }` — così il fetch riceve JSON 200, non un redirect 302.
|
||||
2. Fetch headers in `table-settings.blade.php`: aggiunto `'Accept': 'application/json'` — necessario perché `expectsJson()` controlla l'header `Accept`, non `Content-Type`.
|
||||
|
||||
## 2026-06-15 — Centralized Google OAuth 2.0 System (Gmail, Drive, Calendar)
|
||||
|
||||
**Obiettivo**: Implementare autenticazione OAuth 2.0 centralizzata per Gmail (IMAP/SMTP), Google Drive e Google Calendar come alternativa opzionale all'auth con password, con revoca per-servizio.
|
||||
|
||||
### Files Creati
|
||||
- **Enum** `app/Enums/GoogleService.php` — 3 casi (Gmail, Drive, Calendar) con scope/label/icon/hexColor
|
||||
- **Migration 1** `2026_06_15_000001_create_google_oauth_connections_table.php` — tabella google_oauth_connections
|
||||
- **Migration 2** `2026_06_15_000002_add_auth_method_to_email_settings_table.php` — auth_method a email_settings
|
||||
- **Model** `app/Models/GoogleOAuthConnection.php` — encrypted field accessor/mutator
|
||||
- **Service** `app/Services/GoogleOAuthService.php` — full OAuth flow methods
|
||||
- **Controller** `app/Http/Controllers/GoogleOAuthController.php` — connect/callback/revoke/status
|
||||
- **Routes** in `routes/web.php` — 4 nuove route
|
||||
- **View** `resources/views/google-oauth/status.blade.php`
|
||||
|
||||
### Problemi Risolti
|
||||
1. Filesystem permission: directory 755 (www-data). Script PHP via Apache da storage/app/public/
|
||||
2. routes/web.php root:root 644 -> rename trick
|
||||
3. authorize() method conflict -> rinominato in connect()
|
||||
|
||||
### Architettura
|
||||
- Fallback pattern: Drive/Calendar provano OAuth centralizzata, poi config esistente
|
||||
- Per-service revoca: record separato per servizio (unique su service)
|
||||
- Single callback URI: /auth/google/callback, routing via state
|
||||
- Token encryption: AES-256-CBC + APP_KEY
|
||||
|
||||
### Completato
|
||||
1. ✅ **EmailSetting model** (`app/Models/EmailSetting.php`): `auth_method` in ``, `isOauth()` method, `getOAuthAccessToken()` via `GoogleOAuthService`, `getDecryptedPassword()` returns OAuth token when isOauth, `getDecryptedSmtpPassword()` same, `getImapClient()` returns null for OAuth, `testConnection()` has OAuth path via Webklex\PHPIMAP
|
||||
2. ✅ **EmailController** (`app/Http/Controllers/EmailController.php`): `syncEmails()` redirects to `syncEmailsViaOAuth()`, `connectImap()` redirects to `connectOAuthImap()`, `sendViaImap()` appends `auth_mode=xoauth2` to DSN, added `processWebklexMessage()` helper
|
||||
3. ✅ **StorageRepositoryService** (`app/Services/StorageRepositoryService.php`): `buildGoogleDrive()` tries `GoogleOAuthService::buildClient(GoogleService::Drive)` first, falls back to config. Same for `readGoogleDriveFile()` and `checkGoogleDriveApiStatus()`
|
||||
4. ✅ **GoogleCalendarSyncService** (`app/Services/GoogleCalendarSyncService.php`): `buildClient()` tries `GoogleOAuthService::buildClient(GoogleService::Calendar)` first, falls back to config
|
||||
5. ✅ **Tab Google Services** in `resources/views/impostazioni/index.blade.php` — nav tab + tab-pane with Connect/Revoke per service (Gmail, Drive, Calendar), status badges, alert linking to email tab. Added `auth_method` select in email IMAP tab
|
||||
6. ⏳ **Test end-to-end** — requires user to configure Google Cloud Console (OAuth consent screen, callback URI) and provide credentials
|
||||
|
||||
### Files Modified
|
||||
- `app/Models/EmailSetting.php` — OAuth-aware auth_method, decrypt overrides, IMAP client
|
||||
- `app/Http/Controllers/EmailController.php` — OAuth sync/send/connect paths
|
||||
- `app/Services/StorageRepositoryService.php` — Drive OAuth fallback
|
||||
- `app/Services/GoogleCalendarSyncService.php` — Calendar OAuth fallback
|
||||
- `resources/views/impostazioni/index.blade.php` — Google Services tab + auth_method select
|
||||
|
||||
### Bug Fix
|
||||
- **2026-06-15 — Variable interpolation in str_replace**: In `apply_all_mods.php`, the second argument to `str_replace()` used double quotes, causing PHP to interpolate $fileId, $service, $googleMimeType, $originalBasename as empty strings. Result: method signature `exportGoogleDriveDoc` lost all parameter variable names. Fixed by running a second script that used `preg_replace` to restore the signature. (file -> app/Services/StorageRepositoryService.php)
|
||||
|
||||
|
||||
### Pre-Production Review Fixes
|
||||
|
||||
**2026-06-15 — 4 criticità risolte prima del deploy**
|
||||
|
||||
| # | Problema | File | Fix |
|
||||
|---|----------|------|-----|
|
||||
| 1 | Credenziali Google vuote | `GoogleOAuthService.php:createClient()` | Sostituito `setAuthConfig([client_id:'']` con `setClientId(config(...))`, `setClientSecret(config(...))`, `setRedirectUri(...)`. Rimossi 4 import inutilizzati |
|
||||
| 2 | Route name errato | `google-oauth/status.blade.php:55` | `google.oauth.connect` → `google.oauth.authorize` |
|
||||
| 3 | Metodo inesistente `description()` | `google-oauth/status.blade.php:43` | Sostituito con `label() . ' - ' . scope()`. Layout cambiato da `layouts.app` a `layouts.adminlte` |
|
||||
| 4 | `auth_method` select mancante | `impostazioni/index.blade.php` | Inserito `<select name="auth_method">` all'inizio del card-body in `#email-imap` |
|
||||
| — | `GOOGLE_CLIENT_ID`/`GOOGLE_CLIENT_SECRET` mancanti | `config/services.php`, `.env.example` | Aggiunte sezione google in services.php con `env()`, variabili a `.env.example` |
|
||||
| — | Istruzioni aggiornamento mancanti | `build-dist.sh` | Aggiunta sezione "AGGIORNAMENTO (SERVER ESISTENTE)" con backup, migrate, env vars |
|
||||
|
||||
### Files Review Round
|
||||
- `app/Services/GoogleOAuthService.php` — createClient() legge da config, import puliti
|
||||
- `resources/views/google-oauth/status.blade.php` — route, description, layout fix
|
||||
- `resources/views/impostazioni/index.blade.php` — auth_method select
|
||||
- `config/services.php` — sezione google
|
||||
- `.env.example` — GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
|
||||
- `build-dist.sh` — update instructions
|
||||
|
||||
|
||||
### 2026-06-15 — Cleanup: file inutilizzati, codice morto e import superflui
|
||||
|
||||
**File eliminati (7 backup .bak):**
|
||||
- `MEMORY.md.bak`, `EmailController.php.bak`, `web.php.bak`, `web.php.bak2`
|
||||
- `index.blade.php.bak` (141 KB), `build-dist.sh.bak`, `.env.example.bak`
|
||||
- Directory vuota `tests/Feature/Auth/`
|
||||
|
||||
**Metodi morti rimossi (3):**
|
||||
| Metodo | File | Motivo |
|
||||
|--------|------|--------|
|
||||
| `create()` | `DocumentoController.php` | Nessuna route registrata, view inesistente |
|
||||
| `index()` | `StorageRepositoryController.php` | Nessuna route GET, view inesistente |
|
||||
| `downloadMigrationScript()` | `BackupController.php` | Nessuna route, view inesistente |
|
||||
|
||||
**Import superflui rimossi (20):**
|
||||
- `EmailController.php`: `GoogleService`, `GoogleOAuthService`, `Crypt` (non usati direttamente, logica passa da `EmailSetting` model)
|
||||
- `BackupController.php`: `JsonResponse` (usato dal metodo rimosso)
|
||||
- `StorageRepositoryController.php`: `View` (usato dal metodo rimosso)
|
||||
- `GruppoMembroController.php`: `Individuo`, `Ruolo`
|
||||
- `HomeController.php`: `Notifica`
|
||||
- `ImpostazioniController.php`: `Crypt`
|
||||
- `AuthController.php`: `EmailSetting`, `Address`
|
||||
- `IndividuoController.php`: `Contatto`
|
||||
- `AppSetting.php`: `File`
|
||||
- `EmailAttachment.php`: `Storage`
|
||||
- `Evento.php`: `HasMany`
|
||||
- `ExportHelpPdf.php`: `Storage`
|
||||
- `BackupService.php`: `Notifica`, `Crypt`, `Storage`
|
||||
- `AuthServiceProvider.php`: `Route`
|
||||
|
||||
**Verifica:** Tutti i 14 file modificati passano `php -l`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user