Skip to content

feat: ✨ add support for QR code login#174

Draft
clins1994 wants to merge 9 commits into
beeper:mainfrom
clins1994:line-v372-qr-login
Draft

feat: ✨ add support for QR code login#174
clins1994 wants to merge 9 commits into
beeper:mainfrom
clins1994:line-v372-qr-login

Conversation

@clins1994

Copy link
Copy Markdown
Contributor

Replacement for #124 after GitHub refused reopening the closed PR. This branch is pushed from a Beeper-network fork and includes the conflict-resolution merge from current main.


Fixes #94

Summary

This PR adds LINE QR code login as a new login flow while keeping the existing email/password flow intact.

Although the user-facing change is simple (scan QR), implementation touches multiple layers because LINE’s QR login uses a different protocol path with long-poll state transitions and E2EE login key bootstrap.

Why this is larger than it looks

QR login is not a variant of email login. It requires:

  1. Different LINE endpoints/services (SecondaryQrCodeLoginService + permit-notice long polling)
  2. Multi-step async login state machine (session -> QR -> scan wait -> certificate check -> optional PIN -> finalize)
  3. E2EE secret/public key injection into QR callback URL for keychain unwrap
  4. Request plumbing for QR-specific headers/timeouts (X-Line-Session-ID, X-LST, context-aware long polling)

What changed (by area)

1) Connector login flow wiring

  • Added two explicit flows:
    • QR Code (recommended/default)
    • Email and Password (existing fallback)
  • New LineQRLogin process implementing display-and-wait behavior
  • Reuses shared login finalization path for both email + QR

Files:

  • pkg/connector/connector.go

2) LINE QR protocol client

  • Added QR RPC methods:
    • CreateQRSession
    • CreateQRCode
    • CheckQRCodeVerified(Context)
    • VerifyCertificate
    • CreatePinCode
    • CheckPinCodeVerified(Context)
    • QRCodeLoginV2
  • Added QR response model(s)

Files:

  • pkg/line/methods.go
  • pkg/line/structs.go

3) Transport updates for QR long-polling

  • Extended HMAC POST path with optional options:
    • include/omit x-line-application
    • X-Line-Session-ID
    • X-LST
    • context-aware request
  • Timeout handling for long-poll requests

File:

  • pkg/line/client.go

4) E2EE QR bootstrap support

  • Appends login pubkey + e2ee version to callback URL before rendering QR
  • Exposes base64 public key from secret generation

Files:

  • pkg/line/qr.go (new)
  • pkg/line/secret/secret.go
  • pkg/runner.go

5) Docs

  • README now explains QR flow, PIN fallback, and email-flow caveat

File:

  • README.md

Login flow behavior

  1. User selects QR login
  2. Bridge creates QR session + QR code
  3. Bridge adds E2EE secret/public key to callback URL and displays QR
  4. Bridge waits for mobile scan confirmation
  5. Bridge tries certificate verification:
    • success: complete login directly
    • failure: create/display PIN and wait for PIN verification
  6. Bridge completes qrCodeLoginV2 and stores login metadata

Follow-up commits in this PR

  • 33eab2c: QR login token recovery fixes
  • 54a2f91: QR login key-handling hardening
  • 2f0207c: stale OBS token recovery fix (small isolated bugfix)

Reviewer guide

Recommended review order:

  1. pkg/line/methods.go + pkg/line/client.go (protocol + transport)
  2. pkg/connector/connector.go (bridge login state machine)
  3. E2EE glue (pkg/line/qr.go, pkg/line/secret/secret.go, pkg/runner.go)
  4. README

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@clins1994, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 37 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 26cf60db-935c-4398-9360-963d768ea283

📥 Commits

Reviewing files that changed from the base of the PR and between 95c0b06 and 11e7808.

