# Google Play Closed Testing — server-side setup Deze functionaliteit beheert **distributietoegang** tot de Android-app via Google Play Closed Testing. Het vervangt **niet** de bestaande app-login of API-autorisatie. ## Architectuur ``` Adminpaneel → backend → Google Cloud Identity Groups API → Google Group ↓ Google Play Closed Testing track ``` - Gebruikers worden **niet** individueel via de Play Developer API beheerd. - De Closed Testing-track wordt **eenmalig** gekoppeld aan `PLAY_ACCESS_GROUP_EMAIL`. - Het adminpaneel beheert alleen lidmaatschap van die groep. ## Benodigde configuratie **Voorkeur:** vul alles in via het adminpaneel → **Instellingen → Google Play**. Credentials worden versleuteld in de database opgeslagen (zoals OpenSubtitles). Optioneel blijven environment variables werken als fallback (bijv. voor lokale development). ### Velden in Instellingen | Veld | Verplicht | Beschrijving | |------|-----------|--------------| | Project ID | Ja | Google Cloud project ID | | Service account e-mail | Ja | Service account e-mail | | Private key | Ja | PEM private key | | Workspace admin e-mail | Meestal ja | Admin voor domain-wide delegation | | Workspace customer ID | Optioneel | Workspace customer ID | | Play access group ID | Ja | Group resource ID (zonder `groups/` prefix) | | Play access group e-mail | Ja | E-mailadres van de Google Group | | Opt-in URL | Aanbevolen | Publieke Closed Testing opt-in URL | ### Optionele environment variables (fallback) Stel deze alleen in als je géén Settings-UI gebruikt: | Variabele | Beschrijving | |-----------|--------------| | `GOOGLE_CLOUD_PROJECT_ID` | Google Cloud project ID | | `GOOGLE_SERVICE_ACCOUNT_EMAIL` | Service account e-mail | | `GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY` | PEM private key (`\n` als `\\n` in env) | | `PLAY_ACCESS_GROUP_ID` | Group resource ID | | `PLAY_ACCESS_GROUP_EMAIL` | E-mailadres van de Google Group | | `GOOGLE_WORKSPACE_ADMIN_EMAIL` | Admin voor domain-wide delegation | | `GOOGLE_WORKSPACE_CUSTOMER_ID` | Workspace customer ID | | `GOOGLE_PLAY_OPT_IN_URL` | Publieke Closed Testing opt-in URL | | `GOOGLE_PLAY_SYNC_INTERVAL_MS` | Reconciliatie-interval (default: 86400000 = 24u) | ### Waar instellen - **Productie (aanbevolen):** Admin UI → Instellingen → Google Play - **Lokaal fallback:** `apps/master-api/.env` - **Dokploy env:** alleen nodig als je Settings-UI niet wilt gebruiken ## Google Cloud — handmatige stappen ### 1. APIs inschakelen In Google Cloud Console → APIs & Services: - **Cloud Identity Groups API** (`cloudidentity.googleapis.com`) ### 2. Service account aanmaken 1. IAM & Admin → Service Accounts → Create 2. Download JSON key **of** kopieer private key naar `GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY` 3. Noteer `client_email` → `GOOGLE_SERVICE_ACCOUNT_EMAIL` ### 3. Domain-wide delegation (Workspace) Als de group in Google Workspace staat: 1. Service account → Enable Domain-Wide Delegation 2. Google Admin Console → Security → API Controls → Domain-wide delegation 3. Voeg scope toe: `https://www.googleapis.com/auth/cloud-identity.groups` 4. Stel `GOOGLE_WORKSPACE_ADMIN_EMAIL` in op een super admin ### 4. Service account rechten op de group De service account (of geïmpersonateerde admin) moet leden kunnen beheren: - Google Group → **Group member manager** of **Owner** - Of via Cloud Identity met de juiste IAM-rollen ### 5. Google Group aanmaken Maak een **technische ACL-groep** (geen hardcoded naam in code): - Niet publiek vindbaar - Self-join uit - Alleen beheerders beheren leden - Ledenlijst niet zichtbaar voor gewone members - Posten/conversations uit indien mogelijk - Externe accounts alleen toestaan als nodig (bijv. `@gmail.com` testers) Noteer: - Group e-mail → `PLAY_ACCESS_GROUP_EMAIL` - Group ID → `PLAY_ACCESS_GROUP_ID` #### Group ID vinden Via [Cloud Identity Groups API lookup](https://cloud.google.com/identity/docs/reference/rest/v1/groups/lookup): ``` GET https://cloudidentity.googleapis.com/v1/groups:lookup?groupKey.id=GROUP_EMAIL ``` Het veld `name` is bijv. `groups/03abc123` → `PLAY_ACCESS_GROUP_ID=03abc123` ### 6. Google Play Console — Closed Testing koppelen 1. Play Console → app → Testing → Closed testing 2. Maak of open een track 3. Testers → **Google Groups** 4. Voeg `PLAY_ACCESS_GROUP_EMAIL` toe 5. Kopieer de **opt-in URL** → `GOOGLE_PLAY_OPT_IN_URL` ## Gebruik in adminpaneel 1. Ga naar **Kijkers** 2. Per kijker: sectie **Google Play access** - **Google Play email** — het Google-account voor Play (fallback: account-e-mail) - **Store access** — ON/OFF - **Status** — sync-status (ACTIVE, ERROR, …) - **Retry synchronization** — bij ERROR 3. Pagina-acties: - **Sync all** — alle kijkers synchroniseren - **Reconcile** — lokale status vergelijken met Google Group ## Testgebruiker toevoegen 1. Maak kijker aan (of bestaande) 2. Vul Google Play e-mail in (bijv. `user@gmail.com`) 3. Zet **Store access** aan 4. Status wordt **ACTIVE** na succesvolle sync 5. Gebruiker opent `GOOGLE_PLAY_OPT_IN_URL` terwijl ingelogd met hetzelfde Google-account 6. Installeert app via Play Store ## Toegang intrekken 1. Zet **Store access** uit in adminpaneel 2. Backend verwijdert lidmaatschap uit de group 3. Nieuwe installs via Play zijn niet meer mogelijk 4. **Let op:** reeds geïnstalleerde apps blijven op het toestel — app-login/API blijft leidend voor contenttoegang ## Sync & reconciliatie | Lokaal | Google Group | Actie | |--------|--------------|-------| | ON | member | OK | | ON | geen member | toevoegen | | OFF | member | verwijderen | | OFF | geen member | OK | - **Sync all:** past gewenste status toe voor alle kijkers - **Reconcile:** vergelijkt en herstelt afwijkingen - **Scheduled:** elke `GOOGLE_PLAY_SYNC_INTERVAL_MS` (default 24u) ## Foutafhandeling Bij Google API-fouten: - Gewenste instelling blijft bewaard - Status → **ERROR** - Fout staat in admin UI + audit log - Gebruik **Retry synchronization** Audit log tabel: `google_play_access_audit_logs` (geen tokens/keys gelogd). ## API endpoints (admin only) | Method | Route | |--------|-------| | GET | `/api/v1/admin/google-play-access/config` | | PATCH | `/api/v1/admin/viewers/:id/google-play-access` | | POST | `/api/v1/admin/viewers/:id/google-play-access/retry` | | POST | `/api/v1/admin/google-play-access/sync-all` | | POST | `/api/v1/admin/google-play-access/reconcile` | Body PATCH: ```json { "enabled": true, "email": "user@gmail.com" } ``` ## Wat jij nog handmatig moet invullen Stop hier — vul **geen** credentials in deze repo. 1. Maak Google Cloud service account + group + Play Closed Testing-koppeling (stappen hierboven) 2. Open adminpaneel → **Instellingen → Google Play** 3. Vul project, service account, private key, group ID/e-mail en opt-in URL in 4. Opslaan 5. Ga naar **Kijkers** en zet Store access aan voor een testgebruiker Daarna master-api herstarten is alleen nodig als je de nieuwe code net hebt gedeployed.