A third party ATProto appview

auth fixes

Changed files
+12 -6
server
services
+12 -6
server/services/auth.ts
··· 136 136 ) { 137 137 userDid = payload.sub; 138 138 139 - // App password tokens from PDS: sub=userDID, aud=pdsDID, scope=com.atproto.appPassPrivileged 139 + // PDS-issued tokens: sub=userDID, aud=pdsDID, scope=com.atproto.access or com.atproto.appPassPrivileged 140 140 // SECURITY: All JWTs MUST have their cryptographic signatures verified 141 - // Even app password tokens need signature verification to prevent forgery 142 141 const pdsDid = payload.aud; 143 142 if ( 144 - payload.scope === 'com.atproto.appPassPrivileged' && 143 + (payload.scope === 'com.atproto.appPassPrivileged' || payload.scope === 'com.atproto.access') && 145 144 pdsDid && 146 145 typeof pdsDid === 'string' && 147 146 pdsDid.startsWith('did:') 148 147 ) { 149 - // For app password tokens, the PDS is the issuer 148 + // For PDS-issued tokens, the PDS is the signer 150 149 signingDid = pdsDid; 151 150 console.log( 152 - `[AUTH] PDS app password token detected for DID: ${payload.sub} (from PDS: ${pdsDid}) - verifying signature` 151 + `[AUTH] PDS token detected (scope: ${payload.scope}) for DID: ${payload.sub} (from PDS: ${pdsDid}) - verifying signature` 153 152 ); 154 153 } 155 154 // OAuth tokens with iss field need signature verification 156 155 else if (payload.iss && typeof payload.iss === 'string') { 157 156 signingDid = payload.iss; 157 + } 158 + // Fallback: use aud as signing DID if present 159 + else if (pdsDid && typeof pdsDid === 'string' && pdsDid.startsWith('did:')) { 160 + signingDid = pdsDid; 161 + console.log( 162 + `[AUTH] Using aud field as signing DID for token from: ${pdsDid}` 163 + ); 158 164 } else { 159 - console.log(`[AUTH] OAuth token missing iss field`); 165 + console.log(`[AUTH] OAuth token missing iss/aud field`); 160 166 return null; 161 167 } 162 168 }