📒 Files selected for processing (15)
  • .github/workflows/deploy.yml
  • pkg/connector/client.go
  • pkg/connector/connector.go
  • pkg/connector/creategroup.go
  • pkg/connector/e2ee_keys.go
  • pkg/connector/handle_message.go
  • pkg/connector/handlers/handler.go
  • pkg/connector/reaction.go
  • pkg/connector/send_message.go
  • pkg/connector/sync.go
  • pkg/connector/userinfo.go
  • pkg/line/client.go
  • pkg/line/methods.go
  • pkg/line/structs.go
  • pkg/runner.go
📝 Walkthrough

Walkthrough

This PR adds QR-code-based login as the primary authentication flow for the LINE bridge, alongside email/password as a secondary option. It introduces multi-key E2EE infrastructure to support multiple login key derivations, implements the complete LINE QR protocol with session/code/verification/PIN steps, synchronizes token updates with a mutex, and refactors completion helpers to use parameterized login key IDs.

Changes

QR Code Login with Multi-Key E2EE Support

Layer / File(s) Summary
E2EE Key Infrastructure with LoginKeyID
pkg/runner.go, pkg/e2ee/manager.go, pkg/line/secret/secret.go, pkg/line/structs.go
Runner adds loginKeyStore map to track multiple login curve keys by ID and exports LoginUnwrapKeyChainWithKey to unwrap key chains against a specific stored key. SecretResult gains LoginKeyID and PublicKeyBase64 fields. Manager.InitFromLoginKeyChainWithKey delegates key unwrapping to the parameterized runner method. QRCodeResponse struct added for QR server responses.
LINE Client QR Protocol Methods
pkg/line/client.go, pkg/line/methods.go, pkg/line/qr.go
LINE client adds QRLoginBaseURL constant, refactors HMAC POST helper with hmacPostOptions for context and long-polling timeout support, and updates token refresh handling. New exported QR methods: CreateQRSession, CreateQRCode, CheckQRCodeVerified*, VerifyCertificate, CreatePinCode, CheckPinCodeVerified*, QRCodeLoginV2. Helper QRCodeCallbackURLWithE2EESecret enriches callback URLs with E2EE parameters. ClearEncryptedAccessTokenCache invalidates OBS token cache.
Token Synchronization and Recovery
pkg/connector/client.go, pkg/connector/e2ee_keys.go
LineClient adds tokenMu mutex to guard token updates in refreshAndSave. isRefreshRequired expands error detection to include code:10051 and broader patterns. recoverToken wraps refresh and re-login errors together on failure. Connect switches from login-first to refresh-first by calling recoverToken(ctx). ensurePeerKey and ensurePeerKeyByID now use provided context for token recovery and retry on refresh-required errors.
Connector QR Login Orchestration
pkg/connector/connector.go
GetLoginFlows advertises QR Code and Email/Password options. CreateLogin instantiates LineQRLogin for QR flow. New LineQRLogin type implements QR session: Start creates session/code and begins polling, Wait handles verification/certificate validation/PIN transition, Cancel stops polling. Email login refactored to delegate via finishLineLogin helpers. Standalone fetchLoginKeys function refactored to accept loginKeyID and initialize E2EE manager using InitFromLoginKeyChainWithKey.
Auth Failure Recovery and OBS Cache
pkg/connector/handlers/handler.go
tryRecoverClient detects "OBS download failed (401)" error, clears encrypted access token cache, and returns recovered client; existing 401/auth-refresh handling remains for other errors.
User-Facing Documentation
README.md
Login section describes QR code (primary, with first-login PIN and certificate caching) and email/password (secondary). Troubleshooting clarifies QR code does not require LINE email, while email/password flow requires email in account info.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is comprehensive and directly related to the changeset, explaining implementation details, architecture decisions, and affected files.
Linked Issues check ✅ Passed The PR fully addresses linked issue #94: implements QR code login as primary flow while retaining email/password as secondary, with comprehensive protocol and UI support.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing QR code login: protocol methods, transport layer updates, E2EE integration, documentation, and token recovery fixes are all aligned with PR objectives.
Title check ✅ Passed The title 'feat: ✨ add support for QR code login' clearly and specifically describes the main change—adding QR code login support as a new feature, which aligns with the PR's primary objective and the substantial changes across connector, LINE protocol, and E2EE modules.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/connector/connector.go (1)

