diff --git a/src/receiver/app.py b/src/receiver/app.py index 22ec4cf..c2f2f8b 100644 --- a/src/receiver/app.py +++ b/src/receiver/app.py @@ -25,12 +25,22 @@ def handler(event, context): timestamp = headers.get("x-slack-request-timestamp", "") signature = headers.get("x-slack-signature", "") + print( + f"Request: body_len={len(body)}, isBase64={event.get('isBase64Encoded')}, " + f"has_signature={bool(signature)}, has_timestamp={bool(timestamp)}, " + f"timestamp={timestamp}" + ) + if not verify_signature(body, timestamp, signature): + print("Signature verification FAILED — returning 401") return {"statusCode": 401, "body": "unauthorized"} + print("Signature verified") payload = json.loads(body) + print(f"Payload type: {payload.get('type')}") if payload.get("type") == "url_verification": + print("URL verification handshake, echoing challenge") return { "statusCode": 200, "headers": {"Content-Type": "text/plain"}, @@ -38,11 +48,14 @@ def handler(event, context): } if payload.get("type") == "event_callback": + event_type = payload.get("event", {}).get("type") + print(f"Event callback, event.type={event_type}, invoking processor") lambda_client.invoke( FunctionName=PROCESSOR_FUNCTION_NAME, InvocationType="Event", Payload=json.dumps(payload["event"]).encode("utf-8"), ) + print("Processor invoked") return {"statusCode": 200, "body": ""} @@ -58,14 +71,26 @@ def get_signing_secret() -> str: def verify_signature(body: str, timestamp: str, signature: str) -> bool: if not timestamp or not signature: + print("verify_signature: missing timestamp or signature header") return False try: ts = int(timestamp) except ValueError: + print(f"verify_signature: non-integer timestamp: {timestamp!r}") return False - if abs(time.time() - ts) > 300: + age = abs(time.time() - ts) + if age > 300: + print(f"verify_signature: timestamp too old (age={age:.1f}s)") return False secret = get_signing_secret() + secret_len = len(secret) base = f"v0:{timestamp}:{body}".encode("utf-8") expected = "v0=" + hmac.new(secret.encode("utf-8"), base, hashlib.sha256).hexdigest() - return hmac.compare_digest(expected, signature) + ok = hmac.compare_digest(expected, signature) + if not ok: + print( + f"verify_signature: HMAC mismatch. " + f"secret_len={secret_len}, expected_prefix={expected[:15]}, " + f"received_prefix={signature[:15]}" + ) + return ok