Challenge 2: Verify the Auth Fix Actually Works — Possible Solution ==================================================================== QUERY: { posts { author { email } } } CALLER: an authenticated user who is NOT the author of any of the returned posts. TRACE ------ 1. Query.posts's resolver runs, returning every Post (no authorization check here — reading a list of posts and their titles is intended to be publicly visible in this schema). 2. For each post, Post.author's resolver runs: context.userLoader.load(parent.authorId) — batched via DataLoader (Chapter 5), returning the actual User object for each post's author. No authorization check happens in THIS resolver either — it's perfectly fine for the caller to see that a post has an author with a given name; the sensitive part is specifically the email address. 3. For each of those User objects, User.email's resolver runs: (context.currentUser?.id === parent.id) ? parent.email : null Here, parent is the specific author User object from step 2, and context.currentUser is the CALLER (not the author). Since the caller is confirmed NOT to be any of these posts' authors, context.currentUser.id === parent.id evaluates to false for every single one of these User objects, and the resolver returns null in every case. RESULT: email comes back null for every post's author, confirming the value is never leaked to this caller. WHY THIS SPECIFICALLY CLOSES CHAPTER 8'S GOTCHA ---------------------------------------------------- Chapter 8's gotcha described exactly this scenario: authorization placed only on Query.user would do NOTHING to protect data reached via Query.posts -> Post.author instead. This capstone's schema never places its authorization check on Query.user at all (Query.user isn't even part of this schema's Query type) — the check lives directly inside User.email's own resolver, which is the ONE place every possible path to a User's email necessarily passes through, regardless of whether that User object arrived via a hypothetical Query.user, Post.author (as traced above), or any other field anywhere in the schema that might someday also return a User. Because the check is attached to the field returning the sensitive data itself — not to any one particular entry point — it applies uniformly no matter which resolver chain produced the User object being read from.