550-560: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Persist the verified MID into login metadata.

LoadUserLogin rebuilds LineClient.Mid from UserLoginMetadata.Mid, but this metadata is populated from res.Mid while the canonical identity here is already profile.Mid. When QR login omits mid, the stored login reloads with an empty MID after restart even though ul.ID points at the real LINE account.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/connector/connector.go` around lines 550 - 560, The UserLoginMetadata.Mid
is being set from res.Mid but the canonical verified MID is profile.Mid; update
the metadata to persist the verified MID (set meta.Mid = profile.Mid) before
calling fetchLoginKeys and before creating the login via user.NewLogin (ensure
UserLoginMetadata passed to NewLogin contains profile.Mid rather than res.Mid)
so that LineClient.Mid rebuilds correctly on reload; reference
UserLoginMetadata, meta.Mid, profile.Mid, res.Mid, fetchLoginKeys, and
user.NewLogin when making the change.
🧹 Nitpick comments (3)
pkg/connector/handlers/handler.go (3)

36-36: ⚡ Quick win

Extract magic string to a named constant.

The error message literal "OBS download failed (401)" should be extracted as a package-level constant to improve maintainability and make the error contract explicit.

♻️ Proposed constant extraction

At package level:

const obsAuthFailureMsg = "OBS download failed (401)"

Then update the check:

-isOBSAuthFailure := strings.Contains(err.Error(), "OBS download failed (401)")
+isOBSAuthFailure := strings.Contains(err.Error(), obsAuthFailureMsg)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/connector/handlers/handler.go` at line 36, Extract the magic string "OBS
download failed (401)" into a package-level constant (e.g., obsAuthFailureMsg)
and replace the inline literal used in the strings.Contains check inside
handler.go where isOBSAuthFailure is computed; update any other occurrences of
the same literal in the file to reference the new constant so the error contract
is centralized and maintainable (ensure the constant name is unique and placed
at top of the package).

36-40: ⚡ Quick win

Add explanatory comment for the early-return path.

The OBS auth failure recovery bypasses the general 401/refresh/logout handling below (lines 41-48). This non-obvious early return deserves a comment explaining why OBS auth failures are handled differently (the OBS token is derived from the main token; when the main token was already refreshed elsewhere, the cached OBS token becomes stale and just needs cache invalidation, not a full token recovery).

