Framework-agnostic OAuth integration for AT Protocol (Bluesky) applications.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Transparent re-auth on issuer mismatch in quick-connect (v2.7.2)

+24 -9
+10
CHANGELOG.md
··· 2 2 3 3 All notable changes to this project will be documented in this file. 4 4 5 + ## [2.7.2] - 2026-02-15 6 + 7 + ### Fixed 8 + 9 + - **Transparent re-auth on issuer mismatch**: When "Connect with Bluesky" is 10 + used by someone whose PDS has a different auth server (e.g., self-hosted PDS), 11 + the callback now automatically re-authorizes through the correct auth server 12 + using the user's resolved handle. The user is transparently redirected to 13 + their PDS's auth server instead of seeing an error. 14 + 5 15 ## [2.7.1] - 2026-02-15 6 16 7 17 ### Fixed
+2 -2
deno.json
··· 1 1 { 2 2 "$schema": "https://jsr.io/schema/config-file.v1.json", 3 3 "name": "@tijs/atproto-oauth", 4 - "version": "2.7.1", 4 + "version": "2.7.2", 5 5 "license": "MIT", 6 6 "exports": "./mod.ts", 7 7 "publish": { ··· 16 16 }, 17 17 "imports": { 18 18 "@std/assert": "jsr:@std/assert@1.0.16", 19 - "@tijs/oauth-client-deno": "jsr:@tijs/oauth-client-deno@5.0.0", 19 + "@tijs/oauth-client-deno": "jsr:@tijs/oauth-client-deno@5.0.1", 20 20 "@tijs/atproto-sessions": "jsr:@tijs/atproto-sessions@2.1.0", 21 21 "@tijs/atproto-storage": "jsr:@tijs/atproto-storage@0.1.1", 22 22 "@atproto/syntax": "npm:@atproto/syntax@0.3.0"
+12 -7
src/routes.ts
··· 305 305 }); 306 306 } catch (error) { 307 307 // Issuer mismatch: the auth server used (e.g. bsky.social) is not 308 - // authoritative for this user's PDS. Redirect back to login with 309 - // a hint to enter their handle instead of using quick-connect. 310 - if (error instanceof IssuerMismatchError) { 311 - logger.warn( 312 - "Issuer mismatch — user's PDS uses a different auth server", 313 - { expected: error.expected, actual: error.actual }, 308 + // authoritative for this user's PDS. If we discovered the user's 309 + // handle, re-authorize through their correct auth server transparently. 310 + if (error instanceof IssuerMismatchError && error.handle) { 311 + logger.info( 312 + "Issuer mismatch — re-authorizing through correct auth server", 313 + { 314 + expected: error.expected, 315 + actual: error.actual, 316 + handle: error.handle, 317 + }, 314 318 ); 319 + const loginUrl = `/login?handle=${encodeURIComponent(error.handle)}`; 315 320 return new Response(null, { 316 321 status: 302, 317 - headers: { Location: "/?auth_error=issuer_mismatch" }, 322 + headers: { Location: loginUrl }, 318 323 }); 319 324 } 320 325