' . esc_html__( 'Settings', 'sirius-press' ) . '' ); return $links; } public static function menu() { add_menu_page( __( 'Sirius Press', 'sirius-press' ), __( 'Sirius Press', 'sirius-press' ), 'manage_options', self::PAGE, array( __CLASS__, 'render' ), 'dashicons-admin-site-alt3', 71 ); } public static function render() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You are not allowed to configure this site.', 'sirius-press' ) ); } $errors = array(); $notes = array(); if ( isset( $_POST['sirius_press_settings'] ) && check_admin_referer( 'sirius_press_settings' ) ) { list( $errors, $notes ) = self::save( wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- each field sanitised in save(). } $name = SP_Settings::name(); $address = SP_Settings::publishing_address(); $mode = SP_Settings::mode(); $requirement = sirius_press_requirements_problem(); echo '

' . esc_html__( 'Sirius Press', 'sirius-press' ) . '

'; if ( '' !== $requirement ) { printf( '

%s

', esc_html( $requirement ) ); } foreach ( $errors as $e ) { printf( '

%s

', esc_html( $e ) ); } foreach ( $notes as $n ) { printf( '

%s

', wp_kses_post( $n ) ); } echo '
'; wp_nonce_field( 'sirius_press_settings' ); echo ''; echo '

' . esc_html__( 'Identity', 'sirius-press' ) . '

'; echo ''; self::text_row( 'sirius_name', __( 'BCNR name', 'sirius-press' ), $name, __( 'The name this site publishes under, exactly as registered — for example example.bch. Point that name\'s p or ip record at this server so visitors reach it.', 'sirius-press' ) ); echo ''; self::text_row( 'sirius_gateway', __( 'Gateway', 'sirius-press' ), SP_Settings::gateway(), __( 'The BNS gateway that accepts static exports. Leave as the default unless you run your own.', 'sirius-press' ) ); echo ''; echo '

' . esc_html__( 'Publishing', 'sirius-press' ) . '

'; echo ''; echo ''; echo ''; self::text_row( 'sirius_path', __( 'Derivation path', 'sirius-press' ), SP_Settings::derivation_path(), __( 'Leave alone unless your wallet was created somewhere that used a different path. The default matches the Sirius portal wallet.', 'sirius-press' ) ); echo ''; echo ''; echo '

' . esc_html__( 'Accounts', 'sirius-press' ) . '

'; echo ''; echo ''; self::text_row( 'sirius_stub_domain', __( 'Placeholder mail domain', 'sirius-press' ), SP_Settings::stub_email_domain(), __( 'Plugins that insist on an email address get one here. It must stay unroutable — keep the .invalid ending, which is reserved so it can never resolve.', 'sirius-press' ) ); echo ''; submit_button(); echo '
'; self::render_status( $name, $address ); echo '
'; } /** The reality check: does the stored key actually own the name? */ private static function render_status( $name, $address ) { echo '

' . esc_html__( 'Status', 'sirius-press' ) . '

'; echo ''; self::status_row( __( 'Name', 'sirius-press' ), '' !== $name ? $name : __( 'not set', 'sirius-press' ), '' !== $name ); self::status_row( __( 'Publishing address', 'sirius-press' ), '' !== $address ? $address : __( 'no phrase stored', 'sirius-press' ), '' !== $address ); if ( '' === $name ) { echo '
'; return; } $owner = SP_Gateway::owner_of_name(); if ( '' === $owner ) { self::status_row( __( 'On-chain owner', 'sirius-press' ), __( 'the gateway did not answer — it may not have indexed this name yet', 'sirius-press' ), null ); } elseif ( '' === $address ) { self::status_row( __( 'On-chain owner', 'sirius-press' ), $owner, null ); } elseif ( hash_equals( $owner, $address ) ) { self::status_row( __( 'On-chain owner', 'sirius-press' ), __( 'matches the stored key — this site can publish', 'sirius-press' ), true ); } else { self::status_row( __( 'On-chain owner', 'sirius-press' ), sprintf( /* translators: %s: the address that currently owns the name. */ __( '%s — which is NOT the stored key. Exports will be refused until the phrase here is the one that owns the name.', 'sirius-press' ), $owner ), false ); } echo ''; } private static function status_row( $label, $value, $ok ) { $mark = true === $ok ? '✓' : ( false === $ok ? '✗' : '·' ); $col = true === $ok ? '#007017' : ( false === $ok ? '#b32d2e' : '#646970' ); printf( '%s%s %s', esc_html( $label ), esc_attr( $col ), esc_html( $mark ), esc_html( $value ) ); } private static function text_row( $field, $label, $value, $description ) { printf( '