📝 Proposed comment
+// OBS auth failures require clearing the derived OBS token cache rather than
+// refreshing the main token; the main token may have been rotated elsewhere,
+// leaving the OBS cache stale. Clear it and return a fresh client.
 isOBSAuthFailure := strings.Contains(err.Error(), "OBS download failed (401)")
 if isOBSAuthFailure {

Based on learnings from context snippet 2: "The OBS token is derived from the main LINE access token; when the latter is rotated (refresh or re-login) any previously-issued OBS token is invalidated server-side, but the cache here would keep handing it out until its original TTL expires."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/connector/handlers/handler.go` around lines 36 - 40, Add a clear
explanatory comment above the OBS-auth-failure early-return (the
isOBSAuthFailure check) stating that OBS tokens are derived from the main LINE
access token and can become stale when the main token is rotated elsewhere, so
we only clear the OBS token cache (call line.ClearEncryptedAccessTokenCache())
and instantiate a new client (h.NewClient()) instead of invoking the general
401/refresh/logout logic; reference the isOBSAuthFailure variable,
line.ClearEncryptedAccessTokenCache(), and h.NewClient() in the comment to make
the rationale and control-flow choice explicit.

36-40: ⚡ Quick win

Add logging for OBS auth failure recovery path.

The general token recovery path logs a warning on failure (line 45), but the OBS-specific recovery path is silent. For consistency and observability, consider adding a structured log entry when clearing the OBS token cache.

📊 Proposed logging addition
 isOBSAuthFailure := strings.Contains(err.Error(), "OBS download failed (401)")
 if isOBSAuthFailure {
+	h.Log.Debug().Str("error", err.Error()).Msg("Clearing stale OBS token cache after auth failure")
 	line.ClearEncryptedAccessTokenCache()
 	return h.NewClient(), true
 }

As per coding guidelines: "Use zerolog for logging throughout the codebase" and "Do not use Msgf in logging; use Msg with structured fields instead."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/connector/handlers/handler.go` around lines 36 - 40, Add a zerolog
structured warning when the OBS-specific recovery path triggers: detect the OBS
auth failure (isOBSAuthFailure) and log a warning with fields such as error
(err.Error()), action="clearing_encrypted_access_token_cache", and any
identifying info available on the line or handler (e.g., line.ID or h.Name)
before calling line.ClearEncryptedAccessTokenCache() and returning
h.NewClient(); use zerolog.Msg with fields (not Msgf) to match project logging
conventions.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/connector/client.go`:
- Around line 145-146: Multiple goroutines still read/write lc.AccessToken and
lc.RefreshToken without using the new tokenMu, causing races; ensure all token
access is serialized either by centralizing token replacement into a single
locked helper (e.g., create a setTokensLocked method used by refreshAndSave) or
by taking lc.tokenMu in every place that reads/writes tokens (notably tryLogin,
Connect, and the E2EE recovery codepaths) so every read/write of
lc.AccessToken/lc.RefreshToken is protected by lc.tokenMu.

In `@pkg/connector/connector.go`:
- Around line 248-259: The current logic treats any error from
lq.client.VerifyCertificate as a rejection and falls back to creating a PIN;
instead, change the VerifyCertificate error handling so only an explicit
certificate-rejected response triggers the PIN path—propagate any
transport/5xx/unknown errors back to the caller. Concretely, inspect the error
(or returned status) from lq.client.VerifyCertificate and if it indicates
"certificate rejected" (use whatever sentinel/error type the client returns)
then call lq.client.CreatePinCode(lq.AuthSessionID) and proceed; otherwise
return the VerifyCertificate error immediately. Keep references to
lq.client.VerifyCertificate, lq.client.CreatePinCode, QRCodeLoginV2,
finishLineLoginWithLoginKey and lq.AuthSessionID to locate and update the
branch.
- Around line 196-223: CreateQRCode currently returns longPollingMaxCount and
longPollingIntervalSec but the flow ignores them and calls
CheckQRCodeVerifiedContext only once; change the code that calls
lq.client.CreateQRCode to capture the returned longPollingMaxCount and
longPollingIntervalSec and use them to repeatedly call
lq.client.CheckQRCodeVerifiedContext (and likewise use longPolling values for
CheckPinCodeVerifiedContext in the PIN flow) by updating lq.startPoll (or
wrapping the provided checker) so it retries up to longPollingMaxCount times
with longPollingIntervalSec between attempts and only fails after exhausting
those retries or on an explicit error; reference symbols:
lq.client.CreateQRCode, longPollingMaxCount, longPollingIntervalSec,
lq.startPoll, lq.client.CheckQRCodeVerifiedContext, CheckPinCodeVerifiedContext.

In `@pkg/connector/e2ee_keys.go`:
- Around line 112-116: The retry logic around E2EE public-key calls currently
only checks lc.isRefreshRequired(err); change both places (the
NegotiateE2EEPublicKey and GetE2EEPublicKey retry blocks) to also treat
lc.isLoggedOut(err) as recoverable by using a combined condition (e.g., if err
!= nil && (lc.isRefreshRequired(err) || lc.isLoggedOut(err))) and then call
lc.recoverToken(ctx) as before; after successful recoverToken set client =
line.NewClient(lc.AccessToken) and re-invoke the respective method
(NegotiateE2EEPublicKey or GetE2EEPublicKey).

In `@pkg/runner.go`:
- Around line 343-345: LoginUnwrapKeyChainWithKey allows selecting a login key
for unwrap but GenerateConfirmHash still reads the mutable r.loginCurveKey, so
concurrent logins can clobber confirm hashing; add a keyed confirm-hash path
(e.g. GenerateConfirmHashWithKey(loginKeyID int, ...)) that mirrors
LoginUnwrapKeyChainWithKey’s lookup logic and uses the selected key instead of
r.loginCurveKey, update confirmE2EELogin to accept and pass loginKeyID to the
new GenerateConfirmHashWithKey, and then thread that loginKeyID through callers
(including places that call GenerateE2EESecret/GetRunner flows) so confirmation
uses the stable per-key path rather than the mutable r.loginCurveKey.

---

Outside diff comments:
In `@pkg/connector/connector.go`:
- Around line 550-560: The UserLoginMetadata.Mid is being set from res.Mid but
the canonical verified MID is profile.Mid; update the metadata to persist the
verified MID (set meta.Mid = profile.Mid) before calling fetchLoginKeys and
before creating the login via user.NewLogin (ensure UserLoginMetadata passed to
NewLogin contains profile.Mid rather than res.Mid) so that LineClient.Mid
rebuilds correctly on reload; reference UserLoginMetadata, meta.Mid,
profile.Mid, res.Mid, fetchLoginKeys, and user.NewLogin when making the change.

---

Nitpick comments:
In `@pkg/connector/handlers/handler.go`:
- Line 36: Extract the magic string "OBS download failed (401)" into a
package-level constant (e.g., obsAuthFailureMsg) and replace the inline literal
used in the strings.Contains check inside handler.go where isOBSAuthFailure is
computed; update any other occurrences of the same literal in the file to
reference the new constant so the error contract is centralized and maintainable
(ensure the constant name is unique and placed at top of the package).
- Around line 36-40: Add a clear explanatory comment above the OBS-auth-failure
early-return (the isOBSAuthFailure check) stating that OBS tokens are derived
from the main LINE access token and can become stale when the main token is
rotated elsewhere, so we only clear the OBS token cache (call
line.ClearEncryptedAccessTokenCache()) and instantiate a new client
(h.NewClient()) instead of invoking the general 401/refresh/logout logic;
reference the isOBSAuthFailure variable, line.ClearEncryptedAccessTokenCache(),
and h.NewClient() in the comment to make the rationale and control-flow choice
explicit.
- Around line 36-40: Add a zerolog structured warning when the OBS-specific
recovery path triggers: detect the OBS auth failure (isOBSAuthFailure) and log a
warning with fields such as error (err.Error()),
action="clearing_encrypted_access_token_cache", and any identifying info
available on the line or handler (e.g., line.ID or h.Name) before calling
line.ClearEncryptedAccessTokenCache() and returning h.NewClient(); use
zerolog.Msg with fields (not Msgf) to match project logging conventions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f0849f30-f280-46b1-a2ad-dd352ededd41

📥 Commits

Reviewing files that changed from the base of the PR and between 2914bdb and 95c0b06.

📒 Files selected for processing (12)
  • README.md
  • pkg/connector/client.go
  • pkg/connector/connector.go
  • pkg/connector/e2ee_keys.go
  • pkg/connector/handlers/handler.go
  • pkg/e2ee/manager.go
  • pkg/line/client.go
  • pkg/line/methods.go
  • pkg/line/qr.go
  • pkg/line/secret/secret.go
  • pkg/line/structs.go
  • pkg/runner.go
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lint with 1.25
🧰 Additional context used
📓 Path-based instructions (3)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Use go fmt for code formatting across all Go files
Use goimports with -local "github.com/highesttt/matrix-line-messenger" flag to group project-local imports correctly
Use zerolog for logging throughout the codebase
Do not use Msgf in logging; use Msg with structured fields instead
Use Stringer interface where applicable in Go code

Files:

  • pkg/connector/handlers/handler.go
  • pkg/line/structs.go
  • pkg/line/qr.go
  • pkg/e2ee/manager.go
  • pkg/line/secret/secret.go
  • pkg/line/client.go
  • pkg/connector/e2ee_keys.go
  • pkg/runner.go
  • pkg/connector/client.go
  • pkg/line/methods.go
  • pkg/connector/connector.go
**/!(ltsm)/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/!(ltsm)/**/*.go: Run staticcheck on all Go files excluding pkg/ltsm package (transpiled WASM code)
Run go vet on all Go files excluding pkg/ltsm package (transpiled WASM code)

Files:

  • pkg/connector/handlers/handler.go
  • pkg/line/structs.go
  • pkg/line/qr.go
  • pkg/e2ee/manager.go
  • pkg/line/secret/secret.go
  • pkg/line/client.go
  • pkg/connector/e2ee_keys.go
  • pkg/runner.go
  • pkg/connector/client.go
  • pkg/line/methods.go
  • pkg/connector/connector.go
pkg/connector/connector.go

📄 CodeRabbit inference engine (AGENTS.md)

Implement bridgev2.NetworkConnector and bridgev2.NetworkAPI interfaces in the connector package for bridge logic

Files:

  • pkg/connector/connector.go
🧠 Learnings (2)
📚 Learning: 2026-05-29T10:13:37.093Z
Learnt from: CR
Repo: beeper/matrix-line-messenger PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-29T10:13:37.093Z
Learning: Implement proactive token refresh in LineClient based on server-provided duration with automatic recovery on expiry

Applied to files:

  • pkg/line/client.go
  • pkg/connector/client.go
📚 Learning: 2026-05-29T10:13:37.093Z
Learnt from: CR
Repo: beeper/matrix-line-messenger PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-05-29T10:13:37.093Z
Learning: Applies to pkg/connector/connector.go : Implement `bridgev2.NetworkConnector` and `bridgev2.NetworkAPI` interfaces in the connector package for bridge logic

Applied to files:

  • pkg/connector/connector.go
🔇 Additional comments (2)
README.md (1)

286-294: LGTM!

Also applies to: 316-319

pkg/connector/handlers/handler.go (1)

36-40: Verify the OBS error message format (and scope the cache-clear fragility).

DownloadOBSWithSIDOptions formats non-200 responses as fmt.Errorf("OBS download failed (%d): %s", resp.StatusCode, ...), so for HTTP 401 the error string includes the substring OBS download failed (401) and the cache-clear path will trigger for this download code path. Even if that exact substring ever changed, tryRecoverClient still attempts RecoverToken whenever err.Error() contains "401"—so only line.ClearEncryptedAccessTokenCache() would be at risk.
Refactor to avoid brittle string matching by returning a typed error that carries the HTTP status code (so callers can errors.As on it).

			> Likely an incorrect or invalid review comment.

Comment thread pkg/connector/client.go
Comment thread pkg/connector/connector.go
Comment thread pkg/connector/connector.go Outdated
Comment thread pkg/connector/e2ee_keys.go Outdated
Comment thread pkg/runner.go

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@clins1994 clins1994 marked this pull request as draft June 7, 2026 06:51
@clins1994

Copy link
Copy Markdown
Contributor Author

in light of coderabbitai's comments i'll move this pr to draft. need to have another look at it eventually

@clins1994 clins1994 changed the title Add QR code login feat: ✨ add support for QR code login Jun 7, 2026
@clins1994

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

feat: ✨ qr code login

1 participant