command_tower 0.3.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +104 -28
- data/app/auth/command_tower/auth/auth_context.rb +36 -0
- data/app/auth/command_tower/auth/password_recovery_session_context.rb +11 -0
- data/app/auth/command_tower/auth/signup_session_context.rb +11 -0
- data/app/controllers/command_tower/admin/messaging/announcements_controller.rb +34 -0
- data/app/controllers/command_tower/application_controller.rb +80 -14
- data/app/controllers/command_tower/auth/email/availability_controller.rb +35 -0
- data/app/controllers/command_tower/auth/email_verification/send_controller.rb +24 -0
- data/app/controllers/command_tower/auth/email_verification/verify_controller.rb +41 -0
- data/app/controllers/command_tower/auth/identity_policy_controller.rb +14 -0
- data/app/controllers/command_tower/auth/logout_controller.rb +14 -0
- data/app/controllers/command_tower/auth/password_recovery_session/create_controller.rb +17 -0
- data/app/controllers/command_tower/auth/password_reset/reset_controller.rb +35 -0
- data/app/controllers/command_tower/auth/password_reset/send_controller.rb +40 -0
- data/app/controllers/command_tower/auth/password_reset/validate_controller.rb +35 -0
- data/app/controllers/command_tower/auth/plain_text/login_controller.rb +22 -0
- data/app/controllers/command_tower/auth/register_controller.rb +33 -0
- data/app/controllers/command_tower/auth/session_controller.rb +21 -0
- data/app/controllers/command_tower/auth/signup_session/create_controller.rb +17 -0
- data/app/controllers/command_tower/auth/username/availability_controller.rb +35 -0
- data/app/controllers/command_tower/me/inbox_controller.rb +85 -0
- data/app/controllers/command_tower/me/name_controller.rb +37 -0
- data/app/controllers/command_tower/me/password_controller.rb +37 -0
- data/app/controllers/command_tower/me/phone_controller.rb +44 -0
- data/app/controllers/command_tower/me/phone_verification/verifications_controller.rb +23 -0
- data/app/controllers/command_tower/me/phone_verification/verify_controller.rb +34 -0
- data/app/controllers/command_tower/me/preferences_controller.rb +46 -0
- data/app/controllers/command_tower/me/pushover/verifications_controller.rb +23 -0
- data/app/controllers/command_tower/me/pushover_controller.rb +66 -0
- data/app/controllers/command_tower/me_controller.rb +19 -0
- data/app/controllers/command_tower/profile_controller.rb +19 -0
- data/app/controllers/concerns/command_tower/api/application_response_renderer.rb +82 -0
- data/app/controllers/concerns/command_tower/api/deserializer_failure_details.rb +22 -0
- data/app/controllers/concerns/command_tower/auth/authentication_boundary.rb +34 -0
- data/app/controllers/concerns/command_tower/auth/authorization_boundary.rb +26 -0
- data/app/controllers/concerns/command_tower/auth/invalid_credentials_deserializer_renderer.rb +23 -0
- data/app/controllers/concerns/command_tower/auth/password_recovery_session_boundary.rb +29 -0
- data/app/controllers/concerns/command_tower/auth/signup_session_boundary.rb +29 -0
- data/app/deserializers/command_tower/deserializers/admin/messaging/create_announcement_deserializer.rb +106 -0
- data/app/deserializers/command_tower/deserializers/application_deserializer.rb +148 -0
- data/app/deserializers/command_tower/deserializers/auth/email_availability_deserializer.rb +19 -0
- data/app/deserializers/command_tower/deserializers/auth/email_verification/verify_deserializer.rb +21 -0
- data/app/deserializers/command_tower/deserializers/auth/password_reset/reset_deserializer.rb +31 -0
- data/app/deserializers/command_tower/deserializers/auth/password_reset/send_deserializer.rb +21 -0
- data/app/deserializers/command_tower/deserializers/auth/password_reset/validate_deserializer.rb +23 -0
- data/app/deserializers/command_tower/deserializers/auth/plain_text/login_deserializer.rb +24 -0
- data/app/deserializers/command_tower/deserializers/auth/register_deserializer.rb +42 -0
- data/app/deserializers/command_tower/deserializers/auth/username_availability_deserializer.rb +19 -0
- data/app/deserializers/command_tower/deserializers/clients/errors.rb +45 -0
- data/app/deserializers/command_tower/deserializers/clients/missing.rb +10 -0
- data/app/deserializers/command_tower/deserializers/clients/payload.rb +21 -0
- data/app/deserializers/command_tower/deserializers/clients/result.rb +122 -0
- data/app/deserializers/command_tower/deserializers/clients/types.rb +192 -0
- data/app/deserializers/command_tower/deserializers/coercion_result.rb +35 -0
- data/app/deserializers/command_tower/deserializers/failure.rb +14 -0
- data/app/deserializers/command_tower/deserializers/me/change_password_deserializer.rb +41 -0
- data/app/deserializers/command_tower/deserializers/me/phone_verification/verify_deserializer.rb +29 -0
- data/app/deserializers/command_tower/deserializers/me/pushover/credentials_deserializer.rb +31 -0
- data/app/deserializers/command_tower/deserializers/me/update_name_deserializer.rb +22 -0
- data/app/deserializers/command_tower/deserializers/me/update_phone_deserializer.rb +22 -0
- data/app/deserializers/command_tower/deserializers/messaging/inbox.rb +77 -0
- data/app/deserializers/command_tower/deserializers/messaging/preferences/show_deserializer.rb +17 -0
- data/app/deserializers/command_tower/deserializers/messaging/preferences/update_deserializer.rb +97 -0
- data/app/errors/command_tower/errors/account/phone_already_verified_error.rb +17 -0
- data/app/errors/command_tower/errors/account/phone_missing_error.rb +17 -0
- data/app/errors/command_tower/errors/account/phone_verification_code_invalid_error.rb +17 -0
- data/app/errors/command_tower/errors/account/phone_verification_expired_error.rb +17 -0
- data/app/errors/command_tower/errors/account/phone_verification_send_failed_error.rb +25 -0
- data/app/errors/command_tower/errors/account/phone_verification_stale_error.rb +17 -0
- data/app/errors/command_tower/errors/account/phone_verification_throttled_error.rb +24 -0
- data/app/errors/command_tower/errors/account/pushover_already_configured_error.rb +21 -0
- data/app/errors/command_tower/errors/account/pushover_capability_unavailable_error.rb +21 -0
- data/app/errors/command_tower/errors/account/pushover_not_configured_error.rb +21 -0
- data/app/errors/command_tower/errors/account/pushover_provider_unavailable_error.rb +21 -0
- data/app/errors/command_tower/errors/account/pushover_verification_failed_error.rb +27 -0
- data/app/errors/command_tower/errors/account/sms_capability_unavailable_error.rb +21 -0
- data/app/errors/command_tower/errors/application_error.rb +27 -0
- data/app/errors/command_tower/errors/auth/csrf_mismatch_error.rb +17 -0
- data/app/errors/command_tower/errors/auth/csrf_missing_error.rb +17 -0
- data/app/errors/command_tower/errors/auth/email_already_registered_error.rb +17 -0
- data/app/errors/command_tower/errors/auth/email_verification_required_error.rb +21 -0
- data/app/errors/command_tower/errors/auth/invalid_credentials_error.rb +21 -0
- data/app/errors/command_tower/errors/auth/password_recovery_ip_rate_limit_error.rb +25 -0
- data/app/errors/command_tower/errors/auth/password_recovery_session_expired_error.rb +21 -0
- data/app/errors/command_tower/errors/auth/password_recovery_session_invalid_error.rb +21 -0
- data/app/errors/command_tower/errors/auth/password_recovery_session_missing_error.rb +21 -0
- data/app/errors/command_tower/errors/auth/password_recovery_session_rate_limit_error.rb +25 -0
- data/app/errors/command_tower/errors/auth/password_reset_invalid_token_error.rb +21 -0
- data/app/errors/command_tower/errors/auth/password_reset_unavailable_error.rb +21 -0
- data/app/errors/command_tower/errors/auth/signup_ip_rate_limit_error.rb +25 -0
- data/app/errors/command_tower/errors/auth/signup_session_expired_error.rb +17 -0
- data/app/errors/command_tower/errors/auth/signup_session_invalid_error.rb +17 -0
- data/app/errors/command_tower/errors/auth/signup_session_missing_error.rb +17 -0
- data/app/errors/command_tower/errors/auth/signup_session_rate_limit_error.rb +25 -0
- data/app/errors/command_tower/errors/auth/verification_code_invalid_error.rb +17 -0
- data/app/errors/command_tower/errors/auth/verification_send_failed_error.rb +25 -0
- data/app/errors/command_tower/errors/forbidden_error.rb +19 -0
- data/app/errors/command_tower/errors/internal_error.rb +19 -0
- data/app/errors/command_tower/errors/messaging/accept_rejected_error.rb +21 -0
- data/app/errors/command_tower/errors/messaging/idempotency_conflict_error.rb +21 -0
- data/app/errors/command_tower/errors/messaging/recipient_unresolved_error.rb +21 -0
- data/app/errors/command_tower/errors/not_found_error.rb +19 -0
- data/app/errors/command_tower/errors/unauthorized_error.rb +19 -0
- data/app/errors/command_tower/errors/validation_error.rb +15 -0
- data/app/jobs/command_tower/messaging/channel_delivery_execution_job.rb +18 -0
- data/app/jobs/command_tower/messaging/communications/produce_recipient_job.rb +24 -0
- data/app/jobs/command_tower/messaging/execution_recovery_job.rb +13 -0
- data/app/jobs/command_tower/messaging/handoff_job.rb +15 -0
- data/app/jobs/command_tower/messaging/handoff_recovery_job.rb +13 -0
- data/app/mailers/command_tower/email_verification_mailer.rb +5 -3
- data/app/mailers/command_tower/messaging/channel_mailer.rb +25 -0
- data/app/mailers/command_tower/password_reset_mailer.rb +18 -0
- data/app/models/command_tower/messaging/channel_delivery.rb +45 -0
- data/app/models/command_tower/messaging/communication.rb +60 -0
- data/app/models/command_tower/messaging/delivery_attempt.rb +28 -0
- data/app/models/command_tower/messaging/destination_plan.rb +17 -0
- data/app/models/command_tower/messaging/endpoint.rb +98 -0
- data/app/models/command_tower/messaging/endpoint_pushover_credential.rb +18 -0
- data/app/models/command_tower/messaging/inbox_item.rb +52 -0
- data/app/models/command_tower/messaging/notification_preference.rb +21 -0
- data/app/models/user.rb +4 -1
- data/app/serializers/command_tower/serializers/admin/messaging/announcement_response_serializer.rb +41 -0
- data/app/serializers/command_tower/serializers/application/envelope_serializer.rb +25 -0
- data/app/serializers/command_tower/serializers/application/error_entry_serializer.rb +18 -0
- data/app/serializers/command_tower/serializers/application_serializer.rb +26 -0
- data/app/serializers/command_tower/serializers/auth/email_availability_serializer.rb +17 -0
- data/app/serializers/command_tower/serializers/auth/email_verification/message_response_serializer.rb +15 -0
- data/app/serializers/command_tower/serializers/auth/identity_policy_serializer.rb +36 -0
- data/app/serializers/command_tower/serializers/auth/login_response_serializer.rb +17 -0
- data/app/serializers/command_tower/serializers/auth/logout_response_serializer.rb +13 -0
- data/app/serializers/command_tower/serializers/auth/password_recovery_session_response_serializer.rb +16 -0
- data/app/serializers/command_tower/serializers/auth/password_reset/message_response_serializer.rb +15 -0
- data/app/serializers/command_tower/serializers/auth/password_reset/validate_response_serializer.rb +22 -0
- data/app/serializers/command_tower/serializers/auth/register_response_serializer.rb +16 -0
- data/app/serializers/command_tower/serializers/auth/session_response_serializer.rb +16 -0
- data/app/serializers/command_tower/serializers/auth/signup_session_response_serializer.rb +16 -0
- data/app/serializers/command_tower/serializers/auth/user_serializer.rb +21 -0
- data/app/serializers/command_tower/serializers/auth/username_availability_serializer.rb +17 -0
- data/app/serializers/command_tower/serializers/me/account_serializer.rb +45 -0
- data/app/serializers/command_tower/serializers/me/change_password_response_serializer.rb +13 -0
- data/app/serializers/command_tower/serializers/me/pushover_serializer.rb +59 -0
- data/app/serializers/command_tower/serializers/messaging/inbox.rb +45 -0
- data/app/serializers/command_tower/serializers/messaging/preferences/catalog_serializer.rb +17 -0
- data/app/serializers/command_tower/serializers/messaging/preferences/category_serializer.rb +23 -0
- data/app/serializers/command_tower/serializers/messaging/preferences/notification_serializer.rb +30 -0
- data/app/serializers/command_tower/serializers/profile/profile_serializer.rb +13 -0
- data/app/services/command_tower/README.md +22 -6
- data/app/services/command_tower/auth/request_context.rb +21 -0
- data/app/services/command_tower/authorize/validate.rb +54 -18
- data/app/services/command_tower/clients/client_base.rb +183 -0
- data/app/services/command_tower/clients/client_result.rb +45 -0
- data/app/services/command_tower/clients/const_resolution.rb +32 -0
- data/app/services/command_tower/clients/decoded_response.rb +16 -0
- data/app/services/command_tower/clients/endpoint_base.rb +242 -0
- data/app/services/command_tower/clients/endpoint_input.rb +18 -0
- data/app/services/command_tower/clients/errors/authentication_error.rb +26 -0
- data/app/services/command_tower/clients/errors/configuration_error.rb +10 -0
- data/app/services/command_tower/clients/errors/deserialization_error.rb +26 -0
- data/app/services/command_tower/clients/errors/discovery_error.rb +10 -0
- data/app/services/command_tower/clients/errors/upstream_error.rb +26 -0
- data/app/services/command_tower/clients/invocation.rb +61 -0
- data/app/services/command_tower/clients/namespace_proxy.rb +75 -0
- data/app/services/command_tower/clients/scoped_client.rb +88 -0
- data/app/services/command_tower/clients/serialized_request.rb +17 -0
- data/app/services/command_tower/clients/transport/error.rb +18 -0
- data/app/services/command_tower/clients/transport/faraday_adapter.rb +129 -0
- data/app/services/command_tower/clients/transport/faraday_config.rb +45 -0
- data/app/services/command_tower/clients/transport/request.rb +50 -0
- data/app/services/command_tower/clients/transport/response.rb +22 -0
- data/app/services/command_tower/clients/url.rb +56 -0
- data/app/services/command_tower/identity/phone/normalizer.rb +41 -0
- data/app/services/command_tower/identity/phone_verification/sms_configuration.rb +58 -0
- data/app/services/command_tower/identity/phone_verification/sms_transport/adapters/fake_adapter.rb +35 -0
- data/app/services/command_tower/identity/phone_verification/sms_transport/adapters/log_adapter.rb +34 -0
- data/app/services/command_tower/identity/phone_verification/sms_transport/adapters/twilio_adapter.rb +60 -0
- data/app/services/command_tower/identity/phone_verification/sms_transport.rb +42 -0
- data/app/services/command_tower/jwt/authenticate_user.rb +61 -34
- data/app/services/command_tower/jwt/authentication_outcome.rb +36 -0
- data/app/services/command_tower/jwt/decode.rb +27 -8
- data/app/services/command_tower/jwt/encode.rb +4 -6
- data/app/services/command_tower/jwt/login_create.rb +6 -7
- data/app/services/command_tower/login_strategy/plain_text/email_verification/required.rb +11 -9
- data/app/services/command_tower/messaging/accept/channel_delivery_result.rb +13 -0
- data/app/services/command_tower/messaging/accept/coordinator.rb +166 -0
- data/app/services/command_tower/messaging/accept/error.rb +9 -0
- data/app/services/command_tower/messaging/accept/excluded_destination.rb +24 -0
- data/app/services/command_tower/messaging/accept/handoff_scheduler.rb +40 -0
- data/app/services/command_tower/messaging/accept/idempotency_conflict_error.rb +9 -0
- data/app/services/command_tower/messaging/accept/illegal_override_error.rb +9 -0
- data/app/services/command_tower/messaging/accept/impossible_mandatory_plan_error.rb +9 -0
- data/app/services/command_tower/messaging/accept/invalid_preference_error.rb +9 -0
- data/app/services/command_tower/messaging/accept/invariant_error.rb +9 -0
- data/app/services/command_tower/messaging/accept/operation_logger.rb +97 -0
- data/app/services/command_tower/messaging/accept/persistence_error.rb +9 -0
- data/app/services/command_tower/messaging/accept/persister.rb +90 -0
- data/app/services/command_tower/messaging/accept/request_normalizer.rb +100 -0
- data/app/services/command_tower/messaging/accept/result.rb +99 -0
- data/app/services/command_tower/messaging/accept/unknown_type_error.rb +9 -0
- data/app/services/command_tower/messaging/accept/validation_error.rb +9 -0
- data/app/services/command_tower/messaging/channel_detectors.rb +52 -0
- data/app/services/command_tower/messaging/channels/definition.rb +24 -0
- data/app/services/command_tower/messaging/channels/error.rb +9 -0
- data/app/services/command_tower/messaging/channels/unknown_channel_error.rb +9 -0
- data/app/services/command_tower/messaging/channels.rb +85 -0
- data/app/services/command_tower/messaging/contract/communications.rb +29 -0
- data/app/services/command_tower/messaging/contract/error.rb +9 -0
- data/app/services/command_tower/messaging/contract/internal/finder.rb +43 -0
- data/app/services/command_tower/messaging/contract/invariant_error.rb +9 -0
- data/app/services/command_tower/messaging/contract/mappers/channel_delivery_mapper.rb +53 -0
- data/app/services/command_tower/messaging/contract/mappers/communication_mapper.rb +61 -0
- data/app/services/command_tower/messaging/contract/mappers/delivery_attempt_mapper.rb +27 -0
- data/app/services/command_tower/messaging/contract/mappers/destination_plan_mapper.rb +17 -0
- data/app/services/command_tower/messaging/contract/mappers/inbox_item_mapper.rb +17 -0
- data/app/services/command_tower/messaging/contract/not_found_error.rb +9 -0
- data/app/services/command_tower/messaging/contract/observability/correlation.rb +17 -0
- data/app/services/command_tower/messaging/contract/observability/operation_logger.rb +101 -0
- data/app/services/command_tower/messaging/contract/observability/structured_logger.rb +56 -0
- data/app/services/command_tower/messaging/contract/requests/find_communication.rb +21 -0
- data/app/services/command_tower/messaging/contract/results/channel_delivery_result.rb +25 -0
- data/app/services/command_tower/messaging/contract/results/communication_result.rb +22 -0
- data/app/services/command_tower/messaging/contract/results/delivery_attempt_result.rb +21 -0
- data/app/services/command_tower/messaging/contract/results/destination_plan_result.rb +11 -0
- data/app/services/command_tower/messaging/contract/results/inbox_item_result.rb +11 -0
- data/app/services/command_tower/messaging/contract/validation_error.rb +9 -0
- data/app/services/command_tower/messaging/delivery_retry_policy.rb +30 -0
- data/app/services/command_tower/messaging/endpoints/begin_verification.rb +13 -0
- data/app/services/command_tower/messaging/endpoints/channel_gate.rb +39 -0
- data/app/services/command_tower/messaging/endpoints/conflict_error.rb +9 -0
- data/app/services/command_tower/messaging/endpoints/create.rb +181 -0
- data/app/services/command_tower/messaging/endpoints/error.rb +9 -0
- data/app/services/command_tower/messaging/endpoints/fingerprinter.rb +50 -0
- data/app/services/command_tower/messaging/endpoints/invalid_transition_error.rb +9 -0
- data/app/services/command_tower/messaging/endpoints/lifecycle.rb +37 -0
- data/app/services/command_tower/messaging/endpoints/mark_invalid.rb +32 -0
- data/app/services/command_tower/messaging/endpoints/mark_verification_failed.rb +13 -0
- data/app/services/command_tower/messaging/endpoints/mark_verified.rb +13 -0
- data/app/services/command_tower/messaging/endpoints/not_found_error.rb +9 -0
- data/app/services/command_tower/messaging/endpoints/persistence.rb +91 -0
- data/app/services/command_tower/messaging/endpoints/pushover/verify.rb +101 -0
- data/app/services/command_tower/messaging/endpoints/query.rb +28 -0
- data/app/services/command_tower/messaging/endpoints/replace.rb +181 -0
- data/app/services/command_tower/messaging/endpoints/reset_verification.rb +13 -0
- data/app/services/command_tower/messaging/endpoints/revoke.rb +40 -0
- data/app/services/command_tower/messaging/endpoints/safe_view.rb +50 -0
- data/app/services/command_tower/messaging/endpoints/secret_box.rb +86 -0
- data/app/services/command_tower/messaging/endpoints/secret_reader.rb +72 -0
- data/app/services/command_tower/messaging/endpoints/validation_error.rb +9 -0
- data/app/services/command_tower/messaging/endpoints/validators/push.rb +24 -0
- data/app/services/command_tower/messaging/endpoints/validators/pushover.rb +68 -0
- data/app/services/command_tower/messaging/endpoints/validators.rb +36 -0
- data/app/services/command_tower/messaging/endpoints/verification.rb +39 -0
- data/app/services/command_tower/messaging/endpoints/verification_failed_error.rb +18 -0
- data/app/services/command_tower/messaging/endpoints/verification_transition.rb +20 -0
- data/app/services/command_tower/messaging/endpoints.rb +55 -0
- data/app/services/command_tower/messaging/execution/adapter_request.rb +45 -0
- data/app/services/command_tower/messaging/execution/adapter_result.rb +81 -0
- data/app/services/command_tower/messaging/execution/adapters/email/adapter.rb +78 -0
- data/app/services/command_tower/messaging/execution/adapters/email/configuration.rb +55 -0
- data/app/services/command_tower/messaging/execution/adapters/fake_adapter.rb +34 -0
- data/app/services/command_tower/messaging/execution/adapters/pushover/adapter.rb +107 -0
- data/app/services/command_tower/messaging/execution/adapters/pushover/configuration.rb +30 -0
- data/app/services/command_tower/messaging/execution/adapters/sms/adapter.rb +90 -0
- data/app/services/command_tower/messaging/execution/adapters/sms/configuration.rb +58 -0
- data/app/services/command_tower/messaging/execution/adapters/sms/log_adapter.rb +34 -0
- data/app/services/command_tower/messaging/execution/adapters/sms/twilio_http_client.rb +70 -0
- data/app/services/command_tower/messaging/execution/adapters/unconfigured_adapter.rb +20 -0
- data/app/services/command_tower/messaging/execution/attempt_ledger.rb +146 -0
- data/app/services/command_tower/messaging/execution/claim.rb +35 -0
- data/app/services/command_tower/messaging/execution/invalid_adapter_contract_error.rb +9 -0
- data/app/services/command_tower/messaging/execution/operation_logger.rb +237 -0
- data/app/services/command_tower/messaging/execution/readiness_terminal_mapping.rb +37 -0
- data/app/services/command_tower/messaging/execution/recovery.rb +78 -0
- data/app/services/command_tower/messaging/execution/resolve_recipient_address.rb +58 -0
- data/app/services/command_tower/messaging/execution/revalidate_readiness.rb +73 -0
- data/app/services/command_tower/messaging/execution/scheduler.rb +38 -0
- data/app/services/command_tower/messaging/execution/select_adapter.rb +63 -0
- data/app/services/command_tower/messaging/handoff/advance_communication.rb +39 -0
- data/app/services/command_tower/messaging/handoff/operation_logger.rb +78 -0
- data/app/services/command_tower/messaging/handoff/recovery.rb +26 -0
- data/app/services/command_tower/messaging/inbox/bulk_result.rb +19 -0
- data/app/services/command_tower/messaging/inbox/error.rb +9 -0
- data/app/services/command_tower/messaging/inbox/invalid_bulk_items_error.rb +19 -0
- data/app/services/command_tower/messaging/inbox/invariant_error.rb +9 -0
- data/app/services/command_tower/messaging/inbox/item_result.rb +64 -0
- data/app/services/command_tower/messaging/inbox/list_result.rb +18 -0
- data/app/services/command_tower/messaging/inbox/mutator.rb +252 -0
- data/app/services/command_tower/messaging/inbox/not_found_error.rb +9 -0
- data/app/services/command_tower/messaging/inbox/operation_logger.rb +37 -0
- data/app/services/command_tower/messaging/inbox/reader.rb +117 -0
- data/app/services/command_tower/messaging/inbox/scope.rb +24 -0
- data/app/services/command_tower/messaging/inbox/unread_count_result.rb +16 -0
- data/app/services/command_tower/messaging/inbox/validation_error.rb +9 -0
- data/app/services/command_tower/messaging/inbox.rb +61 -0
- data/app/services/command_tower/messaging/notification_types/catalog_category.rb +19 -0
- data/app/services/command_tower/messaging/notification_types/declaration.rb +96 -0
- data/app/services/command_tower/messaging/notification_types/declaration_validator.rb +152 -0
- data/app/services/command_tower/messaging/notification_types/duplicate_type_error.rb +9 -0
- data/app/services/command_tower/messaging/notification_types/error.rb +9 -0
- data/app/services/command_tower/messaging/notification_types/invalid_declaration_error.rb +9 -0
- data/app/services/command_tower/messaging/notification_types/not_found_error.rb +9 -0
- data/app/services/command_tower/messaging/notification_types/registry.rb +103 -0
- data/app/services/command_tower/messaging/notification_types/sealed_registry_error.rb +9 -0
- data/app/services/command_tower/messaging/notification_types.rb +37 -0
- data/app/services/command_tower/messaging/planner/destination_plan.rb +41 -0
- data/app/services/command_tower/messaging/planner/error.rb +9 -0
- data/app/services/command_tower/messaging/planner/excluded_destination.rb +28 -0
- data/app/services/command_tower/messaging/planner/illegal_override_error.rb +9 -0
- data/app/services/command_tower/messaging/planner/impossible_mandatory_plan_error.rb +9 -0
- data/app/services/command_tower/messaging/planner/invalid_evaluation_error.rb +9 -0
- data/app/services/command_tower/messaging/planner/message_overrides.rb +33 -0
- data/app/services/command_tower/messaging/planner/operation_logger.rb +28 -0
- data/app/services/command_tower/messaging/planner/planner.rb +261 -0
- data/app/services/command_tower/messaging/planner/unknown_type_error.rb +9 -0
- data/app/services/command_tower/messaging/planner.rb +25 -0
- data/app/services/command_tower/messaging/preferences/catalog.rb +96 -0
- data/app/services/command_tower/messaging/preferences/catalog_category_result.rb +19 -0
- data/app/services/command_tower/messaging/preferences/catalog_notification_result.rb +55 -0
- data/app/services/command_tower/messaging/preferences/catalog_result.rb +13 -0
- data/app/services/command_tower/messaging/preferences/error.rb +9 -0
- data/app/services/command_tower/messaging/preferences/evaluation_result.rb +61 -0
- data/app/services/command_tower/messaging/preferences/evaluator.rb +194 -0
- data/app/services/command_tower/messaging/preferences/invalid_preference_state_error.rb +9 -0
- data/app/services/command_tower/messaging/preferences/invalid_preference_write_error.rb +10 -0
- data/app/services/command_tower/messaging/preferences/not_settings_visible_error.rb +10 -0
- data/app/services/command_tower/messaging/preferences/preference_state.rb +61 -0
- data/app/services/command_tower/messaging/preferences/reason_classes.rb +17 -0
- data/app/services/command_tower/messaging/preferences/resolve.rb +50 -0
- data/app/services/command_tower/messaging/preferences/store.rb +126 -0
- data/app/services/command_tower/messaging/preferences/store_error.rb +10 -0
- data/app/services/command_tower/messaging/preferences/suppressed_destination.rb +24 -0
- data/app/services/command_tower/messaging/preferences/unknown_type_error.rb +9 -0
- data/app/services/command_tower/messaging/preferences/update.rb +248 -0
- data/app/services/command_tower/messaging/preferences.rb +68 -0
- data/app/services/command_tower/messaging/pushover/adapters/disabled_adapter.rb +33 -0
- data/app/services/command_tower/messaging/pushover/adapters/fake_adapter.rb +90 -0
- data/app/services/command_tower/messaging/pushover/adapters/http_adapter.rb +145 -0
- data/app/services/command_tower/messaging/pushover/adapters/log_adapter.rb +52 -0
- data/app/services/command_tower/messaging/pushover/result.rb +34 -0
- data/app/services/command_tower/messaging/pushover/transport.rb +64 -0
- data/app/services/command_tower/messaging/recipient_readiness/channel_result.rb +55 -0
- data/app/services/command_tower/messaging/recipient_readiness/error.rb +9 -0
- data/app/services/command_tower/messaging/recipient_readiness/evaluate.rb +319 -0
- data/app/services/command_tower/messaging/recipient_readiness/identity_facts.rb +54 -0
- data/app/services/command_tower/messaging/recipient_readiness/reason_codes.rb +33 -0
- data/app/services/command_tower/messaging/recipient_readiness/recipient_not_found_error.rb +9 -0
- data/app/services/command_tower/messaging/recipient_readiness/recipient_result.rb +38 -0
- data/app/services/command_tower/messaging/recipient_readiness/unknown_channel_error.rb +9 -0
- data/app/services/command_tower/messaging/recipient_readiness.rb +26 -0
- data/app/services/command_tower/messaging/rendering/channel_renderer.rb +127 -0
- data/app/services/command_tower/messaging/rendering/render_error.rb +24 -0
- data/app/services/command_tower/messaging/rendering/rendered_payload.rb +44 -0
- data/app/services/command_tower/messaging/rendering/rendered_pushover_payload.rb +43 -0
- data/app/services/command_tower/messaging/rendering/rendered_sms_payload.rb +40 -0
- data/app/services/command_tower/messaging.rb +35 -0
- data/app/services/command_tower/secrets/cleanse.rb +19 -5
- data/app/services/command_tower/secrets/generate.rb +62 -27
- data/app/services/command_tower/secrets/verify.rb +46 -12
- data/app/services/command_tower/secrets.rb +2 -0
- data/app/services/command_tower/services/account/clear_phone.rb +25 -0
- data/app/services/command_tower/services/account/phone_verification/send.rb +114 -0
- data/app/services/command_tower/services/account/phone_verification/verify.rb +88 -0
- data/app/services/command_tower/services/account/pushover/create.rb +28 -0
- data/app/services/command_tower/services/account/pushover/ct_support.rb +70 -0
- data/app/services/command_tower/services/account/pushover/destroy.rb +30 -0
- data/app/services/command_tower/services/account/pushover/replace.rb +28 -0
- data/app/services/command_tower/services/account/pushover/show.rb +19 -0
- data/app/services/command_tower/services/account/pushover/verify.rb +30 -0
- data/app/services/command_tower/services/account/update_phone.rb +50 -0
- data/app/services/command_tower/services/application_service.rb +21 -0
- data/app/services/command_tower/services/auth/authenticate_session.rb +105 -0
- data/app/services/command_tower/services/auth/authorize_request.rb +34 -0
- data/app/services/command_tower/services/auth/client_ip_resolver.rb +13 -0
- data/app/services/command_tower/services/auth/email_availability.rb +42 -0
- data/app/services/command_tower/services/auth/email_verification/send.rb +65 -0
- data/app/services/command_tower/services/auth/email_verification/verify.rb +51 -0
- data/app/services/command_tower/services/auth/identity_policy.rb +60 -0
- data/app/services/command_tower/services/auth/password_recovery/rate_limits/check_send.rb +48 -0
- data/app/services/command_tower/services/auth/password_recovery/rate_limits/check_token_issue.rb +35 -0
- data/app/services/command_tower/services/auth/password_recovery/rate_limits/enforcement.rb +53 -0
- data/app/services/command_tower/services/auth/password_recovery_session/create.rb +26 -0
- data/app/services/command_tower/services/auth/password_recovery_session/decode.rb +29 -0
- data/app/services/command_tower/services/auth/password_recovery_session/encode.rb +31 -0
- data/app/services/command_tower/services/auth/password_recovery_session/validate.rb +58 -0
- data/app/services/command_tower/services/auth/password_reset/reset.rb +65 -0
- data/app/services/command_tower/services/auth/password_reset/send.rb +77 -0
- data/app/services/command_tower/services/auth/password_reset/token_verification.rb +68 -0
- data/app/services/command_tower/services/auth/password_reset/validate.rb +29 -0
- data/app/services/command_tower/services/auth/plain_text/login.rb +44 -0
- data/app/services/command_tower/services/auth/register.rb +77 -0
- data/app/services/command_tower/services/auth/signup_rate_limits/check_availability.rb +52 -0
- data/app/services/command_tower/services/auth/signup_rate_limits/check_register.rb +24 -0
- data/app/services/command_tower/services/auth/signup_rate_limits/check_token_issue.rb +33 -0
- data/app/services/command_tower/services/auth/signup_rate_limits/enforcement.rb +50 -0
- data/app/services/command_tower/services/auth/signup_session/create.rb +26 -0
- data/app/services/command_tower/services/auth/signup_session/decode.rb +29 -0
- data/app/services/command_tower/services/auth/signup_session/encode.rb +31 -0
- data/app/services/command_tower/services/auth/signup_session/validate.rb +58 -0
- data/app/services/command_tower/services/auth/username_availability.rb +28 -0
- data/app/services/command_tower/services/me/capabilities.rb +43 -0
- data/app/services/command_tower/services/me/change_password.rb +84 -0
- data/app/services/command_tower/services/me/pushover_product_gate.rb +18 -0
- data/app/services/command_tower/services/me/sms_product_gate.rb +19 -0
- data/app/services/command_tower/services/me/update_name.rb +58 -0
- data/app/services/command_tower/services/messaging/communications/produce.rb +68 -0
- data/app/services/command_tower/services/messaging/communications/produce_many.rb +154 -0
- data/app/services/command_tower/services/messaging/inbox.rb +129 -0
- data/app/services/command_tower/services/messaging/preferences/platform_enabled_channels.rb +20 -0
- data/app/services/command_tower/services/messaging/preferences/show.rb +36 -0
- data/app/services/command_tower/services/messaging/preferences/update.rb +43 -0
- data/app/services/command_tower/services/messaging/recipients.rb +20 -0
- data/app/services/command_tower/services/rate_limits/check.rb +31 -0
- data/app/services/command_tower/services/service_result.rb +73 -0
- data/app/services/command_tower/user_attributes/mutate.rb +154 -0
- data/app/services/command_tower/username/available.rb +24 -11
- data/app/views/command_tower/email_verification_mailer/verify_email.html.erb +70 -22
- data/app/views/command_tower/messaging/rendering/email.html.erb +28 -0
- data/app/views/command_tower/messaging/rendering/email.text.erb +7 -0
- data/app/views/command_tower/messaging/rendering/pushover.text.erb +1 -0
- data/app/views/command_tower/messaging/rendering/sms.text.erb +1 -0
- data/app/views/command_tower/password_reset_mailer/reset_password.html.erb +107 -0
- data/app/views/layouts/mailer.html.erb +13 -0
- data/app/views/layouts/mailer.text.erb +1 -0
- data/app/workflows/command_tower/workflows/admin/messaging/create_announcement_workflow.rb +62 -0
- data/app/workflows/command_tower/workflows/application_workflow.rb +68 -0
- data/app/workflows/command_tower/workflows/auth/authenticate_request_workflow.rb +40 -0
- data/app/workflows/command_tower/workflows/auth/authentication_response_effects.rb +21 -0
- data/app/workflows/command_tower/workflows/auth/authorize_request_workflow.rb +28 -0
- data/app/workflows/command_tower/workflows/auth/email_availability_workflow.rb +39 -0
- data/app/workflows/command_tower/workflows/auth/email_verification/send_workflow.rb +32 -0
- data/app/workflows/command_tower/workflows/auth/email_verification/verify_workflow.rb +35 -0
- data/app/workflows/command_tower/workflows/auth/identity_error_status.rb +36 -0
- data/app/workflows/command_tower/workflows/auth/identity_policy_workflow.rb +26 -0
- data/app/workflows/command_tower/workflows/auth/logout_workflow.rb +19 -0
- data/app/workflows/command_tower/workflows/auth/password_recovery_session/authenticate_workflow.rb +49 -0
- data/app/workflows/command_tower/workflows/auth/password_recovery_session/create_workflow.rb +39 -0
- data/app/workflows/command_tower/workflows/auth/password_reset/reset_workflow.rb +40 -0
- data/app/workflows/command_tower/workflows/auth/password_reset/send_workflow.rb +45 -0
- data/app/workflows/command_tower/workflows/auth/password_reset/validate_workflow.rb +40 -0
- data/app/workflows/command_tower/workflows/auth/plain_text/login_workflow.rb +46 -0
- data/app/workflows/command_tower/workflows/auth/register_workflow.rb +83 -0
- data/app/workflows/command_tower/workflows/auth/session/show_workflow.rb +44 -0
- data/app/workflows/command_tower/workflows/auth/session_error_status.rb +30 -0
- data/app/workflows/command_tower/workflows/auth/signup_error_status.rb +31 -0
- data/app/workflows/command_tower/workflows/auth/signup_session/authenticate_workflow.rb +49 -0
- data/app/workflows/command_tower/workflows/auth/signup_session/create_workflow.rb +37 -0
- data/app/workflows/command_tower/workflows/auth/username_availability_workflow.rb +39 -0
- data/app/workflows/command_tower/workflows/me/change_password_workflow.rb +34 -0
- data/app/workflows/command_tower/workflows/me/clear_phone_workflow.rb +52 -0
- data/app/workflows/command_tower/workflows/me/error_mapping.rb +46 -0
- data/app/workflows/command_tower/workflows/me/error_status.rb +28 -0
- data/app/workflows/command_tower/workflows/me/phone_verification/send_workflow.rb +65 -0
- data/app/workflows/command_tower/workflows/me/phone_verification/verify_workflow.rb +57 -0
- data/app/workflows/command_tower/workflows/me/pushover/create_workflow.rb +38 -0
- data/app/workflows/command_tower/workflows/me/pushover/destroy_workflow.rb +34 -0
- data/app/workflows/command_tower/workflows/me/pushover/replace_workflow.rb +38 -0
- data/app/workflows/command_tower/workflows/me/pushover/show_workflow.rb +34 -0
- data/app/workflows/command_tower/workflows/me/pushover/verify_workflow.rb +34 -0
- data/app/workflows/command_tower/workflows/me/pushover/workflow_support.rb +31 -0
- data/app/workflows/command_tower/workflows/me/show_workflow.rb +33 -0
- data/app/workflows/command_tower/workflows/me/update_name_workflow.rb +48 -0
- data/app/workflows/command_tower/workflows/me/update_phone_workflow.rb +55 -0
- data/app/workflows/command_tower/workflows/messaging/communications/produce_recipient_workflow.rb +60 -0
- data/app/workflows/command_tower/workflows/messaging/error_mapping.rb +26 -0
- data/app/workflows/command_tower/workflows/messaging/execution/deliver_workflow.rb +234 -0
- data/app/workflows/command_tower/workflows/messaging/handoff/process_workflow.rb +90 -0
- data/app/workflows/command_tower/workflows/messaging/inbox.rb +97 -0
- data/app/workflows/command_tower/workflows/messaging/preferences/show_workflow.rb +31 -0
- data/app/workflows/command_tower/workflows/messaging/preferences/update_workflow.rb +37 -0
- data/app/workflows/command_tower/workflows/profile/show_workflow.rb +27 -0
- data/app/workflows/command_tower/workflows/workflow_result.rb +34 -0
- data/config/routes.rb +85 -37
- data/db/migrate/{20241117043720_create_command_tower_users.rb → 20260805000001_create_command_tower_users.rb} +7 -9
- data/db/migrate/{20241204065708_create_command_tower_user_secrets.rb → 20260805000002_create_command_tower_user_secrets.rb} +3 -0
- data/db/migrate/20260805000003_create_command_tower_messaging_core.rb +90 -0
- data/db/migrate/20260805000004_create_messaging_notification_preferences.rb +17 -0
- data/db/migrate/20260805000005_create_messaging_endpoints_and_pushover_credentials.rb +72 -0
- data/docs/api_reference.md +438 -0
- data/docs/architecture.md +30 -0
- data/docs/authentication.md +37 -0
- data/docs/authentication_authorization_guide.md +150 -0
- data/docs/authorization.md +34 -0
- data/docs/change_password_workflow.md +67 -0
- data/docs/controllers.md +35 -0
- data/docs/cookie_authentication_guide.md +167 -0
- data/docs/email_verification_workflow.md +58 -0
- data/docs/extending.md +105 -0
- data/docs/host_integration_guide.md +158 -0
- data/docs/initializing.md +169 -0
- data/docs/messaging_integration_guide.md +87 -0
- data/docs/models.md +51 -0
- data/docs/pagination.md +47 -0
- data/docs/password_reset_workflow.md +82 -0
- data/docs/sensitive_routes.md +47 -0
- data/docs/testing.md +74 -0
- data/docs/upgrades/0.10.0.md +58 -0
- data/docs/upgrades/README.md +9 -0
- data/lib/command_tower/authorization/default.yml +5 -33
- data/lib/command_tower/configuration/application/config.rb +2 -2
- data/lib/command_tower/configuration/base.rb +0 -1
- data/lib/command_tower/configuration/config.rb +41 -5
- data/lib/command_tower/configuration/credentials/config.rb +33 -0
- data/lib/command_tower/configuration/credentials/smtp.rb +33 -0
- data/lib/command_tower/configuration/credentials/twilio.rb +33 -0
- data/lib/command_tower/configuration/email/config.rb +1 -18
- data/lib/command_tower/configuration/identity/config.rb +19 -0
- data/lib/command_tower/configuration/identity/phone_verification.rb +54 -0
- data/lib/command_tower/configuration/jwt/config.rb +7 -0
- data/lib/command_tower/configuration/jwt/cookie/config.rb +64 -0
- data/lib/command_tower/configuration/jwt/cookie/csrf/config.rb +72 -0
- data/lib/command_tower/configuration/login/strategy/plain_text/config.rb +6 -0
- data/lib/command_tower/configuration/login/strategy/plain_text/email_verify.rb +5 -0
- data/lib/command_tower/configuration/login/strategy/plain_text/password_reset.rb +49 -0
- data/lib/command_tower/configuration/messaging/config.rb +60 -0
- data/lib/command_tower/configuration/messaging/pushover.rb +42 -0
- data/lib/command_tower/configuration/messaging/sms.rb +32 -0
- data/lib/command_tower/configuration/pagination/config.rb +16 -0
- data/lib/command_tower/configuration/password_recovery_session/config.rb +61 -0
- data/lib/command_tower/configuration/password_recovery_session/rate_limits.rb +33 -0
- data/lib/command_tower/configuration/signup_session/config.rb +67 -0
- data/lib/command_tower/configuration/signup_session/email_availability.rb +18 -0
- data/lib/command_tower/configuration/signup_session/rate_limits.rb +48 -0
- data/lib/command_tower/configuration/user/config.rb +6 -5
- data/lib/command_tower/credential_resolution/env_backend.rb +25 -0
- data/lib/command_tower/credential_resolution/smtp_action_mailer_bridge.rb +24 -0
- data/lib/command_tower/credential_resolution/smtp_credentials.rb +26 -0
- data/lib/command_tower/credential_resolution/twilio_credentials.rb +26 -0
- data/lib/command_tower/credential_resolution.rb +78 -0
- data/lib/command_tower/current.rb +7 -0
- data/lib/command_tower/engine.rb +4 -1
- data/lib/command_tower/install/baseline.rb +31 -0
- data/lib/command_tower/install/doctor.rb +227 -0
- data/lib/command_tower/jwt/authorization_helper.rb +136 -0
- data/lib/command_tower/jwt/csrf_helper.rb +138 -0
- data/lib/command_tower/password_recovery/authorization_helper.rb +25 -0
- data/lib/command_tower/redis_connection.rb +21 -0
- data/lib/command_tower/schema/error/email_validation_required.rb +15 -0
- data/lib/command_tower/schema/shared/user.rb +32 -0
- data/lib/command_tower/schema.rb +2 -25
- data/lib/command_tower/signup/authorization_helper.rb +25 -0
- data/lib/command_tower/spec_helper.rb +58 -1
- data/lib/command_tower/testing.rb +62 -0
- data/lib/command_tower/version.rb +1 -1
- data/lib/command_tower.rb +20 -0
- data/lib/generators/command_tower/configure/USAGE +20 -0
- data/lib/generators/command_tower/configure/configure_generator.rb +39 -0
- data/lib/tasks/auto_annotate_models.rake +23 -55
- data/lib/tasks/install.rake +81 -0
- data/lib/tasks/users.rake +119 -0
- data/spec/factories/entity.rb +37 -0
- data/spec/factories/messaging.rb +156 -0
- data/spec/factories/role.rb +29 -0
- data/spec/factories/user.rb +53 -0
- data/spec/factories/user_secret.rb +12 -0
- metadata +579 -53
- data/app/controllers/command_tower/admin_controller.rb +0 -104
- data/app/controllers/command_tower/auth/plain_text_controller.rb +0 -132
- data/app/controllers/command_tower/inbox/message_blast_controller.rb +0 -89
- data/app/controllers/command_tower/inbox/message_controller.rb +0 -79
- data/app/controllers/command_tower/user_controller.rb +0 -49
- data/app/controllers/command_tower/username_controller.rb +0 -26
- data/app/helpers/command_tower/schema_helper.rb +0 -29
- data/app/models/message.rb +0 -30
- data/app/models/message_blast.rb +0 -27
- data/app/services/command_tower/inbox_service/blast/delete.rb +0 -23
- data/app/services/command_tower/inbox_service/blast/metadata.rb +0 -26
- data/app/services/command_tower/inbox_service/blast/new_user_blaster.rb +0 -24
- data/app/services/command_tower/inbox_service/blast/retrieve.rb +0 -30
- data/app/services/command_tower/inbox_service/blast/upsert.rb +0 -67
- data/app/services/command_tower/inbox_service/message/metadata.rb +0 -35
- data/app/services/command_tower/inbox_service/message/modify.rb +0 -44
- data/app/services/command_tower/inbox_service/message/retrieve.rb +0 -36
- data/app/services/command_tower/inbox_service/message/send.rb +0 -33
- data/app/services/command_tower/jwt/time_delay_token.rb +0 -17
- data/app/services/command_tower/login_strategy/plain_text/create.rb +0 -43
- data/app/services/command_tower/login_strategy/plain_text/email_verification/generate.rb +0 -29
- data/app/services/command_tower/login_strategy/plain_text/email_verification/send.rb +0 -23
- data/app/services/command_tower/login_strategy/plain_text/email_verification/verify.rb +0 -24
- data/app/services/command_tower/login_strategy/plain_text/login.rb +0 -50
- data/app/services/command_tower/user_attributes/modify.rb +0 -68
- data/app/services/command_tower/user_attributes/roles.rb +0 -27
- data/db/migrate/20250223023306_create_command_tower_messages.rb +0 -12
- data/db/migrate/20250223023313_create_command_tower_message_blasts.rb +0 -14
- data/lib/command_tower/schema/admin/users.rb +0 -15
- data/lib/command_tower/schema/inbox/blast_request.rb +0 -15
- data/lib/command_tower/schema/inbox/blast_response.rb +0 -16
- data/lib/command_tower/schema/inbox/message_blast_entity.rb +0 -16
- data/lib/command_tower/schema/inbox/message_blast_metadata.rb +0 -16
- data/lib/command_tower/schema/inbox/message_entity.rb +0 -14
- data/lib/command_tower/schema/inbox/metadata.rb +0 -18
- data/lib/command_tower/schema/inbox/modified.rb +0 -13
- data/lib/command_tower/schema/page.rb +0 -14
- data/lib/command_tower/schema/plain_text/create_user_request.rb +0 -18
- data/lib/command_tower/schema/plain_text/create_user_response.rb +0 -17
- data/lib/command_tower/schema/plain_text/email_verify_request.rb +0 -11
- data/lib/command_tower/schema/plain_text/email_verify_response.rb +0 -11
- data/lib/command_tower/schema/plain_text/email_verify_send_request.rb +0 -9
- data/lib/command_tower/schema/plain_text/email_verify_send_response.rb +0 -11
- data/lib/command_tower/schema/plain_text/login_request.rb +0 -15
- data/lib/command_tower/schema/plain_text/login_response.rb +0 -13
- data/lib/command_tower/schema/user.rb +0 -28
- data/lib/generators/api_engine_base/configure/USAGE +0 -8
- data/lib/generators/api_engine_base/configure/configure_generator.rb +0 -12
|
@@ -21,12 +21,12 @@ module CommandTower
|
|
|
21
21
|
|
|
22
22
|
add_composer :url,
|
|
23
23
|
allowed: String,
|
|
24
|
-
default: ENV.fetch("
|
|
24
|
+
default: ENV.fetch("COMMAND_TOWER_FRONTEND_URL", "http://localhost"),
|
|
25
25
|
desc: "When composing SSO's or verification URL's, this is the URL for the application"
|
|
26
26
|
|
|
27
27
|
add_composer :port,
|
|
28
28
|
allowed: [String, NilClass],
|
|
29
|
-
default: ENV.fetch("
|
|
29
|
+
default: ENV.fetch("COMMAND_TOWER_FRONTEND_PORT", nil),
|
|
30
30
|
desc: "When composing SSO's or verification URL's, this is the PORT for the application"
|
|
31
31
|
|
|
32
32
|
add_composer :composed_url,
|
|
@@ -2,16 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
require "singleton"
|
|
4
4
|
require "class_composer"
|
|
5
|
+
require "command_tower/configuration/admin/config"
|
|
6
|
+
require "command_tower/configuration/application/config"
|
|
7
|
+
require "command_tower/configuration/authorization/config"
|
|
5
8
|
require "command_tower/configuration/base"
|
|
9
|
+
require "command_tower/configuration/credentials/config"
|
|
6
10
|
require "command_tower/configuration/email/config"
|
|
11
|
+
require "command_tower/configuration/identity/config"
|
|
7
12
|
require "command_tower/configuration/jwt/config"
|
|
13
|
+
require "command_tower/configuration/jwt/cookie/config"
|
|
8
14
|
require "command_tower/configuration/login/config"
|
|
15
|
+
require "command_tower/configuration/messaging/config"
|
|
9
16
|
require "command_tower/configuration/otp/config"
|
|
10
|
-
require "command_tower/configuration/
|
|
11
|
-
require "command_tower/configuration/
|
|
12
|
-
require "command_tower/configuration/
|
|
13
|
-
require "command_tower/configuration/authorization/config"
|
|
17
|
+
require "command_tower/configuration/pagination/config"
|
|
18
|
+
require "command_tower/configuration/password_recovery_session/config"
|
|
19
|
+
require "command_tower/configuration/signup_session/config"
|
|
14
20
|
require "command_tower/configuration/user/config"
|
|
21
|
+
require "command_tower/configuration/username/config"
|
|
15
22
|
|
|
16
23
|
module CommandTower
|
|
17
24
|
module Configuration
|
|
@@ -38,6 +45,11 @@ module CommandTower
|
|
|
38
45
|
allowed: Configuration::Email::Config,
|
|
39
46
|
default: Configuration::Email::Config.new
|
|
40
47
|
|
|
48
|
+
add_composer :credentials,
|
|
49
|
+
desc: "Deployment provider credentials (typed per provider under config.credentials.<provider>). Consumed by Credential Resolution. Not provider behavior configuration.",
|
|
50
|
+
allowed: Configuration::Credentials::Config,
|
|
51
|
+
default: Configuration::Credentials::Config.new
|
|
52
|
+
|
|
41
53
|
add_composer :username,
|
|
42
54
|
desc: "Username configuration for the app",
|
|
43
55
|
allowed: Configuration::Username::Config,
|
|
@@ -61,11 +73,36 @@ module CommandTower
|
|
|
61
73
|
allowed: Configuration::User::Config,
|
|
62
74
|
default: Configuration::User::Config.new
|
|
63
75
|
|
|
76
|
+
add_composer :identity,
|
|
77
|
+
desc: "Identity-owned capabilities (phone verification OTP, etc.)",
|
|
78
|
+
allowed: Configuration::Identity::Config,
|
|
79
|
+
default: Configuration::Identity::Config.new
|
|
80
|
+
|
|
81
|
+
add_composer :messaging,
|
|
82
|
+
desc: "Messaging delivery configuration (notification SMS, etc.). Separate from Identity OTP.",
|
|
83
|
+
allowed: Configuration::Messaging::Config,
|
|
84
|
+
default: Configuration::Messaging::Config.new
|
|
85
|
+
|
|
64
86
|
add_composer :admin,
|
|
65
87
|
desc: "Admin configuration for the app",
|
|
66
88
|
allowed: Configuration::Admin::Config,
|
|
67
89
|
default: Configuration::Admin::Config.new
|
|
68
90
|
|
|
91
|
+
add_composer :pagination,
|
|
92
|
+
desc: "Pagination configuration for the app",
|
|
93
|
+
allowed: Configuration::Pagination::Config,
|
|
94
|
+
default: Configuration::Pagination::Config.new
|
|
95
|
+
|
|
96
|
+
add_composer :signup_session,
|
|
97
|
+
desc: "Signup session token claims, TTL, and signup rate limit ceilings",
|
|
98
|
+
allowed: Configuration::SignupSession::Config,
|
|
99
|
+
default: Configuration::SignupSession::Config.new
|
|
100
|
+
|
|
101
|
+
add_composer :password_recovery_session,
|
|
102
|
+
desc: "Password recovery session token claims, TTL, and recovery rate limit ceilings",
|
|
103
|
+
allowed: Configuration::PasswordRecoverySession::Config,
|
|
104
|
+
default: Configuration::PasswordRecoverySession::Config.new
|
|
105
|
+
|
|
69
106
|
# To be Deleted
|
|
70
107
|
add_composer :otp,
|
|
71
108
|
desc: "One Time Password generation is used for ease in quickly validating a users actions. This is good for short term validation requirements as opposed to UserSecrets",
|
|
@@ -74,4 +111,3 @@ module CommandTower
|
|
|
74
111
|
end
|
|
75
112
|
end
|
|
76
113
|
end
|
|
77
|
-
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "class_composer"
|
|
4
|
+
require "command_tower/configuration/credentials/twilio"
|
|
5
|
+
require "command_tower/configuration/credentials/smtp"
|
|
6
|
+
|
|
7
|
+
module CommandTower
|
|
8
|
+
module Configuration
|
|
9
|
+
module Credentials
|
|
10
|
+
# Deployment provider credentials namespace (typed per provider).
|
|
11
|
+
# Each provider owns its own credential object — no shared generic fields.
|
|
12
|
+
class Config < ::CommandTower::Configuration::Base
|
|
13
|
+
include ClassComposer::Generator
|
|
14
|
+
|
|
15
|
+
add_composer :twilio,
|
|
16
|
+
desc: "Twilio deployment credentials (account_sid, auth_token). Typed per provider; consumed by Credential Resolution.",
|
|
17
|
+
allowed: Twilio,
|
|
18
|
+
default: Twilio.new
|
|
19
|
+
|
|
20
|
+
add_composer :smtp,
|
|
21
|
+
desc: "SMTP deployment credentials (user_name, password). Typed per provider; consumed by Credential Resolution.",
|
|
22
|
+
allowed: Smtp,
|
|
23
|
+
default: Smtp.new
|
|
24
|
+
|
|
25
|
+
def inspect
|
|
26
|
+
"#<#{self.class.name} twilio=[REDACTED] smtp=[REDACTED]>"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
alias_method :pretty_inspect, :inspect
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "class_composer"
|
|
4
|
+
|
|
5
|
+
module CommandTower
|
|
6
|
+
module Configuration
|
|
7
|
+
module Credentials
|
|
8
|
+
# Explicit SMTP deployment credentials (config.credentials.smtp).
|
|
9
|
+
# Consumed by CredentialResolution — not provider behavior configuration.
|
|
10
|
+
class Smtp < ::CommandTower::Configuration::Base
|
|
11
|
+
include ClassComposer::Generator
|
|
12
|
+
|
|
13
|
+
add_composer :user_name,
|
|
14
|
+
desc: "SMTP username. Explicit supply for Credential Resolution under config.credentials.smtp. Also used as Messaging ChannelMailer From when present. Alternatives: custom credential_resolver or GMAIL_USER_NAME ENV.",
|
|
15
|
+
allowed: String,
|
|
16
|
+
default: "",
|
|
17
|
+
default_shown: '""'
|
|
18
|
+
|
|
19
|
+
add_composer :password,
|
|
20
|
+
desc: "SMTP password. Explicit supply for Credential Resolution under config.credentials.smtp. Alternatives: custom credential_resolver or GMAIL_PASSWORD ENV.",
|
|
21
|
+
allowed: String,
|
|
22
|
+
default: "",
|
|
23
|
+
default_shown: '""'
|
|
24
|
+
|
|
25
|
+
def inspect
|
|
26
|
+
"#<#{self.class.name} user_name=[REDACTED] password=[REDACTED]>"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
alias_method :pretty_inspect, :inspect
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "class_composer"
|
|
4
|
+
|
|
5
|
+
module CommandTower
|
|
6
|
+
module Configuration
|
|
7
|
+
module Credentials
|
|
8
|
+
# Canonical explicit Twilio deployment credentials (config.credentials.twilio).
|
|
9
|
+
# Consumed by CredentialResolution — not provider behavior configuration.
|
|
10
|
+
class Twilio < ::CommandTower::Configuration::Base
|
|
11
|
+
include ClassComposer::Generator
|
|
12
|
+
|
|
13
|
+
add_composer :account_sid,
|
|
14
|
+
desc: "Twilio Account SID. Canonical explicit supply for Credential Resolution. Prefer this over ENV when setting credentials in CommandTower.configure.",
|
|
15
|
+
allowed: String,
|
|
16
|
+
default: "",
|
|
17
|
+
default_shown: '""'
|
|
18
|
+
|
|
19
|
+
add_composer :auth_token,
|
|
20
|
+
desc: "Twilio Auth Token. Canonical explicit supply for Credential Resolution. Prefer this over ENV when setting credentials in CommandTower.configure.",
|
|
21
|
+
allowed: String,
|
|
22
|
+
default: "",
|
|
23
|
+
default_shown: '""'
|
|
24
|
+
|
|
25
|
+
def inspect
|
|
26
|
+
"#<#{self.class.name} account_sid=[REDACTED] auth_token=[REDACTED]>"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
alias_method :pretty_inspect, :inspect
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -15,20 +15,6 @@ module CommandTower
|
|
|
15
15
|
Rails.configuration.action_mailer.public_send(:"#{key}=", value)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
add_composer :user_name,
|
|
19
|
-
desc: "User Name for email. Defaults to ENV['GMAIL_USER_NAME']",
|
|
20
|
-
allowed: String,
|
|
21
|
-
default: ENV.fetch("GMAIL_USER_NAME", ""),
|
|
22
|
-
default_shown: "ENV[\"GMAIL_USER_NAME\"]",
|
|
23
|
-
&ASSIGNMENT
|
|
24
|
-
|
|
25
|
-
add_composer :password,
|
|
26
|
-
desc: "Password for email. Defaults to ENV['GMAIL_PASSWORD']. For more info on how to get this for GMAIL...https://support.google.com/accounts/answer/185833",
|
|
27
|
-
allowed: String,
|
|
28
|
-
default: ENV.fetch("GMAIL_PASSWORD", ""),
|
|
29
|
-
default_shown: "ENV[\"GMAIL_PASSWORD\"]",
|
|
30
|
-
&ASSIGNMENT
|
|
31
|
-
|
|
32
18
|
add_composer :port,
|
|
33
19
|
allowed: Integer,
|
|
34
20
|
default: 587,
|
|
@@ -66,16 +52,13 @@ module CommandTower
|
|
|
66
52
|
default: true,
|
|
67
53
|
&ACTION_MAILER
|
|
68
54
|
|
|
55
|
+
# Non-secret Gmail SMTP behavior helper. Credentials: config.credentials.smtp.* or ENV.
|
|
69
56
|
def gmail!(
|
|
70
|
-
from: ENV["GMAIL_USER_NAME"],
|
|
71
|
-
password: ENV["GMAIL_PASSWORD"],
|
|
72
57
|
port: 587,
|
|
73
58
|
address: "smtp.gmail.com",
|
|
74
59
|
authentication: "plain",
|
|
75
60
|
enable_starttls_auto: true
|
|
76
61
|
)
|
|
77
|
-
method(:from=).call(from)
|
|
78
|
-
method(:password=).call(password)
|
|
79
62
|
method(:port=).call(port)
|
|
80
63
|
method(:address=).call(address)
|
|
81
64
|
method(:authentication=).call(authentication)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "class_composer"
|
|
4
|
+
require "command_tower/configuration/identity/phone_verification"
|
|
5
|
+
|
|
6
|
+
module CommandTower
|
|
7
|
+
module Configuration
|
|
8
|
+
module Identity
|
|
9
|
+
class Config < ::CommandTower::Configuration::Base
|
|
10
|
+
include ClassComposer::Generator
|
|
11
|
+
|
|
12
|
+
add_composer :phone_verification,
|
|
13
|
+
desc: "Identity phone verification OTP configuration",
|
|
14
|
+
allowed: PhoneVerification,
|
|
15
|
+
default: PhoneVerification.new
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "class_composer"
|
|
4
|
+
|
|
5
|
+
module CommandTower
|
|
6
|
+
module Configuration
|
|
7
|
+
module Identity
|
|
8
|
+
class PhoneVerification < ::CommandTower::Configuration::Base
|
|
9
|
+
include ClassComposer::Generator
|
|
10
|
+
|
|
11
|
+
# Same validation style as Configuration::Messaging::Sms (ADAPTERS + ClassComposer validator).
|
|
12
|
+
ADAPTERS = %w[fake log twilio].freeze
|
|
13
|
+
|
|
14
|
+
add_composer :enable,
|
|
15
|
+
desc: "Enable Identity phone verification OTP send/verify",
|
|
16
|
+
allowed: [FalseClass, TrueClass],
|
|
17
|
+
default: true
|
|
18
|
+
|
|
19
|
+
add_composer :verify_code_length,
|
|
20
|
+
desc: "Length of the numeric phone verification OTP (Generate + Identity Policy)",
|
|
21
|
+
allowed: Integer,
|
|
22
|
+
default: 6,
|
|
23
|
+
validator: ->(val) { (val <= 10) && (val >= 4) },
|
|
24
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be between 4 and 10 inclusive." }
|
|
25
|
+
|
|
26
|
+
add_composer :verify_code_valid_for,
|
|
27
|
+
desc: "How long a phone verification OTP remains valid",
|
|
28
|
+
allowed: ActiveSupport::Duration,
|
|
29
|
+
default: 10.minutes,
|
|
30
|
+
validator: ->(val) { val < 60.minutes },
|
|
31
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be less than #{60.minutes}" }
|
|
32
|
+
|
|
33
|
+
add_composer :resend_cooldown,
|
|
34
|
+
desc: "Minimum time between phone verification OTP sends for the same user",
|
|
35
|
+
allowed: ActiveSupport::Duration,
|
|
36
|
+
default: 30.seconds,
|
|
37
|
+
validator: ->(val) { val >= 0.seconds && val < 60.minutes },
|
|
38
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be >= 0 and less than #{60.minutes}" }
|
|
39
|
+
|
|
40
|
+
add_composer :sms_from,
|
|
41
|
+
desc: "Sender identity for phone verification SMS (provider-specific)",
|
|
42
|
+
allowed: [String, NilClass],
|
|
43
|
+
default: nil
|
|
44
|
+
|
|
45
|
+
add_composer :sms_adapter,
|
|
46
|
+
desc: "SMS transport adapter name: fake | log | twilio",
|
|
47
|
+
allowed: String,
|
|
48
|
+
default: "fake",
|
|
49
|
+
validator: ->(val) { ADAPTERS.include?(val.to_s) },
|
|
50
|
+
invalid_message: ->(val) { "Provided #{val.inspect}. Allowed: #{ADAPTERS.join(', ')}" }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "command_tower/configuration/jwt/cookie/config"
|
|
4
|
+
|
|
3
5
|
module CommandTower
|
|
4
6
|
module Configuration
|
|
5
7
|
module Jwt
|
|
@@ -16,6 +18,11 @@ module CommandTower
|
|
|
16
18
|
allowed: String,
|
|
17
19
|
default: ENV.fetch("SECRET_KEY_BASE","Thi$IsASeccretIwi::CH&ang3"),
|
|
18
20
|
default_shown: "ENV.fetch(\"SECRET_KEY_BASE\",\"Thi$IsASeccretIwi::CH&ang3\")"
|
|
21
|
+
|
|
22
|
+
add_composer_blocking :cookie,
|
|
23
|
+
desc: "HttpOnly cookie configuration for JWT token persistence",
|
|
24
|
+
composer_class: Cookie::Config,
|
|
25
|
+
enable_attr: :enabled
|
|
19
26
|
end
|
|
20
27
|
end
|
|
21
28
|
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "command_tower/configuration/jwt/cookie/csrf/config"
|
|
4
|
+
|
|
5
|
+
module CommandTower
|
|
6
|
+
module Configuration
|
|
7
|
+
module Jwt
|
|
8
|
+
module Cookie
|
|
9
|
+
class Config < ::CommandTower::Configuration::Base
|
|
10
|
+
include ClassComposer::Generator
|
|
11
|
+
|
|
12
|
+
add_composer :enabled,
|
|
13
|
+
desc: "Enable HttpOnly cookie support for JWT tokens. When disabled, cookies are never set, read, or refreshed",
|
|
14
|
+
allowed: [TrueClass, FalseClass],
|
|
15
|
+
default: false
|
|
16
|
+
|
|
17
|
+
add_composer :name,
|
|
18
|
+
desc: "Name of the JWT cookie",
|
|
19
|
+
allowed: String,
|
|
20
|
+
default: "ct_jwt"
|
|
21
|
+
|
|
22
|
+
add_composer :same_site,
|
|
23
|
+
desc: "SameSite attribute for the cookie (:lax, :strict, or :none)",
|
|
24
|
+
allowed: Symbol,
|
|
25
|
+
default: :lax
|
|
26
|
+
|
|
27
|
+
add_composer :secure,
|
|
28
|
+
desc: "Secure flag for the cookie (HTTPS only). Defaults to false in development, true in production",
|
|
29
|
+
allowed: [TrueClass, FalseClass],
|
|
30
|
+
default: false
|
|
31
|
+
|
|
32
|
+
add_composer :httponly,
|
|
33
|
+
desc: "HttpOnly flag for the cookie (prevents JavaScript access)",
|
|
34
|
+
allowed: [TrueClass, FalseClass],
|
|
35
|
+
default: true
|
|
36
|
+
|
|
37
|
+
add_composer :path,
|
|
38
|
+
desc: "Path for the cookie",
|
|
39
|
+
allowed: String,
|
|
40
|
+
default: "/"
|
|
41
|
+
|
|
42
|
+
add_composer :domain,
|
|
43
|
+
desc: "Domain for the cookie (nil means host-only)",
|
|
44
|
+
allowed: [String, NilClass],
|
|
45
|
+
default: nil
|
|
46
|
+
|
|
47
|
+
add_composer :ttl,
|
|
48
|
+
desc: "Time to live for the cookie (defaults to JWT TTL)",
|
|
49
|
+
allowed: ActiveSupport::Duration,
|
|
50
|
+
default: 7.days
|
|
51
|
+
|
|
52
|
+
add_composer_blocking :csrf,
|
|
53
|
+
desc: "Double-submit CSRF protection configuration for cookie-authenticated requests",
|
|
54
|
+
composer_class: Csrf::Config,
|
|
55
|
+
enable_attr: :enabled
|
|
56
|
+
|
|
57
|
+
def enabled?
|
|
58
|
+
enabled
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CommandTower
|
|
4
|
+
module Configuration
|
|
5
|
+
module Jwt
|
|
6
|
+
module Cookie
|
|
7
|
+
module Csrf
|
|
8
|
+
class Config < ::CommandTower::Configuration::Base
|
|
9
|
+
include ClassComposer::Generator
|
|
10
|
+
|
|
11
|
+
add_composer :enabled,
|
|
12
|
+
desc: "Enable double-submit CSRF protection for cookie-authenticated requests",
|
|
13
|
+
allowed: [TrueClass, FalseClass],
|
|
14
|
+
default: false
|
|
15
|
+
|
|
16
|
+
add_composer :cookie_name,
|
|
17
|
+
desc: "Name of the CSRF token cookie (must NOT be HttpOnly)",
|
|
18
|
+
allowed: String,
|
|
19
|
+
default: "ct_csrf"
|
|
20
|
+
|
|
21
|
+
add_composer :header_name,
|
|
22
|
+
desc: "Name of the CSRF token header",
|
|
23
|
+
allowed: String,
|
|
24
|
+
default: "X-CSRF-Token"
|
|
25
|
+
|
|
26
|
+
add_composer :rotate_on_login,
|
|
27
|
+
desc: "Rotate CSRF token on login",
|
|
28
|
+
allowed: [TrueClass, FalseClass],
|
|
29
|
+
default: true
|
|
30
|
+
|
|
31
|
+
add_composer :rotate_on_reset,
|
|
32
|
+
desc: "Rotate CSRF token when JWT token is reset",
|
|
33
|
+
allowed: [TrueClass, FalseClass],
|
|
34
|
+
default: true
|
|
35
|
+
|
|
36
|
+
# Note: rotate_on_logout removed - logout always clears CSRF cookie (not configurable)
|
|
37
|
+
|
|
38
|
+
# Cookie attributes (default to nil to inherit from JWT cookie settings)
|
|
39
|
+
add_composer :same_site,
|
|
40
|
+
desc: "SameSite attribute for CSRF cookie (nil inherits from JWT cookie)",
|
|
41
|
+
allowed: [Symbol, NilClass],
|
|
42
|
+
default: nil
|
|
43
|
+
|
|
44
|
+
add_composer :secure,
|
|
45
|
+
desc: "Secure flag for CSRF cookie (nil inherits from JWT cookie)",
|
|
46
|
+
allowed: [TrueClass, FalseClass, NilClass],
|
|
47
|
+
default: nil
|
|
48
|
+
|
|
49
|
+
add_composer :path,
|
|
50
|
+
desc: "Path for the CSRF cookie (nil inherits from JWT cookie)",
|
|
51
|
+
allowed: [String, NilClass],
|
|
52
|
+
default: nil
|
|
53
|
+
|
|
54
|
+
add_composer :domain,
|
|
55
|
+
desc: "Domain for the CSRF cookie (nil inherits from JWT cookie)",
|
|
56
|
+
allowed: [String, NilClass],
|
|
57
|
+
default: nil
|
|
58
|
+
|
|
59
|
+
add_composer :ttl,
|
|
60
|
+
desc: "Time to live for the CSRF cookie",
|
|
61
|
+
allowed: ActiveSupport::Duration,
|
|
62
|
+
default: 7.days
|
|
63
|
+
|
|
64
|
+
def enabled?
|
|
65
|
+
enabled
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "command_tower/configuration/login/strategy/plain_text/lockable"
|
|
4
4
|
require "command_tower/configuration/login/strategy/plain_text/email_verify"
|
|
5
|
+
require "command_tower/configuration/login/strategy/plain_text/password_reset"
|
|
5
6
|
|
|
6
7
|
module CommandTower
|
|
7
8
|
module Configuration
|
|
@@ -26,6 +27,11 @@ module CommandTower
|
|
|
26
27
|
composer_class: EmailVerify,
|
|
27
28
|
enable_attr: :enable
|
|
28
29
|
|
|
30
|
+
add_composer_blocking :password_reset,
|
|
31
|
+
desc: "Enable and change Password Reset for User/Password Login strategy.",
|
|
32
|
+
composer_class: PasswordReset,
|
|
33
|
+
enable_attr: :enabled
|
|
34
|
+
|
|
29
35
|
add_composer :password_length_max,
|
|
30
36
|
desc: "Max Length for Password",
|
|
31
37
|
allowed: Integer,
|
|
@@ -42,6 +42,11 @@ module CommandTower
|
|
|
42
42
|
default: 6,
|
|
43
43
|
validator: -> (val) { (val <= 10) && (val >= 4) },
|
|
44
44
|
invalid_message: ->(val) { "Provided #{val}. Value must be less than or equal to 10 and greater than or equal to 4." }
|
|
45
|
+
|
|
46
|
+
add_composer :custom_template_name,
|
|
47
|
+
desc: "Custom template name to use for the email verification email. Allows using a different view template without creating a custom mailer class. The template should be located at app/views/command_tower/email_verification_mailer/{template_name}.html.erb. Defaults to 'verify_email'",
|
|
48
|
+
allowed: [String, NilClass],
|
|
49
|
+
default: nil
|
|
45
50
|
end
|
|
46
51
|
end
|
|
47
52
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CommandTower
|
|
4
|
+
module Configuration
|
|
5
|
+
module Login
|
|
6
|
+
module Strategy
|
|
7
|
+
module PlainText
|
|
8
|
+
class PasswordReset < ::CommandTower::Configuration::Base
|
|
9
|
+
include ClassComposer::Generator
|
|
10
|
+
|
|
11
|
+
add_composer :enabled,
|
|
12
|
+
desc: "Password reset feature allows users to request password reset via email. By default this is enabled",
|
|
13
|
+
allowed: [FalseClass, TrueClass],
|
|
14
|
+
default: true
|
|
15
|
+
|
|
16
|
+
add_composer :token_valid_for,
|
|
17
|
+
desc: "When the password reset token is sent, how long will that token be valid for. By default, this is set to 1 hour",
|
|
18
|
+
allowed: ActiveSupport::Duration,
|
|
19
|
+
default: 10.minutes,
|
|
20
|
+
validator: -> (val) { val < 24.hours },
|
|
21
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be less than #{24.hours}" }
|
|
22
|
+
|
|
23
|
+
add_composer :token_length,
|
|
24
|
+
desc: "The length of the password reset token sent via email.",
|
|
25
|
+
allowed: Integer,
|
|
26
|
+
default: 32,
|
|
27
|
+
validator: -> (val) { (val <= 64) && (val >= 16) },
|
|
28
|
+
invalid_message: ->(val) { "Provided #{val}. Value must be less than or equal to 64 and greater than or equal to 16." }
|
|
29
|
+
|
|
30
|
+
add_composer :custom_template_name,
|
|
31
|
+
desc: "Custom template name to use for the password reset email. Allows using a different view template without creating a custom mailer class. The template should be located at app/views/command_tower/password_reset_mailer/{template_name}.html.erb. Defaults to 'reset_password'",
|
|
32
|
+
allowed: [String, NilClass],
|
|
33
|
+
default: nil
|
|
34
|
+
|
|
35
|
+
add_composer :require_email,
|
|
36
|
+
desc: "When enabled, requires users to provide both token and email when validating or resetting password. This adds an additional security layer to prevent brute force attacks. Defaults to false for backward compatibility.",
|
|
37
|
+
allowed: [FalseClass, TrueClass],
|
|
38
|
+
default: false
|
|
39
|
+
|
|
40
|
+
add_composer :reset_password_path,
|
|
41
|
+
desc: "The path (not full URL) to the frontend reset password page. This path will be appended to CommandTower.config.app.composed_url to form the full URL. Used in email template for the reset link. Defaults to '/reset-password'",
|
|
42
|
+
allowed: String,
|
|
43
|
+
default: "/reset-password"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "class_composer"
|
|
4
|
+
require "command_tower/configuration/messaging/sms"
|
|
5
|
+
require "command_tower/configuration/messaging/pushover"
|
|
6
|
+
|
|
7
|
+
module CommandTower
|
|
8
|
+
module Configuration
|
|
9
|
+
module Messaging
|
|
10
|
+
class Config < ::CommandTower::Configuration::Base
|
|
11
|
+
include ClassComposer::Generator
|
|
12
|
+
|
|
13
|
+
add_composer :allow_fake_adapter,
|
|
14
|
+
desc: "Platform testing/development execution override: when true, Execution selects " \
|
|
15
|
+
"Execution::Adapters::FakeAdapter for any channel. Not provider configuration — " \
|
|
16
|
+
"intentionally separate from config.messaging.sms.adapter / pushover.adapter. " \
|
|
17
|
+
"Default false (fail-closed). Precedence: injected executor → this flag → " \
|
|
18
|
+
"normal provider adapter selection.",
|
|
19
|
+
allowed: [TrueClass, FalseClass],
|
|
20
|
+
default: false
|
|
21
|
+
|
|
22
|
+
add_composer :platform_enabled_channels,
|
|
23
|
+
desc: "Host-owned callable returning the Array of channel keys currently enabled for " \
|
|
24
|
+
"this platform (Preferences HTTP, Accept/Planner injection). CommandTower does " \
|
|
25
|
+
"not invent product enablement; hosts assign a Proc (e.g. wrapping " \
|
|
26
|
+
"PlatformEnabledChannels). Default fail-closed empty list.",
|
|
27
|
+
allowed: [Proc],
|
|
28
|
+
default: -> { [] },
|
|
29
|
+
default_shown: "-> { [] }"
|
|
30
|
+
|
|
31
|
+
add_composer :welcome_content,
|
|
32
|
+
desc: "Host-owned callable returning nil or a Hash of welcome Produce fields " \
|
|
33
|
+
"({ notification_type_key:, title:, body:, metadata? }). " \
|
|
34
|
+
"Default nil Proc → RegisterWorkflow skips welcome emit. " \
|
|
35
|
+
"CommandTower does not own product welcome copy.",
|
|
36
|
+
allowed: [Proc],
|
|
37
|
+
default: -> { nil },
|
|
38
|
+
default_shown: "-> { nil }"
|
|
39
|
+
|
|
40
|
+
add_composer :resolve_announcement_audience,
|
|
41
|
+
desc: "Host-owned callable receiving a selection Hash ({ mode:, ids? }) and returning " \
|
|
42
|
+
"an Array of Integer user ids for ProduceMany. Default empty list (fail-closed). " \
|
|
43
|
+
"CommandTower never runs product audience queries.",
|
|
44
|
+
allowed: [Proc],
|
|
45
|
+
default: ->(_selection) { [] },
|
|
46
|
+
default_shown: "->(_selection) { [] }"
|
|
47
|
+
|
|
48
|
+
add_composer :sms,
|
|
49
|
+
desc: "Messaging notification SMS delivery configuration (not Identity OTP)",
|
|
50
|
+
allowed: Sms,
|
|
51
|
+
default: Sms.new
|
|
52
|
+
|
|
53
|
+
add_composer :pushover,
|
|
54
|
+
desc: "Pushover verification transport configuration (credential validate + test notification)",
|
|
55
|
+
allowed: Pushover,
|
|
56
|
+
default: Pushover.new
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "class_composer"
|
|
4
|
+
|
|
5
|
+
module CommandTower
|
|
6
|
+
module Configuration
|
|
7
|
+
module Messaging
|
|
8
|
+
class Pushover < ::CommandTower::Configuration::Base
|
|
9
|
+
include ClassComposer::Generator
|
|
10
|
+
|
|
11
|
+
ADAPTERS = %w[disabled fake log http].freeze
|
|
12
|
+
|
|
13
|
+
add_composer :adapter,
|
|
14
|
+
desc: "Pushover verification transport: disabled | fake | log | http. Default disabled (fail closed).",
|
|
15
|
+
allowed: String,
|
|
16
|
+
default: "disabled",
|
|
17
|
+
validator: ->(val) { ADAPTERS.include?(val.to_s) },
|
|
18
|
+
invalid_message: ->(val) { "Provided #{val.inspect}. Allowed: #{ADAPTERS.join(', ')}" }
|
|
19
|
+
|
|
20
|
+
add_composer :api_base_url,
|
|
21
|
+
desc: "Pushover API base URL (versioned path included).",
|
|
22
|
+
allowed: String,
|
|
23
|
+
default: "https://api.pushover.net/1"
|
|
24
|
+
|
|
25
|
+
add_composer :timeout_seconds,
|
|
26
|
+
desc: "HTTP open/read timeout seconds for Pushover provider calls.",
|
|
27
|
+
allowed: Integer,
|
|
28
|
+
default: 5
|
|
29
|
+
|
|
30
|
+
add_composer :test_title,
|
|
31
|
+
desc: "Title for Pushover verification/test notification. Neutral default; hosts override product copy.",
|
|
32
|
+
allowed: String,
|
|
33
|
+
default: "Pushover verification"
|
|
34
|
+
|
|
35
|
+
add_composer :test_message,
|
|
36
|
+
desc: "Body for Pushover verification/test notification.",
|
|
37
|
+
allowed: String,
|
|
38
|
+
default: "Your Pushover credentials were verified successfully."
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|