11import { v4 as uuidv4 } from 'uuid' ;
2+ import isbot from 'isbot' ;
23
34import ProcessedQuery from '../../utils/processed-query' ;
45import { ConfigInterface } from '../../base-types' ;
@@ -18,8 +19,9 @@ import {
1819 AdapterHeaders ,
1920 Cookies ,
2021 NormalizedResponse ,
22+ NormalizedRequest ,
2123} from '../../../runtime/http' ;
22- import { logger } from '../../logger' ;
24+ import { logger , ShopifyLogger } from '../../logger' ;
2325
2426import {
2527 SESSION_COOKIE_NAME ,
@@ -39,6 +41,18 @@ export interface CallbackResponse<T = AdapterHeaders> {
3941 session : Session ;
4042}
4143
44+ interface BotLog {
45+ request : NormalizedRequest ;
46+ log : ShopifyLogger ;
47+ func : string ;
48+ }
49+
50+ const logForBot = ( { request, log, func} : BotLog ) => {
51+ log . debug ( `Possible bot request to auth ${ func } : ` , {
52+ userAgent : request . headers [ 'User-Agent' ] ,
53+ } ) ;
54+ } ;
55+
4256export function begin ( config : ConfigInterface ) {
4357 return async ( {
4458 shop,
@@ -54,10 +68,15 @@ export function begin(config: ConfigInterface) {
5468 const log = logger ( config ) ;
5569 log . info ( 'Beginning OAuth' , { shop, isOnline, callbackPath} ) ;
5670
57- const cleanShop = sanitizeShop ( config ) ( shop , true ) ! ;
5871 const request = await abstractConvertRequest ( adapterArgs ) ;
5972 const response = await abstractConvertIncomingResponse ( adapterArgs ) ;
6073
74+ if ( isbot ( request . headers [ 'User-Agent' ] ) ) {
75+ logForBot ( { request, log, func : 'begin' } ) ;
76+ response . statusCode = 410 ;
77+ return abstractConvertResponse ( response , adapterArgs ) ;
78+ }
79+
6180 const cookies = new Cookies ( request , response , {
6281 keys : [ config . apiSecretKey ] ,
6382 secure : true ,
@@ -82,6 +101,7 @@ export function begin(config: ConfigInterface) {
82101 const processedQuery = new ProcessedQuery ( ) ;
83102 processedQuery . putAll ( query ) ;
84103
104+ const cleanShop = sanitizeShop ( config ) ( shop , true ) ! ;
85105 const redirectUrl = `https://${ cleanShop } /admin/oauth/authorize${ processedQuery . stringify ( ) } ` ;
86106 response . statusCode = 302 ;
87107 response . statusText = 'Found' ;
@@ -116,9 +136,17 @@ export function callback(config: ConfigInterface) {
116136 ) . searchParams ;
117137 const shop = query . get ( 'shop' ) ! ;
118138
139+ const response = { } as NormalizedResponse ;
140+ if ( isbot ( request . headers [ 'User-Agent' ] ) ) {
141+ logForBot ( { request, log, func : 'callback' } ) ;
142+ throw new ShopifyErrors . BotActivityDetected (
143+ 'Invalid OAuth callback initiated by bot' ,
144+ ) ;
145+ }
146+
119147 log . info ( 'Completing OAuth' , { shop} ) ;
120148
121- const cookies = new Cookies ( request , { } as NormalizedResponse , {
149+ const cookies = new Cookies ( request , response , {
122150 keys : [ config . apiSecretKey ] ,
123151 secure : true ,
124152 } ) ;
0 commit comments