f21fa5b5e8
Commilitia Drop:自托管的跨设备剪贴板同步与点对点文件传输。 - 后端 Go(chi / SQLite WAL / SSE Hub / WebRTC signaling + 状态机 / Relay ring buffer),编译进单个 distroless 镜像(前端 go:embed)。 - 前端 React + TanStack Router + Zustand,自实现 SSE + WebRTC P2P,NAT 受阻时回退服务端中继;聚珍(Juzhen)CJK 综合排版。 - 桌面端 Wails v2(macOS / Windows),瘦客户端复用 web。 - 鉴权 OIDC PKCE(自建 Casdoor 等),refresh_token 信封加密存系统密钥库;iOS Shortcut 用 HS256 scoped token。 架构文档与变更记录见 docs 分支(PROJECT_BRIEF / FRONTEND_DESIGN / CHANGELOG)。 本次为公开发布初始提交:完整开发历史(含部署细节)留存于私有归档,公开仓库自此干净起步。
57 lines
1.8 KiB
Go
57 lines
1.8 KiB
Go
package platform
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// FetchOAuthConfig pulls the provider coordinates from the cdrop backend's
|
|
// /api/auth/config. The desktop reuses the same OAuth client as the web app
|
|
// (the client_id published there) and runs its own loopback PKCE flow against
|
|
// the provider, instead of the browser's in-page redirect + /api/auth/exchange
|
|
// proxy. apiBase is the backend origin, e.g. https://drop.commilitia.net.
|
|
func FetchOAuthConfig(ctx context.Context, apiBase string) (OAuthConfig, error) {
|
|
endpoint := strings.TrimRight(apiBase, "/") + "/api/auth/config"
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
|
if err != nil {
|
|
return OAuthConfig{}, fmt.Errorf("oauth: build config request: %w", err)
|
|
}
|
|
req.Header.Set("Accept", "application/json")
|
|
|
|
client := &http.Client{Timeout: 15 * time.Second}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return OAuthConfig{}, fmt.Errorf("oauth: fetch config: %w", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
return OAuthConfig{}, fmt.Errorf("oauth: config endpoint status %d", resp.StatusCode)
|
|
}
|
|
|
|
var c struct {
|
|
AuthorizeURL string `json:"authorize_url"`
|
|
TokenURL string `json:"token_url"`
|
|
ClientID string `json:"client_id"`
|
|
Scopes string `json:"scopes"`
|
|
}
|
|
if err := json.NewDecoder(resp.Body).Decode(&c); err != nil {
|
|
return OAuthConfig{}, fmt.Errorf("oauth: decode config: %w", err)
|
|
}
|
|
|
|
cfg := OAuthConfig{
|
|
AuthorizeURL: c.AuthorizeURL,
|
|
TokenURL: c.TokenURL,
|
|
ClientID: c.ClientID,
|
|
Scopes: c.Scopes,
|
|
}
|
|
if cfg.AuthorizeURL == "" || cfg.TokenURL == "" || cfg.ClientID == "" {
|
|
return OAuthConfig{}, errors.New("oauth: backend config missing authorize_url / token_url / client_id")
|
|
}
|
|
return cfg, nil
|
|
}
|