mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2025-12-06 02:30:47 -08:00
* 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.
78 lines
2.3 KiB
Markdown
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 ✓
|