%4$s

', esc_attr( $field ), esc_html( $label ), esc_attr( $value ), wp_kses_post( $description ) ); } /** @return array{0:string[],1:string[]} errors, notices */ private static function save( $post ) { $errors = array(); $notes = array(); $name = strtolower( sanitize_text_field( isset( $post['sirius_name'] ) ? $post['sirius_name'] : '' ) ); if ( '' !== $name && ! preg_match( '/^[a-z0-9][a-z0-9.\-]{0,200}\.[a-z0-9\-]+$/', $name ) ) { $errors[] = __( 'That does not look like a BCNR name. A name is a label and a TLD, such as example.bch.', 'sirius-press' ); } else { update_option( SP_Settings::OPT_NAME, $name ); } update_option( SP_Settings::OPT_NETWORK, 'chipnet' === ( isset( $post['sirius_network'] ) ? $post['sirius_network'] : '' ) ? 'chipnet' : 'mainnet' ); $gateway = esc_url_raw( trim( isset( $post['sirius_gateway'] ) ? $post['sirius_gateway'] : '' ) ); if ( '' !== $gateway && 0 !== strpos( $gateway, 'http' ) ) { $errors[] = __( 'The gateway must be a full URL.', 'sirius-press' ); } else { update_option( SP_Settings::OPT_GATEWAY, '' === $gateway ? SP_Settings::DEFAULT_GATEWAY : $gateway ); } update_option( SP_Settings::OPT_MODE, SP_Settings::MODE_SERVER === ( isset( $post['sirius_mode'] ) ? $post['sirius_mode'] : '' ) ? SP_Settings::MODE_SERVER : SP_Settings::MODE_MANUAL ); update_option( SP_Settings::OPT_AUTOPUB, ! empty( $post['sirius_auto_publish'] ) ); update_option( SP_Settings::OPT_OPEN_REG, ! empty( $post['sirius_open_registration'] ) ); $path = sanitize_text_field( isset( $post['sirius_path'] ) ? $post['sirius_path'] : '' ); if ( '' !== $path && ! preg_match( "#^m(/\d+'?)*$#", $path ) ) { $errors[] = __( 'That is not a derivation path. It looks like m/44\'/145\'/0\'/0/0.', 'sirius-press' ); } else { update_option( SP_Settings::OPT_PATH, $path ); } $stub = strtolower( sanitize_text_field( isset( $post['sirius_stub_domain'] ) ? $post['sirius_stub_domain'] : '' ) ); if ( '' !== $stub && ! preg_match( '/\.invalid$/', $stub ) ) { $errors[] = __( 'The placeholder mail domain must end in .invalid, so that mail to it can never be delivered by accident.', 'sirius-press' ); } else { update_option( SP_Settings::OPT_STUB_MAIL, $stub ); } if ( ! empty( $post['sirius_forget_phrase'] ) ) { SP_Settings::set_phrase( '' ); $notes[] = __( 'The stored recovery phrase has been deleted. Automatic publishing is off until a phrase is provided again.', 'sirius-press' ); } elseif ( ! empty( $post['sirius_phrase'] ) ) { $problem = SP_Settings::set_phrase( (string) $post['sirius_phrase'] ); if ( '' !== $problem ) { $errors[] = $problem; } else { $notes[] = sprintf( /* translators: %s: the derived CashAddress. */ __( 'Phrase stored. It publishes from %s — check that this is the address that owns the name.', 'sirius-press' ), esc_html( SP_Settings::publishing_address() ) ); } } if ( ! $errors ) { $notes[] = __( 'Settings saved.', 'sirius-press' ); } return array( $errors, $notes ); } }