Google Drive sync requires OAuth credentials from Google Cloud Console.
- Go to Google Cloud Console
- Create a new project (or select an existing one)
- Enable the Google Drive API (APIs & Services > Library)
- Go to APIs & Services > Credentials
- Click Create Credentials > OAuth client ID
- Configure the consent screen if prompted (External, app name: ThinkUtils)
- Application type: Desktop app
- Name: ThinkUtils Desktop
- Click Create
In your OAuth client settings, add:
http://localhost:8765/callback
The ID is supplied at build time, not committed:
THINKUTILS_GOOGLE_CLIENT_ID="YOUR_CLIENT_ID.apps.googleusercontent.com" \
npm run tauri build::: warning There is no client secret, deliberately A desktop binary cannot keep a secret. Anything compiled in is readable by anyone holding the binary — which is exactly how this project's first client secret ended up public, in the initial commit.
ThinkUtils is a public client using PKCE, which is Google's own guidance for installed apps. PKCE is what protects the exchange: the verifier is generated per authorisation, never leaves the process, and an intercepted authorisation code is useless without it. A shipped secret would add nothing an attacker cannot read, while creating something that has to be rotated when it leaks.
If Google's console offers you a secret for a Desktop app client, you can ignore it. Do not add it to the build. :::
A test asserts set_client_secret never appears in sync.rs, so re-adding one
to work around an auth error fails CI rather than shipping.
- User clicks Login — opens Google OAuth in browser
- User authorizes ThinkUtils for Google Drive access
- OAuth redirects to
localhost:8765/callback - App exchanges the auth code for a token, proving possession of the PKCE verifier it generated in step 1
- Settings sync as
thinkutils_settings.jsonin Google Drive root
- Access tokens stored locally in
~/.config/thinkutils/sync_state.json - Only the Google Drive File scope is requested (not full Drive access)
- Tokens are never transmitted except to Google's OAuth servers
| Problem | Solution |
|---|---|
| "Invalid client" error | Verify Client ID and Secret; check redirect URI in Cloud Console |
| "Access denied" error | Ensure Google Drive API is enabled; check consent screen config |
| Callback timeout | Ensure port 8765 is not blocked by firewall |