Skip to main content

Google (sign-in and Meet)

The backend uses Google for two unrelated things with two different OAuth clients. Mixing them up is the most common setup mistake.

Sign-in (app users)Meet (staff, online events)
WhoMen using the mobile app, web app or websiteStaff organisers in the Admin CRM
Consent screenExternalInternal (Workspace only)
ClientsWeb, iOS, Android (one Android client per signing certificate)One web client
EnvGOOGLE_SIGNIN_CLIENT_IDS (comma-separated)GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET, GOOGLE_OAUTH_REDIRECT_URIS, GOOGLE_TOKEN_KEY
CodeEMAW/social_auth.py, EMAW/google_identity.py, model SocialIdentityevents/google_meet.py, events/google_views.py, models GoogleAccount, MeetSpace, MeetParticipant
EndpointsPOST /rest/auth/google/, POST/DELETE /rest/auth/google/link/, GET /rest/auth/identities//rest/events/staff/google/, …/google/connect/, …/google/callback/
Runbookdocs/GOOGLE_SIGN_IN_SETUP.mdevents/README.md ("Recurring events, leaders, Google Meet")

Sign-in​

The client obtains a Google ID token on the device or in the browser (Google Identity Services on the web; @react-native-google-signin/google-signin on mobile) and posts it to /rest/auth/google/. The backend verifies the token's audience against GOOGLE_SIGNIN_CLIENT_IDS, then signs in or creates the account, auto-linking by hashed email. An unverified account is activated and its password cleared. With no client ids configured, Google sign-in is off and the clients hide their buttons.

Each frontend origin must be an Authorized JavaScript origin on the web client. Android needs no client id in the app: it is matched by package name and SHA-1, so register the debug keystore's SHA-1 and each EAS build credential's SHA-1 as separate Android clients. A native rebuild (not an OTA update) is needed when the mobile client ids change.

Meet​

Staff connect their own Workspace Google account once (google/connect/ opens the OAuth popup; /google/callback in the admin app lands it). Tokens are encrypted with GOOGLE_TOKEN_KEY and stored in GoogleAccount. For an online event the backend then creates a Meet space, calendar invites and recordings as the organiser, and fetch_recent_meet_attendance (beat, every 30 min) pulls attendance into MeetParticipant.

GOOGLE_TOKEN_KEY defaults to a derivation of SECRET_KEY: rotating SECRET_KEY without setting an explicit token key means every staff member must reconnect Google. With the client unset, Meet features are off.