diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 12221631e..8d6d4a653 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -2,7 +2,7 @@ version: 2 updates: - package-ecosystem: "npm" directory: "/" - target-branch: "stage-main-14.1" + target-branch: "stage-main-14.2" schedule: interval: "weekly" day: "monday" @@ -10,4 +10,4 @@ updates: rebase-strategy: auto open-pull-requests-limit: 10 labels: - - "A-dependencies" \ No newline at end of file + - "A-dependencies" diff --git a/README.md b/README.md index d5cf27cc3..4cd70783d 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Want to know more? This version of Spoke suitable for testing and, potentially, for small campaigns. This won't cost any money and will not support production(aka large-scale) usage. It's a great way to practice deploying Spoke or see it in action. - + Deploy diff --git a/app.json b/app.json index f98432b9e..944532bdb 100644 --- a/app.json +++ b/app.json @@ -183,7 +183,7 @@ } }, "addons": [ - "heroku-postgresql:basic", + "heroku-postgresql:essential-0", { "plan": "heroku-redis:mini", "options": { diff --git a/docs/HOWTO_USE_POSTGRESQL.md b/docs/HOWTO_USE_POSTGRESQL.md index cff2f0787..2c817b8d3 100644 --- a/docs/HOWTO_USE_POSTGRESQL.md +++ b/docs/HOWTO_USE_POSTGRESQL.md @@ -3,9 +3,19 @@ To use Postgresql, follow these steps: 1. Either install docker (recommended) or postgresql on your machine: - * If you installed docker run the database using: `docker compose up` - * If you installed postgres locally, create the spoke dev database: `psql -c "create database spokedev;"` - * Then create a spoke user to connect to the database with `createuser -P spoke` with password "spoke" (to match the credentials in the .env.example file) + * If you installed docker run the database using: `docker-compose up` + * If you installed postgres locally (or if you already have a local installation of postgres), create the spoke dev database: `psql -c "create database spokedev;"` + * Then create a spoke user to connect to the database with `psql -d spokedev -c "create user spoke with password 'spoke';"` (to match the credentials in the .env.example file) + * Grant permissions to the new Spoke user: + * `psql -d spokedev -c "GRANT ALL PRIVILEGES ON DATABASE spokedev TO spoke;"` + * `psql -d spokedev -c "GRANT ALL PRIVILEGES ON schema public TO spoke;"` + * Create a test database by running the following commands: + ``` + psql -d spokedev + CREATE DATABASE spoke_test; + CREATE USER spoke_test WITH PASSWORD 'spoke_test'; + GRANT ALL PRIVILEGES ON DATABASE spoke_test TO spoke_test; + ``` 1. In `.env` set `DB_TYPE=pg`. (Otherwise, you will use sqlite.) 2. Set `DB_PORT=5432`, which is the default port for Postgres. diff --git a/docs/REFERENCE-environment_variables.md b/docs/REFERENCE-environment_variables.md index 5d2594446..2eaa355cd 100644 --- a/docs/REFERENCE-environment_variables.md +++ b/docs/REFERENCE-environment_variables.md @@ -40,6 +40,7 @@ | DEV_APP_PORT | Port for development Webpack server. Required for development. | | DOWNTIME | When enabled it will redirect users to a /downtime page. If set to a string, it will show the string as a message to users on the downtime page. Use this to take the system down for maintenance. It will NOT stop graphql requests and will NOT stop users that are already in the app. | | DOWNTIME_NO_DB | On AWS Lambda this blocks the site from loading the app at all and swaps out a system that redirects users to /downtime. This is useful for DB maintenance. For non-Lambda environments, just run the src/server/downtime app instead of src/server/index default app | +| DOWNTIME_NO_INITIAL | When enabled, texters will see a message telling them that sending of initial messages is paused, but they will still be able to reply to any incoming responses. | | DOWNTIME_TEXTER | Setting DOWNTIME_TEXTER to a text message (without quotes, please) will give the message as a text to texters when they arrive on the site, but the admin pages will still be accessible. This could be useful if you want to stop new texters from landing on the site and texting, while you debug things. | | DST_REFERENCE_TIMEZONE | Timezone to use to determine whether DST is in effect. If it's DST in this timezone, we assume it's DST everywhere. _Default_: "US/Eastern". (The default will work for any campaign in the US. For example, if the campaign is in Australia, use "Australia/Sydney" or some other timezone in Australia. Note that DST is opposite in the northern and souther hemispheres.) | | DYNAMICASSIGNMENT_BATCHES | Enables texter strategies for campaigns. Enabled by default are "finished-replies-tz", "vetted-texters", and "finished-replies". Learn more at [HOWTO-use-dynamicassignment-batches.md](https://github.com/StateVoicesNational/Spoke/blob/e217a971f0e1eed6f96d1494aee0f62ce715a771/docs/HOWTO-use-dynamicassignment-batches.md#dynamic-assignment-strategies). NOTE: "vetted-takeconversations" is experimental and does not work on its own, needing other three default strategies enabled. diff --git a/docs/RELEASE_NOTES.md b/docs/RELEASE_NOTES.md index 9eb7dab96..7a532c35e 100644 --- a/docs/RELEASE_NOTES.md +++ b/docs/RELEASE_NOTES.md @@ -1,5 +1,27 @@ # Release Notes +## 14.1.2 + +_October 2024_: Version 14.1.2 + +14.1.2 is a patch release. + +### Bug Fixes + +- [#2488](https://github.com/StateVoicesNational/Spoke/pull/2488) - Fix Redis and readonly DB certificate issues - @jeffm2001 +- [#2490](https://github.com/StateVoicesNational/Spoke/pull/2490) - Fix Bandwidth sending - @jeffm2001 +- [#2491](https://github.com/StateVoicesNational/Spoke/pull/2491) - Avoid error on opt-out - @jeffm2001 +- [#2493](https://github.com/StateVoicesNational/Spoke/pull/2493) - Fix broken docker image build - @engelhartrueben +- [#2442](https://github.com/StateVoicesNational/Spoke/pull/2442) - Add instructions for local postgres - @sjwmoveon +- [#2478](https://github.com/StateVoicesNational/Spoke/pull/2478) - Allow pausing of initial messages - @jeffm2001 +- [#2494](https://github.com/StateVoicesNational/Spoke/pull/2494) - Heroku Plan Update - @engelhartrueben +- [#2498](https://github.com/StateVoicesNational/Spoke/pull/2498) - Remove unused variables causing /phone-numbers blank screen error for Admins - @mau11 +- [#2492](https://github.com/StateVoicesNational/Spoke/pull/2492) - Fix UserInputError GraphQL errors - @jeffm2001 + +### Appreciations + +[Jeff Mann](https://github.com/jeffm2001), [Maureen Zitouni](https://github.com/mau11), [Ruby Engelhart](https://github.com/engelhartrueben), [Sophie Waldman](https://github.com/sjwmoveon) + ## 14.1.1 _October 2024_: Version 14.1.1 diff --git a/package.json b/package.json index 7f02e9854..dab065520 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "spoke", - "version": "14.1.1", + "version": "14.1.2", "description": "Spoke", "main": "src/server", "engines": { @@ -119,6 +119,7 @@ "bandwidth-sdk": "^1.0.2", "body-parser": "^1.15.2", "browserify": "^17.0.0", + "buffer": "^6.0.3", "color-difference": "^0.3.4", "cookie-session": "^2.1.0", "dataloader": "^2.2.2", diff --git a/src/components/AssignmentTexter/Controls.jsx b/src/components/AssignmentTexter/Controls.jsx index 3374c3884..dec3d6031 100644 --- a/src/components/AssignmentTexter/Controls.jsx +++ b/src/components/AssignmentTexter/Controls.jsx @@ -1173,6 +1173,12 @@ export class AssignmentTexterContactControls extends React.Component { renderFirstMessage(enabledSideboxes) { const { contact } = this.props; + if (window.DOWNTIME_NO_INITIAL) { + return [ + this.renderToolbar(enabledSideboxes), +
Sending initial messages is currently paused. You can still reply to any incoming messages.
+ ]; + } return [ this.renderToolbar(enabledSideboxes), { + onChange={event => { + const errorCode = event.target.value; this.setState({ errorCode }); }} onKeyPress={evt => { diff --git a/src/containers/AdminIncomingMessageList.jsx b/src/containers/AdminIncomingMessageList.jsx index 0732c5eef..d2a7351a1 100644 --- a/src/containers/AdminIncomingMessageList.jsx +++ b/src/containers/AdminIncomingMessageList.jsx @@ -185,7 +185,7 @@ export class AdminIncomingMessageList extends Component { handleErrorCodeChange = async errorCode => { const contactsFilter = { ...this.state.contactsFilter, - errorCode: errorCode ? errorCode.split(",") : null + errorCode: errorCode ? errorCode.split(",").map(Number) : null }; await this.setState({ contactsFilter, @@ -234,7 +234,7 @@ export class AdminIncomingMessageList extends Component { handleReassignAllMatchingRequested = async newTexterUserId => { await this.props.mutations.bulkReassignCampaignContacts( this.props.params.organizationId, - newTexterUserId, + newTexterUserId.toString(), this.state.campaignsFilter || {}, this.state.assignmentsFilter || {}, this.state.contactsFilter || {}, diff --git a/src/containers/AdminPhoneNumberInventory.js b/src/containers/AdminPhoneNumberInventory.js index d23bb6cd4..350f87946 100644 --- a/src/containers/AdminPhoneNumberInventory.js +++ b/src/containers/AdminPhoneNumberInventory.js @@ -48,6 +48,9 @@ const inlineStyles = { cancelButton: { marginTop: 15, marginRight: 5 + }, + deleteButton: { + marginTop: 15 } }; @@ -263,9 +266,6 @@ class AdminPhoneNumberInventory extends React.Component { } renderBuyNumbersForm() { - const service = this.props.data.organization.serviceVendor; - const serviceName = service.name; - const serviceConfig = service.config || "{}"; return (