perlsky is a Perl 5 implementation of an AT Protocol Personal Data Server.
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

Extend differential coverage for void success semantics

alice b9a484ae 5d761a0c

+43 -3
+1
docs/TEST_AUDIT.md
··· 82 82 - PLC identity success procedures now also match the official runtime’s empty-body `200` surface: `com.atproto.identity.requestPlcOperationSignature`, `com.atproto.identity.updateHandle`, and `com.atproto.identity.submitPlcOperation`. 83 83 - Remaining lexicon-void admin/sync/temp procedures now also stay on the empty-body `200` surface instead of returning local JSON `{}` objects, including `com.atproto.admin.updateAccountHandle`, `updateAccountEmail`, `disableInviteCodes`, `updateAccountSigningKey`, `com.atproto.sync.requestCrawl`, `notifyOfUpdate`, `com.atproto.temp.requestPhoneVerification`, `revokeAccountCredentials`, and `com.atproto.repo.importRepo`. 84 84 - `app.bsky.actor.putPreferences` and `/oauth/revoke` now also keep their void-style empty-body `200` surface instead of returning local JSON `{}` objects. 85 + - The executable differential harness now also pins empty-body success semantics for `com.atproto.repo.importRepo` and the successful admin `updateAccountEmail` / `updateAccountHandle` flows instead of leaving those response-shape checks purely local. 85 86 - Password-bearing account endpoints need the same bounded-length behavior as the official runtime: `createAccount` rejects passwords longer than 256 characters, `createSession` rejects passwords longer than 512 characters with the reset hint, and `resetPassword` / `deleteAccount` reject overlong password inputs with `Invalid password length.` 86 87 - The executable reference harness now also pins those password-boundary semantics directly, including the official `AuthenticationRequired` error shape for overlong `createSession` requests and case-insensitive `requestPasswordReset` email lookup. 87 88 - `com.atproto.server.createAccount` with an explicit `did` must behave like an authenticated migration flow: require auth from that same DID, keep the existing DID document, and start the new account deactivated until activation catches the DID document up to the new PDS.
+42 -3
script/differential-validate
··· 2168 2168 check($res->is_success, "$name creates an extra record before importRepo"); 2169 2169 next unless $res->is_success; 2170 2170 2171 - $res = post_bytes( 2171 + my $import = post_bytes( 2172 2172 $server{$name}{origin}, 2173 2173 'com.atproto.repo.importRepo', 2174 2174 $server{$name}{repo_snapshot_car}, 2175 2175 'application/vnd.ipld.car', 2176 2176 auth_header($server{$name}{access}), 2177 2177 ); 2178 - check($res->is_success, "$name importRepo succeeds"); 2179 - next unless $res->is_success; 2178 + check($import->is_success, "$name importRepo succeeds"); 2179 + next unless $import->is_success; 2180 2180 2181 2181 $res = get_form($server{$name}{origin}, 'com.atproto.repo.listRecords', { 2182 2182 repo => $server{$name}{did}, ··· 2190 2190 $rkey // q(); 2191 2191 } @$records; 2192 2192 $server{$name}{import_repo_state} = { 2193 + import_status => $import->code // 0, 2194 + import_body => $import->body, 2193 2195 record_count => 0 + @$records, 2194 2196 rkeys => \@rkeys, 2195 2197 restored_diffpost => scalar(grep { $_ eq 'diffpost' } @rkeys) ? 1 : 0, ··· 2591 2593 identifier => $server{$name}{secondary_handle}, 2592 2594 password => 'newhunter22', 2593 2595 }); 2596 + my $updated_secondary_email = $name eq 'reference' ? 'bob-updated-ref@test.com' : 'bob-updated-perl@test.com'; 2597 + my $update_email_success = post_json( 2598 + $server{$name}{origin}, 2599 + 'com.atproto.admin.updateAccountEmail', 2600 + { 2601 + account => $server{$name}{secondary_did}, 2602 + email => $updated_secondary_email, 2603 + }, 2604 + admin_auth_header($server{$name}{admin_password}), 2605 + ); 2606 + my $updated_secondary_handle = $name eq 'reference' ? 'bob-updated-ref.test' : 'bob-updated-perl.test'; 2607 + my $update_handle_success = post_json( 2608 + $server{$name}{origin}, 2609 + 'com.atproto.admin.updateAccountHandle', 2610 + { 2611 + did => $server{$name}{secondary_did}, 2612 + handle => $updated_secondary_handle, 2613 + }, 2614 + admin_auth_header($server{$name}{admin_password}), 2615 + ); 2616 + my $updated_secondary_info = get_form( 2617 + $server{$name}{origin}, 2618 + 'com.atproto.admin.getAccountInfo', 2619 + { did => $server{$name}{secondary_did} }, 2620 + admin_auth_header($server{$name}{admin_password}), 2621 + ); 2594 2622 2595 2623 my $info_json = $info->json || {}; 2596 2624 my @infos = @{ $info_json->{infos} || [] }; 2597 2625 my $subject_active_json = $subject_active->json || {}; 2598 2626 my $disabled_json = $disabled_info->json || {}; 2599 2627 my $enabled_json = $enabled_info->json || {}; 2628 + my $updated_secondary_json = $updated_secondary_info->json || {}; 2600 2629 2601 2630 $server{$name}{admin_account_management} = { 2602 2631 get_infos => { ··· 2651 2680 update_password_missing => { 2652 2681 status => $reset_password_missing->code // 0, 2653 2682 body => $reset_password_missing->body, 2683 + }, 2684 + update_email_success => { 2685 + status => $update_email_success->code // 0, 2686 + body => $update_email_success->body, 2687 + updated_email => (($updated_secondary_json->{email} // q()) eq $updated_secondary_email) ? 1 : 0, 2688 + }, 2689 + update_handle_success => { 2690 + status => $update_handle_success->code // 0, 2691 + body => $update_handle_success->body, 2692 + updated_handle => (($updated_secondary_json->{handle} // q()) eq $updated_secondary_handle) ? 1 : 0, 2654 2693 }, 2655 2694 }; 2656 2695 }