TidGi-Desktop/docs/features/OAuthFlow.md
lin onetwo b76fc17794
Chore/upgrade (#646)
* docs: deps

* Update dependencies and type usage for AI features

Upgraded multiple dependencies in package.json and pnpm-lock.yaml, including @ai-sdk, @mui, react, and others for improved compatibility and performance. Changed type usage from CoreMessage to ModelMessage in mockOpenAI.test.ts to align with updated ai package. No functional changes to application logic.

* feat: i18n

* feat: test oauth login and use PKCE

* fix: use ollama-ai-provider-v2

* test: github and mock oauth2 login

* test: gitea login

* Refactor context menu cleanup and error message

Moved context menu cleanup for OAuth window to a single closed event handler in Authentication service. Simplified error message formatting in ContextService for missing keys.

* lint: AI fix

* Add tsx as a dev dependency and update scripts

Replaced usage of 'pnpm dlx tsx' with direct 'tsx' command in development and test scripts for improved reliability. Added 'tsx' to devDependencies in package.json.
2025-10-23 23:42:06 +08:00

78 lines
2.3 KiB
Markdown

# Git Service OAuth Flow
We use [`oidc-client-ts`](https://authts.github.io/oidc-client-ts/) which automatically handles PKCE generation, state management, and token exchange.
## Codeberg Setup
To enable one-click login to Codeberg:
1. Go to <https://codeberg.org/user/settings/applications>
2. Create new OAuth2 Application:
- **Application Name**: TidGi Desktop
- **Redirect URI**: `http://127.0.0.1:3012/tidgi-auth/codeberg`
- **⚠️ Do NOT check "Confidential client"** (this allows PKCE)
3. Copy the `Client ID` and `Client Secret`
4. Update `src/constants/oauthConfig.ts`:
Note: `Client Secret` is still necessary even PKCE is used. Otherwise we will get error. Use description to inform user only trust TidGi login oauth app when inside TidGi app's window.
## Configuration
src/constants/oauthConfig.ts
```typescript
export const OAUTH_CONFIGS: Record<Service, IOAuthConfig> = {
github: {
authorizePath: 'https://github.com/login/oauth/authorize',
tokenPath: 'https://github.com/login/oauth/access_token',
userInfoPath: 'https://api.github.com/user',
clientId: '...',
clientSecret: '...',
redirectPath: 'http://127.0.0.1:3012/tidgi-auth/github',
scopes: 'user:email,read:user,repo,workflow',
},
// Gitea/Codeberg use same API structure
gitea: {
authorizePath: '', // User configures: https://gitea.example.com/login/oauth/authorize
// ...
},
};
```
## Implementation
### Window setup
`src/services/windows/handleCreateBasicWindow.ts`
```typescript
window.webContents.on('will-redirect', (event, url) => {
const match = isOAuthRedirect(url); // Check all services
if (match) {
event.preventDefault();
const code = new URL(url).searchParams.get('code');
// Exchange code for token using match.config.tokenPath
// Store token -> triggers userInfo$ update
}
});
```
### Login
`src/components/TokenForm/gitTokenHooks.ts`
```typescript
const oauthUrl = buildOAuthUrl(storageService);
if (oauthUrl) {
location.href = oauthUrl;
}
```
## Flow
1. User clicks login → OAuth page (GitHub/Gitea/Codeberg)
2. OAuth redirects → `http://127.0.0.1:3012/tidgi-auth/{service}?code=xxx`
3. `will-redirect` event → extract code
4. Exchange code for token via `config.tokenPath`
5. Store token → `userInfo$` emits
6. Form updates ✓