From 0c785831e745d14d2a2979e1e9225e7c7a4d5477 Mon Sep 17 00:00:00 2001 From: scanash00 Date: Thu, 11 Jun 2026 22:34:14 -0800 Subject: [PATCH] extension and auth fixes --- backend/internal/oauth/client.go | 36 +++++ backend/internal/oauth/handler.go | 8 + extension/src/components/popup/App.tsx | 11 +- extension/src/entrypoints/background.ts | 4 + .../src/entrypoints/margin-auth.content.ts | 3 + extension/src/utils/api.ts | 153 +++++++++++------- extension/src/utils/messaging.ts | 1 + extension/src/utils/storage.ts | 6 + 8 files changed, 164 insertions(+), 58 deletions(-) diff --git a/backend/internal/oauth/client.go b/backend/internal/oauth/client.go index 843c1a0..c0b0768 100644 --- a/backend/internal/oauth/client.go +++ b/backend/internal/oauth/client.go @@ -180,6 +180,42 @@ func (c *Client) ResolveDIDToPDS(ctx context.Context, did string) (string, error return "", fmt.Errorf("no PDS found in DID document") } +func (c *Client) ResolveDIDToHandle(ctx context.Context, did string) (string, error) { + var docURL string + if strings.HasPrefix(did, "did:plc:") { + docURL = config.Get().PLCResolveURL(did) + } else if strings.HasPrefix(did, "did:web:") { + domain := strings.TrimPrefix(did, "did:web:") + docURL = fmt.Sprintf("https://%s/.well-known/did.json", domain) + } else { + return "", fmt.Errorf("unsupported DID method: %s", did) + } + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, docURL, nil) + if err != nil { + return "", err + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + var doc struct { + AlsoKnownAs []string `json:"alsoKnownAs"` + } + if err := json.NewDecoder(resp.Body).Decode(&doc); err != nil { + return "", err + } + + for _, aka := range doc.AlsoKnownAs { + if handle := strings.TrimPrefix(aka, "at://"); handle != aka { + return handle, nil + } + } + return "", fmt.Errorf("no handle found in DID document") +} + func (c *Client) GetAuthServerMetadata(ctx context.Context, pds string) (*AuthServerMetadata, error) { resourceURL := fmt.Sprintf("%s/.well-known/oauth-protected-resource", strings.TrimSuffix(pds, "/")) resp, err := http.Get(resourceURL) diff --git a/backend/internal/oauth/handler.go b/backend/internal/oauth/handler.go index 8eb60f7..8abeb9c 100644 --- a/backend/internal/oauth/handler.go +++ b/backend/internal/oauth/handler.go @@ -446,6 +446,14 @@ func (h *Handler) HandleCallback(w http.ResponseWriter, r *http.Request) { _ = newNonce + if pending.Handle == "" { + if resolved, herr := client.ResolveDIDToHandle(ctx, tokenResp.Sub); herr == nil { + pending.Handle = resolved + } else { + logger.Error("Failed to resolve handle for %s: %v", tokenResp.Sub, herr) + } + } + sessionID := generateSessionID() expiresAt := time.Now().Add(7 * 24 * time.Hour) diff --git a/extension/src/components/popup/App.tsx b/extension/src/components/popup/App.tsx index 0a342fc..f3c04a7 100644 --- a/extension/src/components/popup/App.tsx +++ b/extension/src/components/popup/App.tsx @@ -171,6 +171,15 @@ export function App() { } } + async function handleSignIn() { + try { + await browser.permissions.request({ origins: [`${new URL(apiUrl).origin}/*`] }); + } catch { + /* empty */ + } + await browser.tabs.create({ url: `${apiUrl}/login` }); + } + async function loadCurrentTab() { const [tab] = await browser.tabs.query({ active: true, currentWindow: true }); if (tab?.url) { @@ -474,7 +483,7 @@ export function App() { Annotate, highlight, and bookmark the web with your AT Protocol identity.