···3838 pub admin_token: Option<String>,
3939 // AES-256-GCM master key for encrypting signing key private keys at rest.
4040 pub signing_key_master_key: Option<Sensitive<Zeroizing<[u8; 32]>>>,
4141+ // URL of the PLC directory service (default: https://plc.directory)
4242+ pub plc_directory_url: String,
4143}
42444345/// Optional privacy/ToS links surfaced by `com.atproto.server.describeServer`.
···117119 #[serde(default)]
118120 pub(crate) telemetry: RawTelemetryConfig,
119121 pub(crate) admin_token: Option<String>,
122122+ pub(crate) plc_directory_url: Option<String>,
120123 #[serde(skip)]
121124 pub(crate) signing_key_master_key: Option<[u8; 32]>,
122125 /// Sentinel field — only present to detect misconfiguration.
···235238 if let Some(v) = env.get("EZPDS_ADMIN_TOKEN") {
236239 raw.admin_token = Some(v.clone());
237240 }
241241+ if let Some(v) = env.get("EZPDS_PLC_DIRECTORY_URL") {
242242+ raw.plc_directory_url = Some(v.clone());
243243+ }
238244 if let Some(v) = env.get("EZPDS_SIGNING_KEY_MASTER_KEY") {
239245 raw.signing_key_master_key = Some(parse_hex_32("EZPDS_SIGNING_KEY_MASTER_KEY", v)?);
240246 }
···291297 ));
292298 }
293299 let invite_code_required = raw.invite_code_required.unwrap_or(true);
300300+ let plc_directory_url = raw
301301+ .plc_directory_url
302302+ .unwrap_or_else(|| "https://plc.directory".to_string());
294303295304 let telemetry_defaults = TelemetryConfig::default();
296305 let otlp_endpoint = raw
···335344 signing_key_master_key: raw
336345 .signing_key_master_key
337346 .map(|k| Sensitive(Zeroizing::new(k))),
347347+ plc_directory_url,
338348 })
339349}
340350
+8
crates/common/src/error.rs
···3838 /// A claim code that has already been redeemed is presented again.
3939 /// Clients should inform the user to obtain a different code.
4040 ClaimCodeRedeemed,
4141+ /// The DID has already been fully promoted to an active account.
4242+ DidAlreadyExists,
4343+ /// The external PLC directory returned a non-success response.
4444+ PlcDirectoryError,
4145 // TODO: add remaining codes from Appendix A as endpoints are implemented:
4246 // 400: INVALID_DOCUMENT, INVALID_PROOF, INVALID_ENDPOINT, INVALID_CONFIRMATION
4347 // 401: INVALID_CREDENTIALS
···6973 ErrorCode::HandleTaken => 409,
7074 ErrorCode::InvalidHandle => 400,
7175 ErrorCode::ClaimCodeRedeemed => 409,
7676+ ErrorCode::DidAlreadyExists => 409,
7777+ ErrorCode::PlcDirectoryError => 502,
7278 }
7379 }
7480}
···220226 (ErrorCode::HandleTaken, 409),
221227 (ErrorCode::InvalidHandle, 400),
222228 (ErrorCode::ClaimCodeRedeemed, 409),
229229+ (ErrorCode::DidAlreadyExists, 409),
230230+ (ErrorCode::PlcDirectoryError, 502),
223231 ];
224232 for (code, expected) in cases {
225233 assert_eq!(code.status_code(), expected, "wrong status for {code:?}");