···11-## XRPC Service Proxying
11+Most atproto endpoints use something called [XRPC](https://atproto.com/specs/xrpc), you've probably seen it in something
22+like this URL to get a Bluesky profile of
33+someone [https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=jcsalterego.bsky.social](https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=jcsalterego.bsky.social).
44+In short XRPC is a way to write HTTP endpoints that can be defined by
55+a [lexicon schema](https://atproto.com/specs/lexicon#query-and-procedure-http-api) so you know what data is returned
66+from the endpoint, what type of request, parmeters, errors, etc. And since this is all defined in a lexicon schema you
77+can generate a client from it as well.
2833-Now that you can create a serviceAuth JWT, let's use it in an actual XRPC request.
99+With XRPC you can also do something called [Service Proxying](https://atproto.com/specs/xrpc#service-proxying) which
1010+means if you call the XRPC endpoint on your PDS while authenicated with the `atproto-proxy` header with the did and the
1111+service like so `did:web:labeler.example.com#atproto_labeler` it looks up the service and proxies the request to the
1212+service with a serviceAuth JWT set as the bearer.
41355-Make an HTTP GET request to our XRPC endpoint with your JWT in the `Authorization` header:
1414+For example, this is how Bluesky DMs work
61577-```
88-GET https://{{service_did_domain}}/xrpc/codes.advent.challenge.getDay6Code
99-Authorization: Bearer <your-jwt>
1010-```
1616+- On requests to the PDS for DMs there is an `atproto-proxy` header that looks like
1717+ `did:web:api.bsky.chat#bsky_chat`.
1818+- When you call the PDS it takes the URL from the `did:web` to find a did doc at
1919+ `https://api.bsky.chat/.well-known/did.json`
2020+- It then looks up the service `bsky_chat` in the did doc andthen proxies the web request to the `serviceEndpoint`
2121+ listed there.
2222+- It then proxies the request to the service with the serviceAuth JWT set as the bearer.
11231212-Your JWT for this request must have:
1313-- `iss`: Your DID
1414-- `aud`: `{{service_did}}`
1515-- `lxm`: `{{lxm_part_two}}`
1616-- `exp`: A UNIX timestamp in the future
1717-1818-The response will contain a JSON object with your verification code. Paste that code below.
2424+Today's part two is for you to make a XRPC query request to the `codes.advent.challenge.getCode` XRPC endpoint to the
2525+service `did:web:{{service_did_domain}}#advent` to get your verification code.
+5-2
web/src/main.rs
···288288 )
289289 .route(
290290 "/day/3/upload-car",
291291- post(handlers::custom::day_three::inspect_car) // 2MB max for default axum
291291+ post(handlers::custom::day_three::inspect_car), // 2MB max for default axum
292292 )
293293 .route(
294294 "/day/5/{user_did}",
295295 get(handlers::custom::day_five::create_record_handler),
296296 )
297297 .route(
298298- "/xrpc/codes.advent.challenge.getChallengeCode",
298298+ "/xrpc/codes.advent.challenge.getCode",
299299 get(handlers::custom::day_six::xrpc_handler),
300300 )
301301 .route(
···358358 .map(|(_, s)| s)
359359 .unwrap_or(&CompletionStatus::None);
360360 if *prev_status == CompletionStatus::Both {
361361+ unlocked.push(window[1]);
362362+ } else if (prev == 4 || prev == 5) && *prev_status == CompletionStatus::PartOne {
363363+ //HACK hardcoded for the workshop since we don't have a part 2 for day 4
361364 unlocked.push(window[1]);
362365 } else {
363366 break;
+5
web/src/unlock.rs
···6363 .map(|(_, s)| s)
6464 .unwrap_or(&CompletionStatus::None);
65656666+ //HACK hardcoded for the workshop since we don't have a part 2 for day 4
6767+ if (pos == 4 || pos == 5) && *prev_status == CompletionStatus::PartOne {
6868+ return next.run(request).await;
6969+ }
7070+6671 if *prev_status != CompletionStatus::Both {
6772 return (
6873 http::StatusCode::FORBIDDEN,