diff --git a/docker-compose-deps.yml b/docker-compose-deps.yml index 7a50adc0b..e9f8035a7 100644 --- a/docker-compose-deps.yml +++ b/docker-compose-deps.yml @@ -34,6 +34,7 @@ services: - '127.0.0.1:9001:9001' maildev: + restart: always image: maildev/maildev ports: - '127.0.0.1:1080:1080' diff --git a/packages/server/.env-example b/packages/server/.env-example index 00bc249dd..8132d0564 100644 --- a/packages/server/.env-example +++ b/packages/server/.env-example @@ -110,3 +110,5 @@ STRATEGY_LOCAL=true ############################################################ # FRONTEND_HOST=localhost # FRONTEND_PORT=8081 + +SPECKLE_AUTOMATE_URL="http://localhost:3030" diff --git a/packages/server/modules/auth/defaultApps.js b/packages/server/modules/auth/defaultApps.js index a2a49857e..40bf07bcf 100644 --- a/packages/server/modules/auth/defaultApps.js +++ b/packages/server/modules/auth/defaultApps.js @@ -8,6 +8,7 @@ const { getApp } = require('@/modules/auth/services/apps') const { Scopes: ScopesConst } = require('@/modules/core/helpers/mainConstants') const { difference } = require('lodash') const { moduleLogger } = require('@/logging/logging') +const { speckleAutomateUrl } = require('@/modules/shared/helpers/envHelper') let allScopes = [] @@ -21,6 +22,7 @@ module.exports = async () => { await registerOrUpdateApp({ ...SpeckleConnectorApp }) await registerOrUpdateApp({ ...SpeckleExcel }) await registerOrUpdateApp({ ...SpecklePowerBi }) + await registerOrUpdateApp({ ...SpeckleAutomate }) } async function registerOrUpdateApp(app) { @@ -197,3 +199,21 @@ const SpecklePowerBi = { ScopesConst.Users.Invite ] } + +const SpeckleAutomate = { + id: 'spklautoma', + secret: 'spklautoma', + name: 'Speckle Automate', + description: 'Our automation platform', + trustByDefault: true, + public: true, + redirectUrl: `${speckleAutomateUrl()}/authn/callback`, + scopes: [ + ScopesConst.Profile.Email, + ScopesConst.Profile.Read, + ScopesConst.Users.Read, + ScopesConst.Tokens.Write, + ScopesConst.Streams.Read, + ScopesConst.Streams.Write + ] +} diff --git a/packages/server/modules/auth/tests/apps.spec.js b/packages/server/modules/auth/tests/apps.spec.js index 1c3684874..3a63e5306 100644 --- a/packages/server/modules/auth/tests/apps.spec.js +++ b/packages/server/modules/auth/tests/apps.spec.js @@ -84,7 +84,7 @@ describe('Services @apps-services', () => { it('Should get all the public apps on this server', async () => { const apps = await getAllPublicApps() expect(apps).to.be.an('array') - expect(apps.length).to.equal(7) + expect(apps.length).to.equal(8) }) it('Should fail to register an app with no scopes', async () => { @@ -217,7 +217,15 @@ describe('Services @apps-services', () => { .catch((err) => expect(err.message).to.equal('Access code not found.')) }) - const defaultApps = ['spklwebapp', 'explorer', 'sdm', 'sca', 'spklexcel'] + const defaultApps = [ + 'spklwebapp', + 'explorer', + 'sdm', + 'sca', + 'spklexcel', + 'spklpwerbi', + 'spklautoma' + ] defaultApps.forEach((speckleAppId) => { it(`Should not invalidate tokens, refresh tokens and access codes for default app: ${speckleAppId}, if updated`, async () => { const [unusedAccessCode, usedAccessCode] = await Promise.all([ diff --git a/packages/server/modules/auth/tests/appsGrapql.spec.js b/packages/server/modules/auth/tests/appsGrapql.spec.js index 75d93dd04..b88de762d 100644 --- a/packages/server/modules/auth/tests/appsGrapql.spec.js +++ b/packages/server/modules/auth/tests/appsGrapql.spec.js @@ -132,7 +132,7 @@ describe('GraphQL @apps-api', () => { expect(res).to.be.json expect(res.body.errors).to.not.exist expect(res.body.data.apps).to.be.an('array') - expect(res.body.data.apps.length).to.equal(7) + expect(res.body.data.apps.length).to.equal(8) }) it('Should get app info without secret if not authenticated and owner', async () => { diff --git a/packages/server/modules/shared/helpers/envHelper.ts b/packages/server/modules/shared/helpers/envHelper.ts index e0007da1a..8efe78ee1 100644 --- a/packages/server/modules/shared/helpers/envHelper.ts +++ b/packages/server/modules/shared/helpers/envHelper.ts @@ -108,3 +108,9 @@ export function enableMixpanel() { // if not explicitly set to '0' or 'false', it is enabled by default return !['0', 'false'].includes(process.env.ENABLE_MP || 'true') } + +export function speckleAutomateUrl() { + const automateUrl = + process.env.SPECKLE_AUTOMATE_URL || 'https://automate.speckle.systems' + return automateUrl +} diff --git a/utils/helm/speckle-server/templates/server/deployment.yml b/utils/helm/speckle-server/templates/server/deployment.yml index 98451e5ea..2d611f379 100644 --- a/utils/helm/speckle-server/templates/server/deployment.yml +++ b/utils/helm/speckle-server/templates/server/deployment.yml @@ -104,6 +104,9 @@ spec: - name: FILE_SIZE_LIMIT_MB value: {{ .Values.file_size_limit_mb | quote }} + - name: SPECKLE_AUTOMATE_URL + value: {{ .Values.server.speckleAutomateUrl }} + # *** Redis *** - name: REDIS_URL valueFrom: diff --git a/utils/helm/speckle-server/values.schema.json b/utils/helm/speckle-server/values.schema.json index 87e8a200c..7321f9575 100644 --- a/utils/helm/speckle-server/values.schema.json +++ b/utils/helm/speckle-server/values.schema.json @@ -441,6 +441,11 @@ "description": "The minimum level of logs which will be output. Suitable values are trace, debug, info, warn, error, fatal, or silent", "default": "info" }, + "speckleAutomateUrl": { + "type": "string", + "description": "The url where the associated Speckle Automate instance is running", + "default": "https://automate.speckle.systems" + }, "adminOverrideEnabled": { "type": "boolean", "description": "Enables the server side admin authz override", diff --git a/utils/helm/speckle-server/values.yaml b/utils/helm/speckle-server/values.yaml index cef232df4..bc8bc52ca 100644 --- a/utils/helm/speckle-server/values.yaml +++ b/utils/helm/speckle-server/values.yaml @@ -367,6 +367,8 @@ server: ## @param server.adminOverrideEnabled Enables the server side admin authz override adminOverrideEnabled: false + + speckleAutomateUrl: 'https://automate.speckle.systems' sessionSecret: ## @param server.sessionSecret.secretName The name of the Kubernetes Secret containing the Session secret. This is a unique value (can be generated randomly). This is expected to be provided within the Kubernetes cluster as an opaque Kubernetes Secret. Ref: https://kubernetes.io/docs/concepts/configuration/secret/#opaque-secrets ##