Merge branch 'main' into iain/auth-service-tidy-error-handling

This commit is contained in:
Iain Sproat
2025-05-13 14:47:58 +01:00
19 changed files with 48 additions and 56 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
import speckleTheme from '@speckle/tailwind-theme'
import { plugin as speckleTheme } from '@speckle/tailwind-theme'
import { tailwindContentEntries as themeEntries } from '@speckle/tailwind-theme/tailwind-configure'
import { tailwindContentEntries as uiLibEntries } from '@speckle/ui-components/tailwind-configure'
import formsPlugin from '@tailwindcss/forms'
@@ -69,10 +69,7 @@ import { ToastNotificationType, useGlobalToast } from '~~/lib/common/composables
import { ensureError } from '@speckle/shared'
import { useAuthManager } from '~~/lib/auth/composables/auth'
import { loginRoute } from '~~/lib/common/helpers/route'
import {
passwordRules,
doesNotContainBlockedDomain
} from '~~/lib/auth/helpers/validation'
import { passwordRules } from '~~/lib/auth/helpers/validation'
import { graphql } from '~~/lib/common/generated/gql'
import type { ServerTermsOfServicePrivacyPolicyFragmentFragment } from '~~/lib/common/generated/gql/graphql'
import { useMounted } from '@vueuse/core'
@@ -96,18 +93,13 @@ const router = useRouter()
const { signUpWithEmail, inviteToken } = useAuthManager()
const { triggerNotification } = useGlobalToast()
const isMounted = useMounted()
const isNoPersonalEmailsEnabled = useIsNoPersonalEmailsEnabled()
const newsletterConsent = defineModel<boolean>('newsletterConsent', { required: true })
const loading = ref(false)
const password = ref('')
const email = ref('')
const emailRules = computed(() =>
inviteToken.value || !isNoPersonalEmailsEnabled.value
? [isEmail]
: [isEmail, doesNotContainBlockedDomain]
)
const emailRules = [isEmail]
const nameRules = [isRequired]
const isEmailDisabled = computed(() => !!props.inviteEmail?.length || loading.value)
@@ -68,12 +68,4 @@ export const useIsBillingIntegrationEnabled = () => {
return ref(FF_BILLING_INTEGRATION_ENABLED)
}
export const useIsNoPersonalEmailsEnabled = () => {
const {
public: { FF_NO_PERSONAL_EMAILS_ENABLED }
} = useRuntimeConfig()
return ref(FF_NO_PERSONAL_EMAILS_ENABLED)
}
export { useGlobalToast, useActiveUser, usePageQueryStandardFetchPolicy }
@@ -1,5 +1,4 @@
import { isStringOfLength, stringContains } from '~~/lib/common/helpers/validation'
import { blockedDomains } from '@speckle/shared'
export const passwordLongEnough = isStringOfLength({ minLength: 8 })
export const passwordHasAtLeastOneNumber = stringContains({
@@ -21,10 +20,3 @@ export const passwordRules = [
passwordHasAtLeastOneLowercaseLetter,
passwordHasAtLeastOneUppercaseLetter
]
export const doesNotContainBlockedDomain = (val: string) => {
const domain = val.split('@')[1]?.toLowerCase()
return domain && blockedDomains.includes(domain)
? 'Please use your work email instead of a personal email address'
: true
}
@@ -107,8 +107,8 @@ export const useWorkspacePlan = (slug: string) => {
// Seat information
const seats = computed(() => result.value?.workspaceBySlug?.seats)
const hasAvailableEditorSeats = computed(() => {
if (seats.value?.editors.available && seats.value?.editors.assigned) {
return seats.value?.editors.available - seats.value?.editors.assigned > 0
if (seats.value?.editors.available) {
return seats.value.editors.available > 0
}
return false
})
@@ -6,6 +6,7 @@ import { UserRecord } from '@/modules/core/helpers/types'
import { MisconfiguredEnvironmentError } from '@/modules/shared/errors'
import { OnboardingCompletionInput } from '@/modules/core/graph/generated/graphql'
import { MailchimpResourceError } from '@/modules/auth/errors'
import { ensureError } from '@speckle/shared'
let mailchimpInitialized = false
@@ -76,11 +77,12 @@ export async function updateMailchimpMemberTags(
// Check if user is already in audience (meaning they consented to marketing emails)
try {
await mailchimp.lists.getListMember(listId, subscriberHash)
} catch {
} catch (e) {
throw new MailchimpResourceError(
'User not found in Mailchimp audience. They should have been added during registration.',
{
info: { userEmailHash: subscriberHash }
info: { userEmailHash: subscriberHash },
cause: ensureError(e, 'Mailchimp API error')
}
)
}
@@ -181,7 +181,8 @@ export const createObjectsFactory =
{
batchIndex: index + 1,
totalCountOfBatches: batches.length,
elapsedTimeMs: t1 - t0
elapsedTimeMs: t1 - t0,
countStoredObjects: objsToInsert.length
},
'Batch {batchIndex}/{totalCountOfBatches}: Stored {countStoredObjects} objects in {elapsedTimeMs}ms.'
)
@@ -86,7 +86,7 @@ export const consumePreviewResultFactory =
switch (previewResult.status) {
case 'error':
log.error({ reason: previewResult.reason }, previewMessage)
log.warn({ reason: previewResult.reason }, previewMessage)
await upsertObjectPreview({
objectPreview: {
objectId,
+1 -1
View File
@@ -5,7 +5,7 @@ Tailwind theme used in frontend 2 and other apps.
## Setup
1. Install the package
1. In your tailwind config import `@speckle/tailwind-theme` and `@tailwindcss/forms` and add them to your `plugins` array
1. In your tailwind config import `plugin` from `@speckle/tailwind-theme` and `@tailwindcss/forms` and add them to your `plugins` array
1. Import `tailwindContentEntries` from `@speckle/tailwind-theme/tailwind-configure` and invoke it in the `contents` field in your Tailwind config to ensure PurgeCSS is configured correctly. It requires the CJS `require` object as its only parameter. If it isn't available (in an ESM environment), you can use node's `createRequire()`.
## Development
-2
View File
@@ -1,4 +1,2 @@
import { darkThemeVariables, lightThemeVariables, plugin } from './plugin.js'
export default plugin
export { darkThemeVariables, lightThemeVariables, plugin }
+1 -2
View File
@@ -1,5 +1,5 @@
import buildPlugin from 'tailwindcss/plugin.js'
import preset from './preset.js'
import { config as preset } from './preset.js'
export const lightThemeVariables = {
/* used only as the page background */
@@ -385,5 +385,4 @@ const plugin = buildPlugin(({ addComponents, addBase }) => {
})
}, preset)
export default plugin
export { plugin }
+1 -1
View File
@@ -97,4 +97,4 @@ const config: Config = {
plugins: [FormsPlugin]
}
export default config
export { config }
+2 -2
View File
@@ -1,4 +1,4 @@
const speckleTheme = require('@speckle/tailwind-theme')
const { plugin: speckleTheme } = require('@speckle/tailwind-theme')
const { tailwindContentEntries } = require('@speckle/tailwind-theme/tailwind-configure')
const formsPlugin = require('@tailwindcss/forms')
@@ -10,5 +10,5 @@ module.exports = {
'./src/**/*.{js,ts,jsx,tsx,vue}',
...tailwindContentEntries()
],
plugins: [speckleTheme.default, formsPlugin]
plugins: [speckleTheme, formsPlugin]
}
@@ -53,6 +53,10 @@ export class DepthNormalPass extends BaseGPass {
return this.mrt as unknown as WebGLRenderTarget
}
set outputTarget(target: WebGLMultipleRenderTargets) {
this.mrt = target
}
public set options(value: DepthNormalPassOptions) {
super.options = value
this.depthType = this._options.depthType
@@ -5,7 +5,7 @@ import { TAAPass } from '../Passes/TAAPass.js'
import { ObjectLayers } from '../../../IViewer.js'
import { ProgressivePipeline } from './ProgressivePipeline.js'
import { DepthNormalIdPass } from '../Passes/DepthNormalIdPass.js'
import { Texture } from 'three'
import { Texture, WebGLMultipleRenderTargets } from 'three'
import { DepthPass } from '../Passes/DepthPass.js'
import { NormalsPass } from '../Passes/NormalsPass.js'
import { BasePipelineOptions } from './Pipeline.js'
@@ -50,11 +50,26 @@ export class EdgesPipeline extends ProgressivePipeline {
depthNormalIdPass.setJitter(true)
depthNormalIdPass.setClearColor(0x000000, 1)
depthNormalIdPass.setClearFlags(ClearFlags.COLOR | ClearFlags.DEPTH)
depthNormalIdPass.setVisibility(ObjectVisibility.DEPTH)
const depthNormalIdPassTransparent = new DepthNormalIdPass()
depthNormalIdPassTransparent.setLayers([ObjectLayers.STREAM_CONTENT_MESH])
depthNormalIdPassTransparent.setJitter(true)
depthNormalIdPassTransparent.setVisibility(ObjectVisibility.TRANSPARENT)
depthNormalIdPassTransparent.outputTarget =
depthNormalIdPass.outputTarget as unknown as WebGLMultipleRenderTargets
const depthPassNormalIdDynamic = new DepthNormalIdPass()
depthPassNormalIdDynamic.setLayers([ObjectLayers.STREAM_CONTENT_MESH])
depthPassNormalIdDynamic.setClearColor(0x000000, 1)
depthPassNormalIdDynamic.setClearFlags(ClearFlags.COLOR | ClearFlags.DEPTH)
depthPassNormalIdDynamic.setVisibility(ObjectVisibility.DEPTH)
const depthPassNormalIdDynamicTransparent = new DepthNormalIdPass()
depthPassNormalIdDynamicTransparent.setLayers([ObjectLayers.STREAM_CONTENT_MESH])
depthPassNormalIdDynamicTransparent.setVisibility(ObjectVisibility.TRANSPARENT)
depthPassNormalIdDynamicTransparent.outputTarget =
depthPassNormalIdDynamic.outputTarget as unknown as WebGLMultipleRenderTargets
const edgesPass = new EdgesPass()
edgesPass.setTexture('tDepth', depthNormalIdPass.depthTexture)
@@ -80,8 +95,17 @@ export class EdgesPipeline extends ProgressivePipeline {
taaPass.inputTexture = edgesPass.outputTarget?.texture
taaPass.accumulationFrames = this.accumulationFrameCount
this.dynamicStage.push(depthPassNormalIdDynamic, edgesPassDynamic)
this.progressiveStage.push(depthNormalIdPass, edgesPass, taaPass)
this.dynamicStage.push(
depthPassNormalIdDynamic,
depthPassNormalIdDynamicTransparent,
edgesPassDynamic
)
this.progressiveStage.push(
depthNormalIdPass,
depthNormalIdPassTransparent,
edgesPass,
taaPass
)
this.passList = this.dynamicStage
@@ -566,9 +566,6 @@ Generate the environment variables for Speckle server and Speckle objects deploy
- name: FF_WORKSPACES_MODULE_ENABLED
value: {{ .Values.featureFlags.workspacesModuleEnabled | quote }}
- name: FF_NO_PERSONAL_EMAILS_ENABLED
value: {{ .Values.featureFlags.noPersonalEmailsEnabled | quote }}
- name: FF_WORKSPACES_SSO_ENABLED
value: {{ .Values.featureFlags.workspacesSSOEnabled | quote }}
@@ -141,8 +141,6 @@ spec:
value: {{ .Values.featureFlags.gendoAIModuleEnabled | quote }}
- name: NUXT_PUBLIC_FF_FORCE_ONBOARDING
value: {{ .Values.featureFlags.forceOnboarding | quote }}
- name: NUXT_PUBLIC_FF_NO_PERSONAL_EMAILS_ENABLED
value: {{ .Values.featureFlags.noPersonalEmailsEnabled | quote }}
- name: NUXT_PUBLIC_FF_WORKSPACES_NEW_PLANS_ENABLED
value: {{ .Values.featureFlags.workspacesNewPlanEnabled | quote }}
- name: NUXT_PUBLIC_FF_NEXT_GEN_FILE_IMPORTER_ENABLED
@@ -85,11 +85,6 @@
"description": "Forces onboarding for all users",
"default": false
},
"noPersonalEmailsEnabled": {
"type": "boolean",
"description": "Disables the ability sign up with personal email addresses",
"default": false
},
"workspacesNewPlanEnabled": {
"type": "boolean",
"description": "Toggles whether the new (Q1 2025) plans for workspaces are available. workspacesModuleEnabled must also be enabled for this to take effect.",
-2
View File
@@ -55,8 +55,6 @@ featureFlags:
forceEmailVerification: false
## @param featureFlags.forceOnboarding Forces onboarding for all users
forceOnboarding: false
## @param featureFlags.noPersonalEmailsEnabled Disables the ability sign up with personal email addresses
noPersonalEmailsEnabled: false
## @param featureFlags.workspacesNewPlanEnabled Toggles whether the new (Q1 2025) plans for workspaces are available. workspacesModuleEnabled must also be enabled for this to take effect.
workspacesNewPlanEnabled: false
## @param featureFlags.moveProjectRegionEnabled Enables the ability to move a project region (manually or automatically)