From d9b0bcdcbffca316ec26f4e1035a16e6d2c2376a Mon Sep 17 00:00:00 2001 From: bodymindarts Date: Wed, 25 Oct 2023 16:18:09 +0200 Subject: [PATCH] chore: run consent test in tilt --- .env | 120 ------------------ .github/workflows/tilt.yml | 2 +- apps/consent/BUCK | 17 +++ apps/consent/cypress.config.ts | 8 +- apps/consent/cypress/support/commands.ts | 2 +- apps/consent/env.ts | 4 +- dev/.env | 0 dev/Tiltfile | 80 ++++++++++-- dev/bin/init-onchain.sh | 4 +- dev/bin/init-user.sh | 16 +++ dev/bin/setup-hydra-client.sh | 34 +++++ dev/config/ory/hydra.yml | 8 +- dev/docker-compose.deps.yml | 2 + dev/helpers/auth.sh | 15 +++ dev/{bin/helpers.sh => helpers/cli.sh} | 11 ++ dev/helpers/gql.sh | 58 +++++++++ .../gql/user-email-registration-initiate.gql | 15 +++ .../gql/user-email-registration-validate.gql | 14 ++ toolchains/workspace-pnpm/macros.bzl | 56 ++++++++ 19 files changed, 321 insertions(+), 145 deletions(-) delete mode 100644 .env delete mode 100644 dev/.env create mode 100755 dev/bin/init-user.sh create mode 100755 dev/bin/setup-hydra-client.sh create mode 100644 dev/helpers/auth.sh rename dev/{bin/helpers.sh => helpers/cli.sh} (59%) mode change 100644 => 100755 create mode 100644 dev/helpers/gql.sh create mode 100644 dev/helpers/gql/user-email-registration-initiate.gql create mode 100644 dev/helpers/gql/user-email-registration-validate.gql diff --git a/.env b/.env deleted file mode 100644 index 8d2ed9f1442..00000000000 --- a/.env +++ /dev/null @@ -1,120 +0,0 @@ -export DOCKER_HOST_IP=${DOCKER_HOST_IP:-127.0.0.1} -export NETWORK=regtest - -# dev/lnd/tls.cert.base64 -export LND1_TLS="LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNZVENDQWdlZ0F3SUJBZ0lSQU9zZzdYWFR4cnVZYlhkeTY2d3RuN1F3Q2dZSUtvWkl6ajBFQXdJd09ERWYKTUIwR0ExVUVDaE1XYkc1a0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1PRFl4T1RneApNak5tT0Roak1CNFhEVEl6TURFeE9USXdOREUxTTFvWERUTTBNRGN5TVRJd05ERTFNMW93T0RFZk1CMEdBMVVFCkNoTVdiRzVrSUdGMWRHOW5aVzVsY21GMFpXUWdZMlZ5ZERFVk1CTUdBMVVFQXhNTU9EWXhPVGd4TWpObU9EaGoKTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFM1lieUlKWU1Vcm8zZkl0UFFucysxZ2lpTXI5NQpJUXRmclFDQ2JhOWVtcjI4TENmbk1vYy9VQVFwUlg3QVlvVFRneUdiMFBuZGNUODF5ZVgvYTlPa0RLT0I4VENCCjdqQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0V3WURWUjBsQkF3d0NnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC8KQkFVd0F3RUIvekFkQmdOVkhRNEVGZ1FVL1AxRHpJUkRzTEhHMU10d3NrZE5nZ0lub1Mwd2daWUdBMVVkRVFTQgpqakNCaTRJTU9EWXhPVGd4TWpObU9EaGpnZ2xzYjJOaGJHaHZjM1NDRFd4dVpDMXZkWFJ6YVdSbExUR0NEV3h1ClpDMXZkWFJ6YVdSbExUS0NEV3h1WkMxdmRYUnphV1JsTFRPQ0JHeHVaREdDQkd4dVpES0NCSFZ1YVhpQ0NuVnUKYVhod1lXTnJaWFNDQjJKMVptTnZibTZIQkg4QUFBR0hFQUFBQUFBQUFBQUFBQUFBQUFBQUFBR0hCS3dUQUJBdwpDZ1lJS29aSXpqMEVBd0lEU0FBd1JRSWhBSU5DNlJWQ3d6SzFYRnFxeVNLY0Y4QzQ5ZFlSOThjemdLNVdkcmNOCkxYYWlBaUJHYmtWeGhaeHdDaDVLQ1o1Z2M1Q2FsQ0RvaGNxVkdiaHNya0hHTFhpdHN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" -export LND2_TLS=$LND1_TLS - -export TLSOUTSIDE1=$LND1_TLS -export TLSOUTSIDE2=$LND1_TLS - -# dev/lnd/regtest/lnd1.admin.macaroon.base64 -export LND1_MACAROON="AgEDbG5kAvgBAwoQB1FdhGa9xoewc1LEXmnURRIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgqHDdwGCqx0aQL1/Z3uUfzCpeBhfapGf9s/AZPOVwf6s=" -# dev/lnd/regtest/lnd2.admin.macaroon.base64 -export LND2_MACAROON="AgEDbG5kAvgBAwoQX0BxfhQTxLTiqaceBnGnfBIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgMAKlr1HehfBpn2R5RPE2IuY9r/18QBeLZxYgRidpos4=" - -# dev/lnd/regtest/lnd-outside-1.admin.macaroon.base64 -export MACAROONOUTSIDE1="AgEDbG5kAvgBAwoQeE+5exgz7/0ExCn7H6AJlBIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgL7pU+cKOt6zGyWTdWWmAJLP1L3cnbOPb4Rd3QtniyyM=" -# -# dev/lnd/regtest/lnd-outside-2.admin.macaroon.base64 -export MACAROONOUTSIDE2="AgEDbG5kAvgBAwoQfKO82/iPT2zIwWYPrOXvABIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYg2XkV+4Z4inbfXGZivRoY+r7KHNZhgxkCEdKByxbeb/Q=" - -# dev/lnd/loop/regtest/loopd1-1.loop.macaroon.base64 -export LND1_LOOP_MACAROON="AgEEbG9vcAJ3AwoQRGymK6/vfF3wwuVmaTj3RhIBMBoMCgRhdXRoEgRyZWFkGg8KBGxvb3ASAmluEgNvdXQaGgoLc3VnZ2VzdGlvbnMSBHJlYWQSBXdyaXRlGhUKBHN3YXASB2V4ZWN1dGUSBHJlYWQaDQoFdGVybXMSBHJlYWQAAAYgAFS/qTZItZ3ZKksQkfXAKFnsb0JS5Ok3Oi5fAgCaE/k=" -# dev/lnd/loop/regtest/loopd2-1.loop.macaroon.base64 -export LND2_LOOP_MACAROON="AgEEbG9vcAJ3AwoQ6Ntr7+DpuicdMgmVPKvDVxIBMBoMCgRhdXRoEgRyZWFkGg8KBGxvb3ASAmluEgNvdXQaGgoLc3VnZ2VzdGlvbnMSBHJlYWQSBXdyaXRlGhUKBHN3YXASB2V4ZWN1dGUSBHJlYWQaDQoFdGVybXMSBHJlYWQAAAYgU6bTJC50AuYehDtb9U2s4EuH7C2Tf8eAppPPOFeUXds=" - -# dev/lnd/loop/regtest/loopd1-1.tls.cert.base64 -export LND1_LOOP_TLS="LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNKakNDQWMyZ0F3SUJBZ0lSQU1memVXM0J0UWJaaTdxSjZoQk5vMHN3Q2dZSUtvWkl6ajBFQXdJd09URWcKTUI0R0ExVUVDaE1YYkc5dmNDQmhkWFJ2WjJWdVpYSmhkR1ZrSUdObGNuUXhGVEFUQmdOVkJBTVREREpqWkdRMQpOMlptWlRZeFpEQWVGdzB5TWpBNU1EY3lNVE15TWpSYUZ3MHlNekV4TURJeU1UTXlNalJhTURreElEQWVCZ05WCkJBb1RGMnh2YjNBZ1lYVjBiMmRsYm1WeVlYUmxaQ0JqWlhKME1SVXdFd1lEVlFRREV3d3lZMlJrTlRkbVptVTIKTVdRd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFUcU5qcVFMUGNHSURaSmtHenNlL3d2ZWt0TwpRVlhpaFJ6WmVLay9ZMFlTNDFkejB2TjlQdktaM0ZxTmN2eEN5a1cvZ1dKNWhBdEpCZTdDaTZhWitnR0tvNEcxCk1JR3lNQTRHQTFVZER3RUIvd1FFQXdJQ3BEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBVEFQQmdOVkhSTUIKQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJRZHJscHQzM2lLdlZUZWQyVnV4Y25uQVJMeTlEQmJCZ05WSFJFRQpWREJTZ2d3eVkyUmtOVGRtWm1VMk1XU0NDV3h2WTJGc2FHOXpkSUlFZFc1cGVJSUtkVzVwZUhCaFkydGxkSUlIClluVm1ZMjl1Ym9jRWZ3QUFBWWNRQUFBQUFBQUFBQUFBQUFBQUFBQUFBWWNFckJzQUR6QUtCZ2dxaGtqT1BRUUQKQWdOSEFEQkVBaUJYaFI2VmRzSFYrREhhWGRrV2VRZ0pzMlRxT0pXajBwUXI1ZHFLcFViNjlBSWdTeGtYYTZFRQpWVk9CZ0VhNXR5Z3NBcGM2bDBSak5nVGF2SkF6T2dWT2tIWT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" -# dev/lnd/loop/regtest/loopd2-1.tls.cert.base64 -export LND2_LOOP_TLS="LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNKakNDQWN5Z0F3SUJBZ0lRVjd2dFlUbzJYS1NybWt6N3d0SjNjVEFLQmdncWhrak9QUVFEQWpBNU1TQXcKSGdZRFZRUUtFeGRzYjI5d0lHRjFkRzluWlc1bGNtRjBaV1FnWTJWeWRERVZNQk1HQTFVRUF4TU1aVEZpTkRobQpZbVUwTmpZek1CNFhEVEl5TURrd056SXhNekl5TlZvWERUSXpNVEV3TWpJeE16SXlOVm93T1RFZ01CNEdBMVVFCkNoTVhiRzl2Y0NCaGRYUnZaMlZ1WlhKaGRHVmtJR05sY25ReEZUQVRCZ05WQkFNVERHVXhZalE0Wm1KbE5EWTIKTXpCWk1CTUdCeXFHU000OUFnRUdDQ3FHU000OUF3RUhBMElBQkVYbzlndHpkUnFMTWFhdjJ1VDA4eHlTUUpTKwpoMFNMcUMrdnpzR0RhZ2owOXg3UW9ud3oralo0eHppeklsdWVOY0JlWDYzd3VGZ0dwOTlBMW9mMDQyU2pnYlV3CmdiSXdEZ1lEVlIwUEFRSC9CQVFEQWdLa01CTUdBMVVkSlFRTU1Bb0dDQ3NHQVFVRkJ3TUJNQThHQTFVZEV3RUIKL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkZOM2E3WkY5Y2FSUGJnNDJXYitOYnVYM2hTYU1Gc0dBMVVkRVFSVQpNRktDREdVeFlqUTRabUpsTkRZMk00SUpiRzlqWVd4b2IzTjBnZ1IxYm1sNGdncDFibWw0Y0dGamEyVjBnZ2RpCmRXWmpiMjV1aHdSL0FBQUJoeEFBQUFBQUFBQUFBQUFBQUFBQUFBQUJod1NzR3dBUU1Bb0dDQ3FHU000OUJBTUMKQTBnQU1FVUNJUURUcUpnVitReks2N3lSN1lGcWtyQkN6aEQ2OExZcjBBM1JMWFF1ckM2d21BSWdZNGdESjA1eQpRTjJCY2YvaEl6VHJwb1ZlK3Y0blBRREg3bXBFQXRyOE96MD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" - -# dev/lnd/regtest/lnd1.pubkey -export LND1_PUBKEY="03ca1907342d5d37744cb7038375e1867c24a87564c293157c95b2a9d38dcfb4c2" -# dev/lnd/regtest/lnd2.pubkey -export LND2_PUBKEY="039341ef13e776dc1611502cf510110d9ac5cdc252141f5997adcfd72cef34c3a7" - -export BITCOINDPORT=18443 - -export BITCOINDADDR=${DOCKER_HOST_IP} -export BITCOIND_SIGNER_PORT=18543 -export BITCOIND_SIGNER_ADDR=${DOCKER_HOST_IP} -export BITCOINDRPCPASS=rpcpassword - -export LND1_DNS=${DOCKER_HOST_IP} -export LND2_DNS=${DOCKER_HOST_IP} -export LNDOUTSIDE1ADDR=${DOCKER_HOST_IP} -export LNDOUTSIDE2ADDR=${DOCKER_HOST_IP} - -export LND1_RPCPORT=10009 -export LND2_RPCPORT=10010 - -export LNDOUTSIDE1RPCPORT=10012 -export LNDOUTSIDE2RPCPORT=10013 - -export LND1_TYPE=offchain,onchain -export LND2_TYPE=offchain - -export LND1_NAME=lnd1 -export LND2_NAME=lnd2 - -export MONGODB_CON=mongodb://${DOCKER_HOST_IP}:27017/galoy - -export REDIS_0_DNS=${DOCKER_HOST_IP} -export REDIS_0_PORT=6379 -export REDIS_MASTER_NAME="mymaster" -export REDIS_PASSWORD="" -export REDIS_TYPE="standalone" - -export BRIA_HOST=${DOCKER_HOST_IP} -export BRIA_PORT=2742 -export BRIA_API_KEY="bria_dev_000000000000000000000" - -export PRICE_HOST=${DOCKER_HOST_IP} -export PRICE_PORT=50051 - -export PRICE_HISTORY_HOST=${DOCKER_HOST_IP} -export PRICE_HISTORY_PORT=50052 - -export OATHKEEPER_DECISION_ENDPOINT=http://${DOCKER_HOST_IP}:4456 - -export WEBSOCKET_PORT=4000 - -export GEETEST_ID="geetest_id" -export GEETEST_KEY="geetest_key" - -export TWILIO_ACCOUNT_SID="AC_twilio_id" -export TWILIO_AUTH_TOKEN="AC_twilio_auth_token" -export TWILIO_VERIFY_SERVICE_ID="VA_twilio_service" - -export COMMITHASH="hash" -export HELMREVISION="1" - -export LOG_LEVEL="info" - -export KRATOS_MASTER_USER_PASSWORD="passwordHardtoFindWithNumber123" -export KRATOS_CALLBACK_API_KEY="The-Value-of-My-Key" -export KRATOS_PG_HOST="localhost" -export KRATOS_PG_PORT="5433" - -export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318" -# TODO: rename to OTEL_SERVICE_NAME -# https://opentelemetry.io/docs/concepts/sdk-configuration/general-sdk-configuration/#otel_service_name -export TRACING_SERVICE_NAME="galoy-dev" - -export MATTERMOST_WEBHOOK_URL="https://chat.galoy.io/hooks/sometoken" - -export KRATOS_PG_CON="postgres://dbuser:secret@localhost:5433/default?sslmode=disable" - -export UNSECURE_DEFAULT_LOGIN_CODE="000000" -export UNSECURE_IP_FROM_REQUEST_OBJECT=true - -export SVIX_SECRET="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2OTE2NzIwMTQsImV4cCI6MjAwNzAzMjAxNCwibmJmIjoxNjkxNjcyMDE0LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.b9s0aWSisNdUNki4edabBEToLNSwjC9-AiJQr4J3y4E" -export SVIX_ENDPOINT="http://localhost:8071" -export SVIX_CALLBACK_URL=http://bats-tests:8080/webhook/ - -export KRATOS_PUBLIC_API="http://localhost:4433" -export KRATOS_ADMIN_API="http://localhost:4434" - -export HYDRA_PUBLIC_API="http://localhost:4444" -export HYDRA_ADMIN_API="http://localhost:4445" diff --git a/.github/workflows/tilt.yml b/.github/workflows/tilt.yml index 4f23f5d6e53..42cc32a3425 100644 --- a/.github/workflows/tilt.yml +++ b/.github/workflows/tilt.yml @@ -11,4 +11,4 @@ jobs: with: github_access_token: ${{ secrets.GITHUB_TOKEN }} - name: Tilt CI - run: nix develop -c bash -c "cd dev && tilt ci" + run: nix develop -c bash -c "cd dev && tilt ci -- -test consent | tee tilt.log | grep test" diff --git a/apps/consent/BUCK b/apps/consent/BUCK index 8f621dfe4fc..2dd0dd0702d 100644 --- a/apps/consent/BUCK +++ b/apps/consent/BUCK @@ -1,10 +1,27 @@ load("@toolchains//workspace-pnpm:macros.bzl", +"dev_pnpm_task_binary", +"dev_pnpm_task_test", "build_node_modules", "next_build", "next_build_bin", "eslint" ) +dev_pnpm_task_binary( + name = "dev", + command = "dev", +) + +dev_pnpm_task_binary( + name = "open-cypress", + command = "cypress:open", +) + +dev_pnpm_task_test( + name = "cypress", + command = "cypress:run", +) + export_file( name = "package.json", visibility = ["PUBLIC"], diff --git a/apps/consent/cypress.config.ts b/apps/consent/cypress.config.ts index 4452ebab6bb..9143d8168f1 100644 --- a/apps/consent/cypress.config.ts +++ b/apps/consent/cypress.config.ts @@ -1,16 +1,14 @@ import { defineConfig } from "cypress" import dotenv from "dotenv" -dotenv.config() -dotenv.config({ path: ".env.test" }) +dotenv.config({ path: "../../dev/.envs/consent.env" }) export default defineConfig({ e2e: { - baseUrl: "http://127.0.0.1:3000", - // setupNodeEvents(on, config) {}, + baseUrl: "http://localhost:3000", }, defaultCommandTimeout: 60000, env: { - ...process.env, + AUTHORIZATION_URL: process.env.AUTHORIZATION_URL, }, component: { devServer: { diff --git a/apps/consent/cypress/support/commands.ts b/apps/consent/cypress/support/commands.ts index 16e0c35dbcd..3bacca45f26 100644 --- a/apps/consent/cypress/support/commands.ts +++ b/apps/consent/cypress/support/commands.ts @@ -46,7 +46,7 @@ declare namespace Cypress { } Cypress.Commands.add("getOTP", (email) => { - const query = `docker exec -i api-kratos-pg-1 psql -U dbuser -d default -t -c "SELECT body FROM courier_messages WHERE recipient='${email}' ORDER BY created_at DESC LIMIT 1;"` + const query = `docker exec -i galoy-dev-kratos-pg-1 psql -U dbuser -d default -t -c "SELECT body FROM courier_messages WHERE recipient='${email}' ORDER BY created_at DESC LIMIT 1;"` cy.exec(query).then((result) => { const rawMessage = result.stdout const otpMatch = rawMessage.match(/(\d{6})/) diff --git a/apps/consent/env.ts b/apps/consent/env.ts index 9804b44cdf1..becafbc31c3 100644 --- a/apps/consent/env.ts +++ b/apps/consent/env.ts @@ -4,10 +4,10 @@ import { z } from "zod" export const env = createEnv({ server: { HYDRA_ADMIN_URL: z.string().default("http://localhost:4445"), - CORE_AUTH_URL: z.string().default("http://localhost:4002/auth"), + CORE_AUTH_URL: z.string().default("http://localhost:4455/auth"), }, shared: { - GRAPHQL_ENDPOINT: z.string().default("http://localhost:4002/graphql"), + GRAPHQL_ENDPOINT: z.string().default("http://localhost:4455/graphql"), }, runtimeEnv: { CORE_AUTH_URL: process.env.CORE_AUTH_URL, diff --git a/dev/.env b/dev/.env deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/dev/Tiltfile b/dev/Tiltfile index f183af24306..f03f9b37656 100644 --- a/dev/Tiltfile +++ b/dev/Tiltfile @@ -1,3 +1,8 @@ +is_ci=sys.argv[1] == "ci" + +config.define_string_list("test") +cfg = config.parse() + groups = { "auth": [ "oathkeeper", @@ -25,6 +30,57 @@ groups = { ], } +consent_test_target = "//apps/consent:cypress" +local_resource( + "consent-test", + labels = ["test"], + auto_init = is_ci and "consent" in cfg.get("test", []), + cmd = "buck2 test {}".format(consent_test_target), + resource_deps = [ + "consent", + "init-test-user", + "hydra-consent" + ], +) + +local_resource( + name='init-test-user', + labels = ['test'], + cmd='bin/init-user.sh', + resource_deps = [ + "oathkeeper", + "kratos", + "api", + ] +) + +consent_target = "//apps/consent:dev" +if is_ci: + consent_target = '//apps/consent:consent' +local_resource( + "consent", + labels = ["auth"], + cmd = "buck2 build {}".format(consent_target), + serve_cmd = "buck2 run {}".format(consent_target), + resource_deps = [ + "apollo-router", + "hydra", + "api", + ], + links = [ + link("http://localhost:3000", "consent"), + ], +) + +local_resource( + name='hydra-consent', + labels = ['auth'], + cmd=['bin/setup-hydra-client.sh', 'consent', 'http://localhost:3000'], + resource_deps = [ + "hydra", + ] +) + api_target = "//core/api:api" local_resource( "api", @@ -51,6 +107,10 @@ local_resource( "REDIS_0_DNS": "localhost", "REDIS_0_PORT": "6379", "REDIS_TYPE": "standalone", + "UNSECURE_IP_FROM_REQUEST_OBJECT": "true", + "UNSECURE_DEFAULT_LOGIN_CODE": "000000", + "GEETEST_ID": "geetest_id", + "GEETEST_KEY": "geetest_key" }, allow_parallel = True, readiness_probe = probe( @@ -66,6 +126,16 @@ local_resource( ] ) +local_resource( + name='init-onchain', + labels = ['bitcoin'], + cmd='bin/init-onchain.sh', + resource_deps = [ + "bitcoind", + "bria", + ] +) + docker_compose("./docker-compose.deps.yml", project_name = "galoy-dev") for service in groups["bitcoin"]: @@ -76,13 +146,3 @@ for service in groups["core"]: dc_resource(service, labels = ["core"]) for service in groups["auth"]: dc_resource(service, labels = ["auth"]) - -local_resource( - name='init-onchain', - labels = ['bitcoin'], - cmd='bin/init-onchain.sh', - resource_deps = [ - "bitcoind", - "bria", - ] -) diff --git a/dev/bin/init-onchain.sh b/dev/bin/init-onchain.sh index cfe1d99d677..c10cd6eee6d 100755 --- a/dev/bin/init-onchain.sh +++ b/dev/bin/init-onchain.sh @@ -2,8 +2,8 @@ set -e -DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" -source "${DIR}/helpers.sh" +DEV_DIR="$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")" +source "${DEV_DIR}/helpers/cli.sh" echo "Seeding some regtest blocks..." diff --git a/dev/bin/init-user.sh b/dev/bin/init-user.sh new file mode 100755 index 00000000000..56e1a484c35 --- /dev/null +++ b/dev/bin/init-user.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +set -x + +DEV_DIR="$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")" +source "${DEV_DIR}/helpers/auth.sh" +source "${DEV_DIR}/helpers/gql.sh" + +user_phone="+16505554350" +email="test@galoy.com" + +auth_token="$(login_user "${user_phone}")" + +register_email_to_user "${auth_token}" "${email}" diff --git a/dev/bin/setup-hydra-client.sh b/dev/bin/setup-hydra-client.sh new file mode 100755 index 00000000000..6113c9109a0 --- /dev/null +++ b/dev/bin/setup-hydra-client.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +set -e + +DEV_DIR="$(dirname "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")")" +source "${DEV_DIR}/helpers/cli.sh" + +hydra_client_name="${1}" +redirect_uri="${2}" + +HYDRA_CLIENT_JSON="${DEV_DIR}/../.${hydra_client_name}-hydra-client.json" +HYDRA_CLIENT_ENV="${DEV_DIR}/../.${hydra_client_name}-hydra-client.env" +HYDRA_ADMIN_API="http://localhost:4445" +HYDRA_PUBLIC_API="http://localhost:4444" + +hydra_cli create client \ + --endpoint "${HYDRA_ADMIN_API}" \ + --grant-type authorization_code,refresh_token \ + --response-type code,id_token \ + --format json \ + --scope offline --scope transactions:read --scope payments:send \ + --redirect-uri "$redirect_uri" > "${HYDRA_CLIENT_JSON}" + +CLIENT_ID=$(jq -r '.client_id' < "${HYDRA_CLIENT_JSON}") +CLIENT_SECRET=$(jq -r '.client_secret' < "${HYDRA_CLIENT_JSON}") + +AUTHORIZATION_URL="${HYDRA_PUBLIC_API}/oauth2/auth?client_id=$CLIENT_ID&scope=offline%20transactions:read&response_type=code&redirect_uri=$redirect_uri&state=kfISr3GhH0rqheByU6A6hqIG_f14pCGkZLSCUTHnvlI" + +echo "export CLIENT_ID=$CLIENT_ID" > "${HYDRA_CLIENT_ENV}" +echo "export CLIENT_SECRET=$CLIENT_SECRET" >> "${HYDRA_CLIENT_ENV}" +echo "export AUTHORIZATION_URL=$AUTHORIZATION_URL" >> "${HYDRA_CLIENT_ENV}" + +mkdir -p "${DEV_DIR}/.envs" +cp "${HYDRA_CLIENT_ENV}" "${DEV_DIR}/.envs/${hydra_client_name}.env" diff --git a/dev/config/ory/hydra.yml b/dev/config/ory/hydra.yml index 8d69cc1d243..eeb3592a3b7 100644 --- a/dev/config/ory/hydra.yml +++ b/dev/config/ory/hydra.yml @@ -4,10 +4,10 @@ serve: urls: self: - issuer: http://127.0.0.1:4444 - consent: http://127.0.0.1:3000/consent - login: http://127.0.0.1:3000/login - logout: http://127.0.0.1:3000/logout + issuer: http://localhost:4444 + consent: http://localhost:3000/consent + login: http://localhost:3000/login + logout: http://localhost:3000/logout secrets: system: diff --git a/dev/docker-compose.deps.yml b/dev/docker-compose.deps.yml index d84da84e1bf..59719e90214 100644 --- a/dev/docker-compose.deps.yml +++ b/dev/docker-compose.deps.yml @@ -72,6 +72,8 @@ services: image: ghcr.io/apollographql/router:v1.25.0 ports: - 4004:4004 + extra_hosts: + - "bats-tests:host-gateway" environment: - APOLLO_ROUTER_SUPERGRAPH_PATH=/repo/dev/apollo-federation/supergraph.graphql - APOLLO_ROUTER_CONFIG_PATH=/repo/dev/apollo-federation/router.yaml diff --git a/dev/helpers/auth.sh b/dev/helpers/auth.sh new file mode 100644 index 00000000000..f2e78b4c484 --- /dev/null +++ b/dev/helpers/auth.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +AUTH_ENDPOINT="http://localhost:4455/auth/phone/login" + +login_user() { + phone="$1" + + login_response=$(curl \ + -s \ + -X POST $AUTH_ENDPOINT \ + -H "Content-Type: application/json" \ + -d '{"phone": "'$phone'", "code":"000000"}') + + echo "$login_response" | jq -r '.authToken' +} diff --git a/dev/bin/helpers.sh b/dev/helpers/cli.sh old mode 100644 new mode 100755 similarity index 59% rename from dev/bin/helpers.sh rename to dev/helpers/cli.sh index f5d069497d8..62b0746ad9d --- a/dev/bin/helpers.sh +++ b/dev/helpers/cli.sh @@ -13,3 +13,14 @@ bitcoin_signer_cli() { bria_cli() { docker exec "${COMPOSE_PROJECT_NAME}-bria-1" bria "$@" } + +hydra_cli() { + docker exec "${COMPOSE_PROJECT_NAME}-hydra-1" hydra "$@" +} + +kratos_pg() { + DB_USER="dbuser" + DB_NAME="default" + + docker exec "${COMPOSE_PROJECT_NAME}-kratos-pg-1" psql -U $DB_USER -d $DB_NAME -t -c "$@" +} diff --git a/dev/helpers/gql.sh b/dev/helpers/gql.sh new file mode 100644 index 00000000000..9608f9522c9 --- /dev/null +++ b/dev/helpers/gql.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +GQL_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/gql" +HELPERS_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" +source "${HELPERS_DIR}/cli.sh" + +GALOY_ENDPOINT="http://localhost:4455/graphql" + +register_email_to_user() { + local token=$1 + local email=$2 + + variables="{\"input\": {\"email\": \"$email\"}}" + registration_id=$(exec_graphql $token 'user-email-registration-initiate' "${variables}" '.data.userEmailRegistrationInitiate.emailRegistrationId') + + email_code_response=$(kratos_pg "SELECT body FROM courier_messages WHERE recipient='$email' ORDER BY created_at DESC LIMIT 1;") + email_code=$(echo "$email_code_response" | grep -oP '\d{6}') + + variables="{\"input\": {\"code\": \"$email_code\", \"emailRegistrationId\": \"$registration_id\"}}" + exec_graphql $token 'user-email-registration-validate' "${variables}" +} + +gql_file() { + echo "${GQL_DIR}/$1.gql" +} + +gql_query() { + cat "$(gql_file $1)" | tr '\n' ' ' | sed 's/"/\\"/g' +} + +exec_graphql() { + local token=$1 + local query_name=$2 + local variables=${3:-"{}"} + local output=${4:-"."} + + if [[ ${token} == "anon" ]]; then + AUTH_HEADER="" + else + AUTH_HEADER="Authorization: Bearer ${token}" + fi + + curl -s \ + -X POST \ + ${AUTH_HEADER:+ -H "$AUTH_HEADER"} \ + -H "Content-Type: application/json" \ + -H "X-Idempotency-Key: $(random_uuid)" \ + -d "{\"query\": \"$(gql_query $query_name)\", \"variables\": $variables}" \ + "${GALOY_ENDPOINT}" | jq -r "${output}" +} + +random_uuid() { + if [[ -e /proc/sys/kernel/random/uuid ]]; then + cat /proc/sys/kernel/random/uuid + else + uuidgen + fi +} diff --git a/dev/helpers/gql/user-email-registration-initiate.gql b/dev/helpers/gql/user-email-registration-initiate.gql new file mode 100644 index 00000000000..e71d774a3d0 --- /dev/null +++ b/dev/helpers/gql/user-email-registration-initiate.gql @@ -0,0 +1,15 @@ +mutation userEmailRegistrationInitiate($input: UserEmailRegistrationInitiateInput!) { + userEmailRegistrationInitiate(input: $input) { + errors { + message + } + emailRegistrationId + me { + id + email { + address + verified + } + } + } +} diff --git a/dev/helpers/gql/user-email-registration-validate.gql b/dev/helpers/gql/user-email-registration-validate.gql new file mode 100644 index 00000000000..14fc670c2ff --- /dev/null +++ b/dev/helpers/gql/user-email-registration-validate.gql @@ -0,0 +1,14 @@ +mutation userEmailRegistrationValidate($input: UserEmailRegistrationValidateInput!) { + userEmailRegistrationValidate(input: $input) { + errors { + message + } + me { + id + email { + address + verified + } + } + } +} diff --git a/toolchains/workspace-pnpm/macros.bzl b/toolchains/workspace-pnpm/macros.bzl index 3e6bc37b835..ac553dd8b46 100644 --- a/toolchains/workspace-pnpm/macros.bzl +++ b/toolchains/workspace-pnpm/macros.bzl @@ -879,3 +879,59 @@ def madge_check( visibility = visibility, **kwargs, ) + +def pnpm_task_binary_impl(ctx: AnalysisContext) -> list[[DefaultInfo, RunInfo]]: + script = ctx.actions.write("pnpm-run.sh", """\ +#!/usr/bin/env bash +set -euo pipefail + +rootpath="$(git rev-parse --show-toplevel)" +install_node_modules="$1" +npm_package_path="$2" +npm_run_command="$3" + +cd "$rootpath/$npm_package_path" +if [ "$install_node_modules" = "True" ]; then + pnpm install +fi +pnpm run --report-summary "$npm_run_command" +""", is_executable = True) + args = cmd_args([script, str(ctx.attrs.local_node_modules), ctx.label.package, ctx.attrs.command]) + args.hidden([ctx.attrs.deps]) + args.hidden([ctx.attrs.srcs]) + return [DefaultInfo(), RunInfo(args = args)] + +dev_pnpm_task_binary = rule(impl = pnpm_task_binary_impl, attrs = { + "command": attrs.string(doc = """pnpm command to run"""), + "local_node_modules": attrs.bool(default = True, doc = """Need to run pnpm install first?"""), + "srcs": attrs.list(attrs.source(), default = [], doc = """List of sources we require"""), + "deps": attrs.list(attrs.source(), default = [], doc = """List of dependencies we require"""), +}) + +def pnpm_task_test_impl(ctx: AnalysisContext) -> list[[DefaultInfo, ExternalRunnerTestInfo]]: + script = ctx.actions.write("pnpm-run.sh", """\ +#!/usr/bin/env bash +set -euo pipefail + +rootpath="$(git rev-parse --show-toplevel)" +install_node_modules="$1" +npm_package_path="$2" +npm_run_command="$3" + +cd "$rootpath/$npm_package_path" +if [ "$install_node_modules" = "True" ]; then + pnpm install +fi +pnpm run --report-summary "$npm_run_command" +""", is_executable = True) + args = cmd_args([script, str(ctx.attrs.local_node_modules), ctx.label.package, ctx.attrs.command]) + args.hidden([ctx.attrs.deps]) + args.hidden([ctx.attrs.srcs]) + return [DefaultInfo(), ExternalRunnerTestInfo(type = "integration", command = [script, str(ctx.attrs.local_node_modules), ctx.label.package, ctx.attrs.command])] + +dev_pnpm_task_test = rule(impl = pnpm_task_test_impl, attrs = { + "command": attrs.string(default = "start", doc = """pnpm command to run"""), + "local_node_modules": attrs.bool(default = True, doc = """Need to run pnpm install first?"""), + "srcs": attrs.list(attrs.source(), default = [], doc = """List of sources we require"""), + "deps": attrs.list(attrs.source(), default = [], doc = """List of dependencies we require"""), +})