diff --git a/.gitignore b/.gitignore index 62486ca02b3..dc26e75b673 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ stats.json storybook-static/ test-report.xml webpack-assets.json +**/data diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 3a9c391c003..3f880395abc 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "7.31.0" + ".": "7.32.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index a962a8a3916..b2086a50df0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,31 @@ This project adheres to [Semantic Versioning](http://semver.org/). This CHANGELOG follows conventions [outlined here](http://keepachangelog.com/). +## [7.32.0](https://github.com/ParabolInc/parabol/compare/v7.31.0...v7.32.0) (2024-05-21) + + +### Added + +* add favorite activities UI to activity library ([#9680](https://github.com/ParabolInc/parabol/issues/9680)) ([d6a775d](https://github.com/ParabolInc/parabol/commit/d6a775d4e8f5383588938e163b1e44025afa6624)) +* add logic that lets users favorite a template ([#9713](https://github.com/ParabolInc/parabol/issues/9713)) ([4558e14](https://github.com/ParabolInc/parabol/commit/4558e143c98c2ceab197b7c00670cc56ae7c6436)) +* saml upload ([#9750](https://github.com/ParabolInc/parabol/issues/9750)) ([5c40fcf](https://github.com/ParabolInc/parabol/commit/5c40fcfb1d6df9ac32c2f2277735169f0e1ae95d)) +* **single-tenant-host:** Embedder and Text Embeddings Inference added to the stack ([#9753](https://github.com/ParabolInc/parabol/issues/9753)) ([5ec8f45](https://github.com/ParabolInc/parabol/commit/5ec8f457f44780036da79b54136f3c68c5bb052c)) + + +### Fixed + +* close websocket with reason on invalid token ([#9744](https://github.com/ParabolInc/parabol/issues/9744)) ([a5d4bad](https://github.com/ParabolInc/parabol/commit/a5d4badf63781ddf9023fcc169d4b90f0f9d646f)) +* **dev-stack:** update text-embeddings-inference to 1.2.2 ([#9754](https://github.com/ParabolInc/parabol/issues/9754)) ([1c8fa84](https://github.com/ParabolInc/parabol/commit/1c8fa84444dc361d6bb8938d55accad31be2b6e7)) +* fix the issue where a successful upgrade won't refresh the billing page ([#9740](https://github.com/ParabolInc/parabol/issues/9740)) ([9a904d3](https://github.com/ParabolInc/parabol/commit/9a904d3a35b0f82ffd67d6e7d4853b40cfc4f234)) +* Send correct websocket status code ([#9760](https://github.com/ParabolInc/parabol/issues/9760)) ([ca20d75](https://github.com/ParabolInc/parabol/commit/ca20d75d86b467eef64c7e08419434a7f4be5946)) +* Update remove user from org copy ([#9759](https://github.com/ParabolInc/parabol/issues/9759)) ([a39cd41](https://github.com/ParabolInc/parabol/commit/a39cd41baa3a696600af5299b281fbb2729fa7af)) + + +### Changed + +* Trace RRule ([#9756](https://github.com/ParabolInc/parabol/issues/9756)) ([341772a](https://github.com/ParabolInc/parabol/commit/341772af9da5923e7c22b8a253aaca0b2aeab7c5)) +* update tutorial card thumbnail & video links ([#9746](https://github.com/ParabolInc/parabol/issues/9746)) ([28c7432](https://github.com/ParabolInc/parabol/commit/28c743274df3c8ed97e3e8dbe2677a58483a851e)) + ## [7.31.0](https://github.com/ParabolInc/parabol/compare/v7.30.4...v7.31.0) (2024-05-08) diff --git a/codegen.json b/codegen.json index 83f9993f249..2bfa7b6011f 100644 --- a/codegen.json +++ b/codegen.json @@ -49,9 +49,9 @@ "ActionMeeting": "../../database/types/MeetingAction#default", "ActionMeetingMember": "../../database/types/ActionMeetingMember#default as ActionMeetingMemberDB", "AddApprovedOrganizationDomainsSuccess": "./types/AddApprovedOrganizationDomainsSuccess#AddApprovedOrganizationDomainsSuccessSource", + "AddPokerTemplateSuccess": "./types/AddPokerTemplateSuccess#AddPokerTemplateSuccessSource", "AddReactjiToReactableSuccess": "./types/AddReactjiToReactableSuccess#AddReactjiToReactableSuccessSource", "AddReflectTemplateSuccess": "./types/AddReflectTemplateSuccess#AddReflectTemplateSuccessSource", - "AddPokerTemplateSuccess": "./types/AddPokerTemplateSuccess#AddPokerTemplateSuccessSource", "AddTranscriptionBotSuccess": "./types/AddTranscriptionBotSuccess#AddTranscriptionBotSuccessSource", "AddedNotification": "./types/AddedNotification#AddedNotificationSource", "AgendaItem": "../../database/types/AgendaItem#default as AgendaItemDB", @@ -132,6 +132,7 @@ "TeamPromptResponse": "../../postgres/queries/getTeamPromptResponsesByIds#TeamPromptResponse", "TemplateDimension": "../../database/types/TemplateDimension#default", "TimelineEventTeamPromptComplete": "./types/TimelineEventTeamPromptComplete#TimelineEventTeamPromptCompleteSource", + "ToggleFavoriteTemplateSuccess": "./types/ToggleFavoriteTemplateSuccess#ToggleFavoriteTemplateSuccessSource", "ToggleSummaryEmailSuccess": "./types/ToggleSummaryEmailSuccess#ToggleSummaryEmailSuccessSource", "TopRetroTemplate": "./types/TopRetroTemplate#TopRetroTemplateSource", "UpdateAutoJoinSuccess": "./types/UpdateAutoJoinSuccess#UpdateAutoJoinSuccessSource", @@ -140,9 +141,9 @@ "UpdateFeatureFlagPayload": "./types/UpdateFeatureFlagPayload#UpdateFeatureFlagPayloadSource", "UpdateGitLabDimensionFieldSuccess": "./types/UpdateGitLabDimensionFieldSuccess#UpdateGitLabDimensionFieldSuccessSource", "UpdateMeetingPromptSuccess": "./types/UpdateMeetingPromptSuccess#UpdateMeetingPromptSuccessSource", + "UpdateMeetingTemplateSuccess": "./types/UpdateMeetingTemplateSuccess#UpdateMeetingTemplateSuccessSource", "UpdateOrgPayload": "./types/UpdateOrgPayload#UpdateOrgPayloadSource", "UpdateRecurrenceSettingsSuccess": "./types/UpdateRecurrenceSettingsSuccess#UpdateRecurrenceSettingsSuccessSource", - "UpdateMeetingTemplateSuccess": "./types/UpdateMeetingTemplateSuccess#UpdateMeetingTemplateSuccessSource", "UpdateTaskPayload": "./types/UpdateTaskPayload#UpdateTaskPayloadSource", "UpdateTemplateCategorySuccess": "./types/UpdateTemplateCategorySuccess#UpdateTemplateCategorySuccessSource", "UpdateUserProfilePayload": "./types/UpdateUserProfilePayload#UpdateUserProfilePayloadSource", diff --git a/docker/images/parabol-ubi/README.md b/docker/images/parabol-ubi/README.md index 7be2429b457..f6f8692cc38 100644 --- a/docker/images/parabol-ubi/README.md +++ b/docker/images/parabol-ubi/README.md @@ -14,7 +14,7 @@ _Assumes redis, rethinkdb, and postgres already running to have operational stac The commands below will start a Parabol container on the target tag specified in \_DOCKER_TAG export. It will volume mount a .env in your current working directory to the container, so you can pass in any .env in your current working directory. -For a more detailed how-to deploy Parabol, please go to the section [docker-host-st](https://github.com/ParabolInc/parabol/tree/master/docker/parabol-ubi/docker-host-st) +For a more detailed how-to deploy Parabol, please go to the section [docker-host-st](https://github.com/ParabolInc/parabol/tree/master/docker/stacks/single-tenant-host/) - Run the PreDeploy script diff --git a/docker/stacks/development/docker-compose.yml b/docker/stacks/development/docker-compose.yml index a4509d051b9..0b73269d898 100644 --- a/docker/stacks/development/docker-compose.yml +++ b/docker/stacks/development/docker-compose.yml @@ -70,7 +70,7 @@ services: networks: parabol-network: text-embeddings-inference: - image: ghcr.io/huggingface/text-embeddings-inference:cpu-1.2 + image: ghcr.io/huggingface/text-embeddings-inference:cpu-1.2.2 command: - "--model-id=llmrails/ember-v1" platform: linux/x86_64 diff --git a/docker/stacks/single-tenant-host/README.md b/docker/stacks/single-tenant-host/README.md index 5f2ca04254f..dfc04502127 100644 --- a/docker/stacks/single-tenant-host/README.md +++ b/docker/stacks/single-tenant-host/README.md @@ -27,6 +27,14 @@ Chronos isn't started by default. If it needs to run, it must be managed using ` This will run `pre-deploy` and thus it will recreate the `web-server` and the `gql-executor`. +## Running Embedder + +Embedder isn't started by default. If it needs to run, it must be managed using `docker compose --profile databases --profile parabol --profile embedder up`. + +This will run `pre-deploy` and thus it will recreate the `web-server` and the `gql-executor`. + +The Embedder requires a model. It can be provided using the **Text Embeddings Inference** container available on the stack. It can be executed with `docker compose --profile databases --profile text-embeddings --profile parabol --profile embedder up` + ## Database debug Some tools are available to debug the databases is needed: @@ -38,5 +46,5 @@ To operate them use `docker compose up --profile databases --profile database-de ## Running the whole stack -- Start the whole stack: `docker compose --profile databases --profile parabol --profile database-debug --profile chronos up -d`. -- Stop the stack: `docker compose --profile databases --profile parabol --profile database-debug --profile chronos down`. +- Start the whole stack: `docker compose --profile databases --profiles text-embeddings --profile parabol --profile database-debug --profile chronos up --profile embedder -d`. +- Stop the stack: `docker compose --profile databases --profiles text-embeddings --profile parabol --profile database-debug --profile chronos up --profile embedder down`. diff --git a/docker/stacks/single-tenant-host/docker-compose.yml b/docker/stacks/single-tenant-host/docker-compose.yml index a336201bfe3..49a918e985d 100644 --- a/docker/stacks/single-tenant-host/docker-compose.yml +++ b/docker/stacks/single-tenant-host/docker-compose.yml @@ -75,6 +75,20 @@ services: - "8081:8081" networks: - parabol-network + text-embeddings-inference: + profiles: ["text-embeddings"] + container_name: text-embeddings-inference + image: ghcr.io/huggingface/text-embeddings-inference:cpu-1.2.2 + command: + - "--model-id=llmrails/ember-v1" + platform: linux/x86_64 + restart: always + ports: + - "3040:80" + volumes: + - ./data/text-embeddings-inference:/data + networks: + - parabol-network pre-deploy: container_name: pre-deploy profiles: ["parabol"] @@ -162,5 +176,27 @@ services: condition: service_healthy networks: - parabol-network + embedder: + container_name: embedder + profiles: ["embedder"] + image: #image:tag + restart: always + command: bash -c "node dist/embedder.js" + env_file: .env + environment: + - SERVER_ID=15 + volumes: + - "./.env:/parabol/.env" + depends_on: + pre-deploy: + condition: service_completed_successfully + rethinkdb: + condition: service_started + postgres: + condition: service_healthy + redis: + condition: service_healthy + networks: + - parabol-network networks: parabol-network: diff --git a/package.json b/package.json index a2fc3dbc5ed..36d6e1a0270 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "An open-source app for building smarter, more agile teams.", "author": "Parabol Inc. (http://github.com/ParabolInc)", "license": "AGPL-3.0", - "version": "7.31.0", + "version": "7.32.0", "repository": { "type": "git", "url": "https://github.com/ParabolInc/parabol" diff --git a/packages/chronos/package.json b/packages/chronos/package.json index 3edb0647598..22ff9e859d0 100644 --- a/packages/chronos/package.json +++ b/packages/chronos/package.json @@ -1,6 +1,6 @@ { "name": "chronos", - "version": "7.31.0", + "version": "7.32.0", "description": "A cron job scheduler", "author": "Matt Krick ", "homepage": "https://github.com/ParabolInc/parabol/tree/master/packages/chronos#readme", @@ -25,6 +25,6 @@ }, "dependencies": { "cron": "^2.3.1", - "parabol-server": "7.31.0" + "parabol-server": "7.32.0" } } diff --git a/packages/client/components/ActivityLibrary/ActivityCardFavorite.tsx b/packages/client/components/ActivityLibrary/ActivityCardFavorite.tsx new file mode 100644 index 00000000000..51b5cfbf60f --- /dev/null +++ b/packages/client/components/ActivityLibrary/ActivityCardFavorite.tsx @@ -0,0 +1,68 @@ +import {Favorite} from '@mui/icons-material' +import graphql from 'babel-plugin-relay/macro' +import clsx from 'clsx' +import React from 'react' +import {useFragment} from 'react-relay' +import {ActivityCardFavorite_user$key} from '../../__generated__/ActivityCardFavorite_user.graphql' +import useAtmosphere from '../../hooks/useAtmosphere' +import useMutationProps from '../../hooks/useMutationProps' +import ToggleFavoriteTemplateMutation from '../../mutations/ToggleFavoriteTemplateMutation' +import {Tooltip} from '../../ui/Tooltip/Tooltip' +import {TooltipContent} from '../../ui/Tooltip/TooltipContent' +import {TooltipTrigger} from '../../ui/Tooltip/TooltipTrigger' + +type Props = { + className?: string + templateId: string + viewerRef: ActivityCardFavorite_user$key +} + +const ActivityCardFavorite = (props: Props) => { + const {className, templateId, viewerRef} = props + const atmosphere = useAtmosphere() + const {onError, onCompleted} = useMutationProps() + + const viewer = useFragment( + graphql` + fragment ActivityCardFavorite_user on User { + favoriteTemplates { + id + } + } + `, + viewerRef + ) + const favoriteTemplateIds = viewer.favoriteTemplates.map((template) => template.id) + const isFavorite = favoriteTemplateIds.includes(templateId) + const tooltipCopy = isFavorite ? 'Remove from favorites' : 'Add to favorites' + + const handleClick = (e: React.MouseEvent) => { + e.preventDefault() + ToggleFavoriteTemplateMutation(atmosphere, {templateId}, {onError, onCompleted}) + } + + return ( + +
+ + + +
+ + {tooltipCopy} + +
+ ) +} + +export default ActivityCardFavorite diff --git a/packages/client/components/ActivityLibrary/ActivityDetails/TemplateDetails.tsx b/packages/client/components/ActivityLibrary/ActivityDetails/TemplateDetails.tsx index b0ca11e0583..0adf77aab6b 100644 --- a/packages/client/components/ActivityLibrary/ActivityDetails/TemplateDetails.tsx +++ b/packages/client/components/ActivityLibrary/ActivityDetails/TemplateDetails.tsx @@ -23,6 +23,7 @@ import {setActiveTemplate} from '../../../utils/relay/setActiveTemplate' import useTemplateDescription from '../../../utils/useTemplateDescription' import DetailAction from '../../DetailAction' import FlatButton from '../../FlatButton' +import ActivityCardFavorite from '../ActivityCardFavorite' import {QUICK_START_CATEGORY_ID} from '../Categories' import TeamPickerModal from '../TeamPickerModal' import ActivityDetailsBadges from './ActivityDetailsBadges' @@ -132,6 +133,7 @@ export const TemplateDetails = (props: Props) => { const viewer = useFragment( graphql` fragment TemplateDetails_user on User { + ...ActivityCardFavorite_user preferredTeamId teams { ...TeamPickerModal_teams @@ -258,15 +260,22 @@ export const TemplateDetails = (props: Props) => { {!isOwner && __typename !== 'FixedActivity' && (
{description}
-
- - -
Clone & Edit
-
+
+ +
+ + +
Clone & Edit
+
+
)} diff --git a/packages/client/components/ActivityLibrary/ActivityGrid.tsx b/packages/client/components/ActivityLibrary/ActivityGrid.tsx index dbfbbbe9f66..1ee031f248a 100644 --- a/packages/client/components/ActivityLibrary/ActivityGrid.tsx +++ b/packages/client/components/ActivityLibrary/ActivityGrid.tsx @@ -1,7 +1,11 @@ +import graphql from 'babel-plugin-relay/macro' import React from 'react' +import {useFragment} from 'react-relay' import {Link} from 'react-router-dom' +import {ActivityGrid_user$key} from '../../__generated__/ActivityGrid_user.graphql' import {ActivityBadge} from './ActivityBadge' import {ActivityCard, ActivityCardImage} from './ActivityCard' +import ActivityCardFavorite from './ActivityCardFavorite' import {Template} from './ActivityLibrary' import {ActivityLibraryCardDescription} from './ActivityLibraryCardDescription' import {CATEGORY_THEMES, CategoryID} from './Categories' @@ -9,9 +13,19 @@ import {CATEGORY_THEMES, CategoryID} from './Categories' interface ActivityGridProps { templates: Template[] selectedCategory: string + viewerRef?: ActivityGrid_user$key } -const ActivityGrid = ({templates, selectedCategory}: ActivityGridProps) => { +const ActivityGrid = (props: ActivityGridProps) => { + const {templates, selectedCategory, viewerRef} = props + const viewer = useFragment( + graphql` + fragment ActivityGrid_user on User { + ...ActivityCardFavorite_user + } + `, + viewerRef ?? null + ) return ( <> {templates.map((template) => { @@ -42,6 +56,13 @@ const ActivityGrid = ({templates, selectedCategory}: ActivityGridProps) => { src={template.illustrationUrl} category={template.category as CategoryID} /> + {viewer && ( + + )} { // If there's a search query, just use the search filter results return filteredTemplates } + if (categoryId === 'favorite') { + return viewer.favoriteTemplates + } return filteredTemplates.filter((template) => categoryId === QUICK_START_CATEGORY_ID @@ -326,7 +333,7 @@ export const ActivityLibrary = (props: Props) => {
- {(availableCategoryIds as Array).map( + {(availableCategoryIds as Array).map( (category) => ( { to={`/activity-library/category/${category}`} onClick={() => resetQuery()} key={category} + style={{ + color: + category === 'favorite' + ? category === categoryId && searchQuery.length === 0 + ? 'white' + : 'red' + : undefined + }} > {CATEGORY_ID_TO_NAME[category]} @@ -380,6 +395,7 @@ export const ActivityLibrary = (props: Props) => {
@@ -392,6 +408,7 @@ export const ActivityLibrary = (props: Props) => {
diff --git a/packages/client/components/ActivityLibrary/ActivityLibraryEmptyState.tsx b/packages/client/components/ActivityLibrary/ActivityLibraryEmptyState.tsx index 8b112783c50..26b1e28183b 100644 --- a/packages/client/components/ActivityLibrary/ActivityLibraryEmptyState.tsx +++ b/packages/client/components/ActivityLibrary/ActivityLibraryEmptyState.tsx @@ -1,4 +1,6 @@ +import FavoriteIcon from '@mui/icons-material/Favorite' import React from 'react' +import favoriteImg from '../../../../static/images/illustrations/favorite-empty-state.png' import halloweenRetrospectiveTemplate from '../../../../static/images/illustrations/halloweenRetrospectiveTemplate.png' import {AllCategoryID, QUICK_START_CATEGORY_ID} from './Categories' import CreateActivityCard from './CreateActivityCard' @@ -12,6 +14,36 @@ const ActivityLibraryEmptyState = (props: Props) => { const {categoryId, searchQuery} = props const showResultsNotFound = categoryId !== 'custom' || searchQuery !== '' + if (categoryId === 'favorite') { + return ( +
+
+ Favorite placeholder +
+
+ + + + Activities you mark as favorite will show up here + +
+
+
+
+ ) + } + return (
diff --git a/packages/client/components/ActivityLibrary/Categories.ts b/packages/client/components/ActivityLibrary/Categories.tsx similarity index 80% rename from packages/client/components/ActivityLibrary/Categories.ts rename to packages/client/components/ActivityLibrary/Categories.tsx index 57b66dbd474..6e6c463ace1 100644 --- a/packages/client/components/ActivityLibrary/Categories.ts +++ b/packages/client/components/ActivityLibrary/Categories.tsx @@ -1,3 +1,5 @@ +import FavoriteIcon from '@mui/icons-material/Favorite' +import React from 'react' import {MeetingTypeEnum} from '../../__generated__/MeetingSelectorQuery.graphql' import {CardTheme} from './ActivityCard' @@ -13,10 +15,12 @@ export const MAIN_CATEGORIES = [ export const QUICK_START_CATEGORY_ID = 'recommended' export const CUSTOM_CATEGORY_ID = 'custom' +export const FAVORITE_CATEGORY_ID = 'favorite' export const ALL_CATEGORIES = [ QUICK_START_CATEGORY_ID, ...MAIN_CATEGORIES, + FAVORITE_CATEGORY_ID, CUSTOM_CATEGORY_ID ] as const @@ -46,11 +50,25 @@ export const CATEGORY_THEMES: Record = { primary: 'bg-fuscia-400', secondary: 'bg-slate-200', text: 'text-slate-500' + }, + [FAVORITE_CATEGORY_ID]: { + primary: 'bg-grape-700', + secondary: 'bg-slate-200', + text: 'text-slate-500' } } -export const CATEGORY_ID_TO_NAME: Record = { +export const CATEGORY_ID_TO_NAME: Record = { [QUICK_START_CATEGORY_ID]: 'Quick Start', + [FAVORITE_CATEGORY_ID]: ( + + ), [CUSTOM_CATEGORY_ID]: 'Custom', retrospective: 'Retrospective', estimation: 'Estimation', diff --git a/packages/client/components/MeetingsDash.tsx b/packages/client/components/MeetingsDash.tsx index 7faf932e1b6..bffee6c9a76 100644 --- a/packages/client/components/MeetingsDash.tsx +++ b/packages/client/components/MeetingsDash.tsx @@ -137,6 +137,7 @@ const MeetingsDash = (props: Props) => { {!teamFilterIds ? ( + diff --git a/packages/client/components/TutorialMeetingCard.tsx b/packages/client/components/TutorialMeetingCard.tsx index 543a9eb1f6a..da38f967417 100644 --- a/packages/client/components/TutorialMeetingCard.tsx +++ b/packages/client/components/TutorialMeetingCard.tsx @@ -2,6 +2,7 @@ import styled from '@emotion/styled' import React, {useCallback} from 'react' import SendClientSideEvent from '~/utils/SendClientSideEvent' import pokerTutorialThumb from '../../../static/images/illustrations/pokerTutorialThumb.jpg' +import retroTutorialThumb from '../../../static/images/illustrations/retroTutorialThumb.png' import standupTutorialThumb from '../../../static/images/illustrations/standupTutorialThumb.jpg' import useAtmosphere from '../hooks/useAtmosphere' import useBreakpoint from '../hooks/useBreakpoint' @@ -100,14 +101,19 @@ const TopLine = styled('div')({ }) interface Props { - type: 'poker' | 'standup' + type: 'retro' | 'poker' | 'standup' } const TUTORIAL_MAP = { + retro: { + label: 'Starting a Retrospective Meeting', + thumbnail: retroTutorialThumb, + url: 'https://www.youtube.com/embed/C96fNtypaww?modestbranding=1&rel=0' + }, poker: { label: 'Starting a Sprint Poker Meeting', thumbnail: pokerTutorialThumb, - url: 'https://www.youtube.com/embed/X_i60AMxPBU?modestbranding=1&rel=0' + url: 'https://www.youtube.com/embed/RJGnNXvvShY?modestbranding=1&rel=0' }, standup: { label: 'Starting a Standup Meeting', diff --git a/packages/client/modules/teamDashboard/components/TeamDashActivityTab/TeamDashActivityTab.tsx b/packages/client/modules/teamDashboard/components/TeamDashActivityTab/TeamDashActivityTab.tsx index 1698bc099a5..5a09a122b4c 100644 --- a/packages/client/modules/teamDashboard/components/TeamDashActivityTab/TeamDashActivityTab.tsx +++ b/packages/client/modules/teamDashboard/components/TeamDashActivityTab/TeamDashActivityTab.tsx @@ -65,6 +65,7 @@ const TeamDashActivityTab = (props: Props) => { ) : ( <> + diff --git a/packages/client/modules/userDashboard/components/OrgAuthentication/OrgAuthenticationMetadata.tsx b/packages/client/modules/userDashboard/components/OrgAuthentication/OrgAuthenticationMetadata.tsx index d49313ec356..ba2d6ece67c 100644 --- a/packages/client/modules/userDashboard/components/OrgAuthentication/OrgAuthenticationMetadata.tsx +++ b/packages/client/modules/userDashboard/components/OrgAuthentication/OrgAuthenticationMetadata.tsx @@ -1,5 +1,6 @@ +import UploadFileIcon from '@mui/icons-material/UploadFile' import graphql from 'babel-plugin-relay/macro' -import React, {useState} from 'react' +import React, {useRef, useState} from 'react' import {commitLocalUpdate, useFragment} from 'react-relay' import orgAuthenticationMetadataQuery, { OrgAuthenticationMetadataQuery @@ -9,6 +10,8 @@ import BasicInput from '../../../../components/InputField/BasicInput' import SecondaryButton from '../../../../components/SecondaryButton' import useAtmosphere from '../../../../hooks/useAtmosphere' import useMutationProps from '../../../../hooks/useMutationProps' +import {useUploadIdPMetadata} from '../../../../mutations/useUploadIdPMetadataMutation' +import {Button} from '../../../../ui/Button/Button' import getOAuthPopupFeatures from '../../../../utils/getOAuthPopupFeatures' import getTokenFromSSO from '../../../../utils/getTokenFromSSO' @@ -40,6 +43,7 @@ const OrgAuthenticationMetadata = (props: Props) => { fragment OrgAuthenticationMetadata_saml on SAML { id metadataURL + orgId } `, samlRef @@ -49,7 +53,7 @@ const OrgAuthenticationMetadata = (props: Props) => { const isMetadataURLSaved = saml ? saml.metadataURL === metadataURL : false const {error, onCompleted, onError, submitMutation, submitting} = useMutationProps() const submitMetadataURL = async () => { - if (submitting) return + if (submitting || !metadataURL) return submitMutation() const domain = saml?.id if (!domain) { @@ -99,6 +103,36 @@ const OrgAuthenticationMetadata = (props: Props) => { key: 'submitMetadata' }) } + + const uploadInputRef = useRef(null) + const onUploadClick = () => { + uploadInputRef.current?.click() + } + const [commit] = useUploadIdPMetadata() + const uploadXML = (e: React.ChangeEvent) => { + const {files} = e.currentTarget + const file = files?.[0] + if (!file || !saml?.orgId) return + commit({ + variables: {orgId: saml.orgId}, + uploadables: {file: file}, + onCompleted: (res) => { + const {uploadIdPMetadata} = res + const {error, url} = uploadIdPMetadata + const message = error?.message + if (message) { + atmosphere.eventEmitter.emit('addSnackbar', { + key: 'errorUploadIdPtMetadata', + message, + autoDismiss: 5 + }) + return + } + setMetadataURL(url!) + } + }) + } + return ( <>
@@ -115,6 +149,17 @@ const OrgAuthenticationMetadata = (props: Props) => { onChange={(e) => setMetadataURL(e.target.value)} error={undefined} /> + +
{error?.message}
diff --git a/packages/client/modules/userDashboard/components/RemoveFromOrgModal/RemoveFromOrgModal.tsx b/packages/client/modules/userDashboard/components/RemoveFromOrgModal/RemoveFromOrgModal.tsx index fe04cba1304..5d8a079bba8 100644 --- a/packages/client/modules/userDashboard/components/RemoveFromOrgModal/RemoveFromOrgModal.tsx +++ b/packages/client/modules/userDashboard/components/RemoveFromOrgModal/RemoveFromOrgModal.tsx @@ -37,9 +37,7 @@ const RemoveFromOrgModal = (props: Props) => { {'Are you sure?'} - {`This will remove ${preferredName} from the organization. Any outstanding tasks will be given - to the team leads. Any time remaining on their subscription will be refunded on the next - invoice.`} + {`This will remove ${preferredName} from all teams within the organization. Any outstanding tasks will be given to the respective team leads.`} diff --git a/packages/client/mutations/ToggleFavoriteTemplateMutation.ts b/packages/client/mutations/ToggleFavoriteTemplateMutation.ts new file mode 100644 index 00000000000..c052d601311 --- /dev/null +++ b/packages/client/mutations/ToggleFavoriteTemplateMutation.ts @@ -0,0 +1,41 @@ +import graphql from 'babel-plugin-relay/macro' +import {commitMutation} from 'react-relay' +import {ToggleFavoriteTemplateMutation as TToggleFavoriteTemplateMutation} from '../__generated__/ToggleFavoriteTemplateMutation.graphql' +import {StandardMutation} from '../types/relayMutations' + +graphql` + fragment ToggleFavoriteTemplateMutation_viewer on ToggleFavoriteTemplateSuccess { + user { + id + ...ActivityCardFavorite_user + } + } +` + +const mutation = graphql` + mutation ToggleFavoriteTemplateMutation($templateId: ID!) { + toggleFavoriteTemplate(templateId: $templateId) { + ... on ErrorPayload { + error { + message + } + } + ...ToggleFavoriteTemplateMutation_viewer @relay(mask: false) + } + } +` + +const ToggleFavoriteTemplateMutation: StandardMutation = ( + atmosphere, + variables, + {onError, onCompleted} +) => { + return commitMutation(atmosphere, { + mutation, + variables, + onCompleted, + onError + }) +} + +export default ToggleFavoriteTemplateMutation diff --git a/packages/client/mutations/handlers/upgradeToTeamTierSuccessUpdater.ts b/packages/client/mutations/handlers/upgradeToTeamTierSuccessUpdater.ts index 8824f06e4eb..f47a9bbb626 100644 --- a/packages/client/mutations/handlers/upgradeToTeamTierSuccessUpdater.ts +++ b/packages/client/mutations/handlers/upgradeToTeamTierSuccessUpdater.ts @@ -5,6 +5,8 @@ const upgradeToTeamTierSuccessUpdater = (payload: RecordProxy) => { if (organization) { organization.setValue(true, 'showConfetti') organization.setValue(true, 'showDrawer') + organization.setValue('team', 'billingTier') + organization.setValue('team', 'tier') } } export default upgradeToTeamTierSuccessUpdater diff --git a/packages/client/mutations/useUploadIdPMetadataMutation.ts b/packages/client/mutations/useUploadIdPMetadataMutation.ts new file mode 100644 index 00000000000..0c50bf2540d --- /dev/null +++ b/packages/client/mutations/useUploadIdPMetadataMutation.ts @@ -0,0 +1,43 @@ +import graphql from 'babel-plugin-relay/macro' +import {useMutation} from 'react-relay' +import {useUploadIdPMetadataMutation as TuseUploadIdPMetadataMutation} from '../__generated__/useUploadIdPMetadataMutation.graphql' + +const mutation = graphql` + mutation useUploadIdPMetadataMutation($file: File!, $orgId: ID!) { + uploadIdPMetadata(file: $file, orgId: $orgId) { + ... on ErrorPayload { + error { + message + } + } + ... on UploadIdPMetadataSuccess { + url + } + } + } +` +interface TTuseUploadIdPMetadataMutation extends Omit { + variables: Omit + uploadables: {file: File} +} + +export const useUploadIdPMetadata = () => { + const [commit, submitting] = useMutation(mutation) + type Execute = ( + config: Parameters[0] & {uploadables: {file: File}} + ) => ReturnType + + const execute: Execute = (config) => { + const {variables} = config + const {orgId} = variables + return commit({ + updater: (store) => { + const org = store.get(orgId) + org?.setValue(orgId, 'id') + }, + // allow components to override default handlers + ...config + }) + } + return [execute, submitting] as const +} diff --git a/packages/client/package.json b/packages/client/package.json index f1b12613b68..c9f898a4047 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -3,7 +3,7 @@ "description": "An open-source app for building smarter, more agile teams.", "author": "Parabol Inc. (http://github.com/ParabolInc)", "license": "AGPL-3.0", - "version": "7.31.0", + "version": "7.32.0", "repository": { "type": "git", "url": "https://github.com/ParabolInc/parabol" @@ -68,7 +68,7 @@ "@emotion/styled": "^10.0.27", "@mattkrick/graphql-trebuchet-client": "^2.2.1", "@mattkrick/sanitize-svg": "0.4.0", - "@mattkrick/trebuchet-client": "^3.0.2", + "@mattkrick/trebuchet-client": "3.0.1", "@mui/icons-material": "^5.8.4", "@mui/material": "^5.9.2", "@mui/x-date-pickers": "^6.3.1", diff --git a/packages/client/ui/Button/Button.tsx b/packages/client/ui/Button/Button.tsx index e214959b5c7..fcfb00ec8eb 100644 --- a/packages/client/ui/Button/Button.tsx +++ b/packages/client/ui/Button/Button.tsx @@ -1,6 +1,7 @@ import {Slot} from '@radix-ui/react-slot' import clsx from 'clsx' import React from 'react' +import {twMerge} from 'tailwind-merge' type Variant = 'primary' | 'secondary' | 'destructive' | 'ghost' | 'link' | 'outline' type Size = 'sm' | 'md' | 'lg' | 'default' @@ -45,12 +46,14 @@ const Button = React.forwardRef( const Comp = asChild ? Slot : 'button' return ( ", "homepage": "https://github.com/ParabolInc/parabol/tree/master/packages/embedder#readme", diff --git a/packages/gql-executor/package.json b/packages/gql-executor/package.json index 2b4ac934549..52fb5f2bb8b 100644 --- a/packages/gql-executor/package.json +++ b/packages/gql-executor/package.json @@ -1,6 +1,6 @@ { "name": "gql-executor", - "version": "7.31.0", + "version": "7.32.0", "description": "A Stateless GraphQL Executor", "author": "Matt Krick ", "homepage": "https://github.com/ParabolInc/parabol/tree/master/packages/gqlExecutor#readme", @@ -27,8 +27,8 @@ }, "dependencies": { "dd-trace": "^4.2.0", - "parabol-client": "7.31.0", - "parabol-server": "7.31.0", + "parabol-client": "7.32.0", + "parabol-server": "7.32.0", "undici": "^5.26.2" } } diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index da23b924d9f..d7aa0dcbc00 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -2,7 +2,7 @@ "name": "integration-tests", "author": "Parabol Inc. (http://github.com/ParabolInc)", "license": "AGPL-3.0", - "version": "7.31.0", + "version": "7.32.0", "description": "", "main": "index.js", "scripts": { diff --git a/packages/server/database/types/User.ts b/packages/server/database/types/User.ts index 0f5002becae..05431d88791 100644 --- a/packages/server/database/types/User.ts +++ b/packages/server/database/types/User.ts @@ -9,6 +9,7 @@ interface Input { id?: string preferredName: string email: string + favoriteTemplateIds?: string[] featureFlags?: string[] lastSeenAt?: Date lastSeenAtURLs?: string[] @@ -28,6 +29,7 @@ export default class User { id: string preferredName: string email: string + favoriteTemplateIds: string[] featureFlags: string[] lastSeenAt: Date lastSeenAtURLs: string[] | null @@ -55,6 +57,7 @@ export default class User { createdAt, picture, updatedAt, + favoriteTemplateIds, featureFlags, lastSeenAt, lastSeenAtURLs, @@ -73,6 +76,7 @@ export default class User { this.createdAt = createdAt || now this.picture = picture this.updatedAt = updatedAt || now + this.favoriteTemplateIds = favoriteTemplateIds || [] this.featureFlags = featureFlags || [] this.identities = identities || [] this.inactive = inactive || false diff --git a/packages/server/dataloader/customLoaderMakers.ts b/packages/server/dataloader/customLoaderMakers.ts index fb3931b1506..0ceba9e5255 100644 --- a/packages/server/dataloader/customLoaderMakers.ts +++ b/packages/server/dataloader/customLoaderMakers.ts @@ -842,6 +842,27 @@ export const isCompanyDomain = (parent: RootDataLoader) => { ) } +export const favoriteTemplateIds = (parent: RootDataLoader) => { + return new DataLoader( + async (userIds) => { + const pg = getKysely() + const users = await pg + .selectFrom('User') + .select(['id', 'favoriteTemplateIds']) + .where('id', 'in', userIds) + .execute() + + const userIdToFavoriteTemplateIds = new Map( + users.map((user) => [user.id, user.favoriteTemplateIds]) + ) + return userIds.map((userId) => userIdToFavoriteTemplateIds.get(userId) || []) + }, + { + ...parent.dataLoaderOptions + } + ) +} + export const fileStoreAsset = (parent: RootDataLoader) => { return new DataLoader( async (urls) => { diff --git a/packages/server/fileStorage/FileStoreManager.ts b/packages/server/fileStorage/FileStoreManager.ts index f35f9ebe5f0..35db10931f2 100644 --- a/packages/server/fileStorage/FileStoreManager.ts +++ b/packages/server/fileStorage/FileStoreManager.ts @@ -28,6 +28,11 @@ export default abstract class FileStoreManager { return this.putUserFile(file, partialPath) } + async putOrgIdPMetadata(file: ArrayBufferLike, orgId: string) { + const partialPath = `Organization/${orgId}/idpMetadata.xml` + return this.putUserFile(file, partialPath) + } + async putTemplateIllustration(file: ArrayBufferLike, orgId: string, ext: string, name?: string) { const filename = name ?? generateUID() const dotfreeExt = ext.replace(/^\./, '') diff --git a/packages/server/graphql/private/mutations/processRecurrence.ts b/packages/server/graphql/private/mutations/processRecurrence.ts index 9b9e6decc53..57d1e8578d5 100644 --- a/packages/server/graphql/private/mutations/processRecurrence.ts +++ b/packages/server/graphql/private/mutations/processRecurrence.ts @@ -187,7 +187,9 @@ const processRecurrence: MutationResolvers['processRecurrence'] = async (_source // For meetings that should still be active, start the meeting and set its end time. // Any subscriptions are handled by the shared meeting start code - const rrule = RRule.fromString(meetingSeries.recurrenceRule) + const rrule = tracer.trace('RRule.fromString', () => + RRule.fromString(meetingSeries.recurrenceRule) + ) // technically, RRULE should never return NaN here but there's a bug in the library // https://github.com/jakubroztocil/rrule/issues/321 if (isNaN(rrule.options.interval)) { @@ -202,9 +204,8 @@ const processRecurrence: MutationResolvers['processRecurrence'] = async (_source Math.max(lastMeeting.createdAt.getTime() + ms('10m'), now.getTime() - ms('24h')) ) : new Date(0) - const newMeetingsStartTimes = rrule.between( - getRRuleDateFromJSDate(fromDate), - getRRuleDateFromJSDate(now) + const newMeetingsStartTimes = tracer.trace('RRule.between', () => + rrule.between(getRRuleDateFromJSDate(fromDate), getRRuleDateFromJSDate(now)) ) for (const startTime of newMeetingsStartTimes) { const err = await tracer.trace('startRecurringMeeting', async (span) => { diff --git a/packages/server/graphql/public/mutations/toggleFavoriteTemplate.ts b/packages/server/graphql/public/mutations/toggleFavoriteTemplate.ts new file mode 100644 index 00000000000..31874a1e1b5 --- /dev/null +++ b/packages/server/graphql/public/mutations/toggleFavoriteTemplate.ts @@ -0,0 +1,37 @@ +import getKysely from '../../../postgres/getKysely' +import {getUserId} from '../../../utils/authorization' +import {MutationResolvers} from '../resolverTypes' + +const toggleFavoriteTemplate: MutationResolvers['toggleFavoriteTemplate'] = async ( + _source, + {templateId}, + {authToken, dataLoader} +) => { + const viewerId = getUserId(authToken) + const pg = getKysely() + const userId = getUserId(authToken) + + const favoriteTemplateIds = await dataLoader.get('favoriteTemplateIds').load(viewerId) + + let updatedFavoriteTemplateIds + + const isCurrentlyFavorite = favoriteTemplateIds.includes(templateId) + + if (isCurrentlyFavorite) { + updatedFavoriteTemplateIds = favoriteTemplateIds.filter((id) => id !== templateId) + } else { + updatedFavoriteTemplateIds = [...favoriteTemplateIds, templateId] + } + + await pg + .updateTable('User') + .set({ + favoriteTemplateIds: updatedFavoriteTemplateIds + }) + .where('id', '=', userId) + .execute() + + return true +} + +export default toggleFavoriteTemplate diff --git a/packages/server/graphql/public/mutations/uploadIdPMetadata.ts b/packages/server/graphql/public/mutations/uploadIdPMetadata.ts new file mode 100644 index 00000000000..c31cdec49ba --- /dev/null +++ b/packages/server/graphql/public/mutations/uploadIdPMetadata.ts @@ -0,0 +1,24 @@ +import getFileStoreManager from '../../../fileStorage/getFileStoreManager' +import {MutationResolvers} from '../resolverTypes' + +const uploadIdPMetadata: MutationResolvers['uploadIdPMetadata'] = async (_, {file, orgId}) => { + // VALIDATION + const {contentType, buffer: jsonBuffer} = file + const buffer = Buffer.from(jsonBuffer.data) + if (!contentType || !contentType.includes('xml')) { + return {error: {message: 'file must be XML'}} + } + if (buffer.byteLength > 1000000) { + return {error: {message: 'file must be less than 1MB'}} + } + if (buffer.byteLength <= 1) { + return {error: {message: 'file must be larger than 1 byte'}} + } + + // RESOLUTION + const manager = getFileStoreManager() + const url = await manager.putOrgIdPMetadata(buffer, orgId) + return {url} +} + +export default uploadIdPMetadata diff --git a/packages/server/graphql/public/permissions.ts b/packages/server/graphql/public/permissions.ts index dd0930cdb35..edf2d4ccce6 100644 --- a/packages/server/graphql/public/permissions.ts +++ b/packages/server/graphql/public/permissions.ts @@ -4,10 +4,11 @@ import {Resolvers} from './resolverTypes' import getTeamIdFromArgTemplateId from './rules/getTeamIdFromArgTemplateId' import isAuthenticated from './rules/isAuthenticated' import isEnvVarTrue from './rules/isEnvVarTrue' -import {isOrgTier, isOrgTierSource} from './rules/isOrgTier' +import {isOrgTier} from './rules/isOrgTier' import isSuperUser from './rules/isSuperUser' import isUserViewer from './rules/isUserViewer' -import {isViewerBillingLeader, isViewerBillingLeaderSource} from './rules/isViewerBillingLeader' +import {isViewerBillingLeader} from './rules/isViewerBillingLeader' +import {isViewerOnOrg} from './rules/isViewerOnOrg' import isViewerOnTeam from './rules/isViewerOnTeam' import rateLimit from './rules/rateLimit' @@ -50,9 +51,10 @@ const permissionMap: PermissionMap = { verifyEmail: rateLimit({perMinute: 50, perHour: 100}), addApprovedOrganizationDomains: or( isSuperUser, - and(isViewerBillingLeader, isOrgTier('enterprise')) + and(isViewerBillingLeader('args.orgId'), isOrgTier('args.orgId', 'enterprise')) ), - removeApprovedOrganizationDomains: or(isSuperUser, isViewerBillingLeader), + removeApprovedOrganizationDomains: or(isSuperUser, isViewerBillingLeader('args.orgId')), + uploadIdPMetadata: isViewerOnOrg('args.orgId'), updateTemplateCategory: isViewerOnTeam(getTeamIdFromArgTemplateId) }, Query: { @@ -61,7 +63,7 @@ const permissionMap: PermissionMap = { SAMLIdP: rateLimit({perMinute: 120, perHour: 3600}) }, Organization: { - saml: and(isViewerBillingLeaderSource, isOrgTierSource('enterprise')) + saml: and(isViewerBillingLeader('source.id'), isOrgTier('source.id', 'enterprise')) }, User: { domains: or(isSuperUser, isUserViewer) diff --git a/packages/server/graphql/public/rules/getResolverDotPath.ts b/packages/server/graphql/public/rules/getResolverDotPath.ts new file mode 100644 index 00000000000..cac815882a0 --- /dev/null +++ b/packages/server/graphql/public/rules/getResolverDotPath.ts @@ -0,0 +1,9 @@ +export const getResolverDotPath = ( + dotPath: ResolverDotPath, + source: Record, + args: Record +) => { + return dotPath.split('.').reduce((val: any, key) => val?.[key], {source, args}) +} + +export type ResolverDotPath = `source.${string}` | `args.${string}` diff --git a/packages/server/graphql/public/rules/isOrgTier.ts b/packages/server/graphql/public/rules/isOrgTier.ts index 8b1da02e726..06e10388dac 100644 --- a/packages/server/graphql/public/rules/isOrgTier.ts +++ b/packages/server/graphql/public/rules/isOrgTier.ts @@ -1,25 +1,16 @@ import {rule} from 'graphql-shield' import {GQLContext} from '../../graphql' import {TierEnum} from '../resolverTypes' +import {ResolverDotPath, getResolverDotPath} from './getResolverDotPath' -const resolve = async (requiredTier: TierEnum, orgId: string, {dataLoader}: GQLContext) => { - const organization = await dataLoader.get('organizations').load(orgId) - if (!organization) return new Error('Organization not found') - const {tier} = organization - if (tier !== requiredTier) return new Error(`Organization is not ${requiredTier}`) - return true -} - -export const isOrgTierSource = (requiredTier: TierEnum) => - rule(`isOrgTierSource-${requiredTier}`, {cache: 'strict'})( - async ({id: orgId}, _args, context: GQLContext) => { - return resolve(requiredTier, orgId, context) - } - ) - -export const isOrgTier = (requiredTier: TierEnum) => - rule(`isOrgTier-${requiredTier}`, {cache: 'strict'})( - async (_source, {orgId}, context: GQLContext) => { - return resolve(requiredTier, orgId, context) +export const isOrgTier = (orgIdDotPath: ResolverDotPath, requiredTier: TierEnum) => + rule(`isViewerOnOrg-${orgIdDotPath}-${requiredTier}`, {cache: 'strict'})( + async (source, args, {dataLoader}: GQLContext) => { + const orgId = getResolverDotPath(orgIdDotPath, source, args) + const organization = await dataLoader.get('organizations').load(orgId) + if (!organization) return new Error('Organization not found') + const {tier} = organization + if (tier !== requiredTier) return new Error(`Organization is not ${requiredTier}`) + return true } ) diff --git a/packages/server/graphql/public/rules/isViewerBillingLeader.ts b/packages/server/graphql/public/rules/isViewerBillingLeader.ts index 87462f99486..28708113671 100644 --- a/packages/server/graphql/public/rules/isViewerBillingLeader.ts +++ b/packages/server/graphql/public/rules/isViewerBillingLeader.ts @@ -1,31 +1,20 @@ import {rule} from 'graphql-shield' import {getUserId} from '../../../utils/authorization' import {GQLContext} from '../../graphql' +import {ResolverDotPath, getResolverDotPath} from './getResolverDotPath' -const resolve = async (orgId: string, {authToken, dataLoader}: GQLContext) => { - const viewerId = getUserId(authToken) - const organizationUser = await dataLoader - .get('organizationUsersByUserIdOrgId') - .load({orgId, userId: viewerId}) - if (!organizationUser) return new Error('Organization User not found') - const {role} = organizationUser - if (role !== 'BILLING_LEADER' && role !== 'ORG_ADMIN') - return new Error('User is not billing leader') - return true -} - -export const isViewerBillingLeader = rule({cache: 'strict'})(async ( - _source, - {orgId}, - context: GQLContext -) => { - return resolve(orgId, context) -}) - -export const isViewerBillingLeaderSource = rule({cache: 'strict'})(async ( - {id: orgId}, - _args, - context: GQLContext -) => { - return resolve(orgId, context) -}) +export const isViewerBillingLeader = (orgIdDotPath: ResolverDotPath) => + rule(`isViewerBillingLeader-${orgIdDotPath}`, {cache: 'strict'})( + async (source, args, {authToken, dataLoader}: GQLContext) => { + const orgId = getResolverDotPath(orgIdDotPath, source, args) + const viewerId = getUserId(authToken) + const organizationUser = await dataLoader + .get('organizationUsersByUserIdOrgId') + .load({orgId, userId: viewerId}) + if (!organizationUser) return new Error('Organization User not found') + const {role} = organizationUser + if (role !== 'BILLING_LEADER' && role !== 'ORG_ADMIN') + return new Error('User is not billing leader') + return true + } + ) diff --git a/packages/server/graphql/public/rules/isViewerOnOrg.ts b/packages/server/graphql/public/rules/isViewerOnOrg.ts new file mode 100644 index 00000000000..01b0cbab18f --- /dev/null +++ b/packages/server/graphql/public/rules/isViewerOnOrg.ts @@ -0,0 +1,17 @@ +import {rule} from 'graphql-shield' +import {getUserId} from '../../../utils/authorization' +import {GQLContext} from '../../graphql' +import {ResolverDotPath, getResolverDotPath} from './getResolverDotPath' + +export const isViewerOnOrg = (orgIdDotPath: ResolverDotPath) => + rule(`isViewerOnOrg-${orgIdDotPath}`, {cache: 'strict'})( + async (source, args, {authToken, dataLoader}: GQLContext) => { + const orgId = getResolverDotPath(orgIdDotPath, source, args) + const viewerId = getUserId(authToken) + const organizationUser = await dataLoader + .get('organizationUsersByUserIdOrgId') + .load({orgId, userId: viewerId}) + if (!organizationUser) return new Error('Viewer is not on Organization') + return true + } + ) diff --git a/packages/server/graphql/public/typeDefs/User.graphql b/packages/server/graphql/public/typeDefs/User.graphql index bd29eaf1c02..ab75ef73a4c 100644 --- a/packages/server/graphql/public/typeDefs/User.graphql +++ b/packages/server/graphql/public/typeDefs/User.graphql @@ -57,6 +57,11 @@ type User { """ email: Email! + """ + The user's favorite meeting templates + """ + favoriteTemplates: [MeetingTemplate!]! + """ Any super power given to the user via a super user """ diff --git a/packages/server/graphql/public/typeDefs/toggleFavoriteTemplate.graphql b/packages/server/graphql/public/typeDefs/toggleFavoriteTemplate.graphql new file mode 100644 index 00000000000..1e046e2becd --- /dev/null +++ b/packages/server/graphql/public/typeDefs/toggleFavoriteTemplate.graphql @@ -0,0 +1,20 @@ +extend type Mutation { + """ + Add or remove the template to the user's favorite templates + """ + toggleFavoriteTemplate( + """ + The ID of the template to be toggled as a favorite + """ + templateId: ID! + ): ToggleFavoriteTemplatePayload! +} + +union ToggleFavoriteTemplatePayload = ErrorPayload | ToggleFavoriteTemplateSuccess + +type ToggleFavoriteTemplateSuccess { + """ + The user who's favorite templates were updated + """ + user: User! +} diff --git a/packages/server/graphql/public/typeDefs/uploadIdPMetadata.graphql b/packages/server/graphql/public/typeDefs/uploadIdPMetadata.graphql new file mode 100644 index 00000000000..346824208d0 --- /dev/null +++ b/packages/server/graphql/public/typeDefs/uploadIdPMetadata.graphql @@ -0,0 +1,22 @@ +extend type Mutation { + """ + Upload the IdP Metadata file for an org for those who cannot self-host the file + """ + uploadIdPMetadata( + """ + the XML Metadata file for the IdP + """ + file: File! + + """ + The orgId to upload the IdP Metadata for + """ + orgId: ID! + ): UploadIdPMetadataPayload! +} + +union UploadIdPMetadataPayload = ErrorPayload | UploadIdPMetadataSuccess + +type UploadIdPMetadataSuccess { + url: String! +} diff --git a/packages/server/graphql/public/types/ToggleFavoriteTemplateSuccess.ts b/packages/server/graphql/public/types/ToggleFavoriteTemplateSuccess.ts new file mode 100644 index 00000000000..e722b9192a5 --- /dev/null +++ b/packages/server/graphql/public/types/ToggleFavoriteTemplateSuccess.ts @@ -0,0 +1,14 @@ +import {getUserId} from '../../../utils/authorization' +import {ToggleFavoriteTemplateSuccessResolvers} from '../resolverTypes' + +export type ToggleFavoriteTemplateSuccessSource = Record + +const ToggleFavoriteTemplateSuccess: ToggleFavoriteTemplateSuccessResolvers = { + user: async (_, _args, {dataLoader, authToken}) => { + const userId = getUserId(authToken) + const user = await dataLoader.get('users').loadNonNull(userId) + return user + } +} + +export default ToggleFavoriteTemplateSuccess diff --git a/packages/server/graphql/public/types/User.ts b/packages/server/graphql/public/types/User.ts index 8f9f0a40040..b5951a80541 100644 --- a/packages/server/graphql/public/types/User.ts +++ b/packages/server/graphql/public/types/User.ts @@ -19,6 +19,7 @@ import {getSSOMetadataFromURL} from '../../../utils/getSSOMetadataFromURL' import sendToSentry from '../../../utils/sendToSentry' import standardError from '../../../utils/standardError' import {getStripeManager} from '../../../utils/stripe' +import isValid from '../../isValid' import connectionFromTemplateArray from '../../queries/helpers/connectionFromTemplateArray' import {getFeatureTier} from '../../types/helpers/getFeatureTier' import getSignOnURL from '../mutations/helpers/SAMLHelpers/getSignOnURL' @@ -85,6 +86,9 @@ const User: UserResolvers = { } return request }, + favoriteTemplates: async ({favoriteTemplateIds}, _args, {dataLoader}) => { + return (await dataLoader.get('meetingTemplates').loadMany(favoriteTemplateIds)).filter(isValid) + }, featureFlags: ({featureFlags}) => { return Object.fromEntries(featureFlags.map((flag) => [flag as any, true])) }, diff --git a/packages/server/package.json b/packages/server/package.json index 1470d60d1f4..2050704c083 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -3,7 +3,7 @@ "description": "An open-source app for building smarter, more agile teams.", "author": "Parabol Inc. (http://github.com/ParabolInc)", "license": "AGPL-3.0", - "version": "7.31.0", + "version": "7.32.0", "repository": { "type": "git", "url": "https://github.com/ParabolInc/parabol" @@ -75,7 +75,7 @@ }, "dependencies": { "@amplitude/analytics-node": "^1.3.2", - "@aws-sdk/client-s3": "3.537.0", + "@aws-sdk/client-s3": "3.556.0", "@aws-sdk/s3-request-presigner": "^3.565.0", "@dicebear/core": "^8.0.1", "@dicebear/initials": "^8.0.1", @@ -123,7 +123,7 @@ "oauth-1.0a": "^2.2.6", "openai": "^4.24.1", "oy-vey": "^0.12.1", - "parabol-client": "7.31.0", + "parabol-client": "7.32.0", "pg": "^8.5.1", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/packages/server/postgres/migrations/1714598525167_addFavoriteTemplateIds.ts b/packages/server/postgres/migrations/1714598525167_addFavoriteTemplateIds.ts new file mode 100644 index 00000000000..b2a17b04b43 --- /dev/null +++ b/packages/server/postgres/migrations/1714598525167_addFavoriteTemplateIds.ts @@ -0,0 +1,28 @@ +import {Kysely, PostgresDialect, sql} from 'kysely' +import getPg from '../getPg' + +export async function up() { + const pg = new Kysely({ + dialect: new PostgresDialect({ + pool: getPg() + }) + }) + + await sql` + ALTER TABLE "User" + ADD COLUMN "favoriteTemplateIds" TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[]; +`.execute(pg) +} + +export async function down() { + const pg = new Kysely({ + dialect: new PostgresDialect({ + pool: getPg() + }) + }) + + await sql` + ALTER TABLE "User" + DROP COLUMN "favoriteTemplateIds"; +`.execute(pg) +} diff --git a/packages/server/socketHandlers/handleOpen.ts b/packages/server/socketHandlers/handleOpen.ts index b002ac03168..151ac82673f 100644 --- a/packages/server/socketHandlers/handleOpen.ts +++ b/packages/server/socketHandlers/handleOpen.ts @@ -1,9 +1,13 @@ import {WebSocketBehavior} from 'uWebSockets.js' +import {TrebuchetCloseReason} from '../../client/types/constEnums' import activeClients from '../activeClients' import AuthToken from '../database/types/AuthToken' import ConnectionContext from '../socketHelpers/ConnectionContext' import keepAlive from '../socketHelpers/keepAlive' import {sendEncodedMessage} from '../socketHelpers/sendEncodedMessage' +import {isAuthenticated} from '../utils/authorization' +import checkBlacklistJWT from '../utils/checkBlacklistJWT' +import sendToSentry from '../utils/sendToSentry' import handleConnect from './handleConnect' const APP_VERSION = process.env.npm_package_version @@ -11,11 +15,31 @@ export type SocketUserData = { connectionContext: ConnectionContext authToken: AuthToken ip: string + protocol: string done?: true } const handleOpen: WebSocketBehavior['open'] = async (socket) => { - const {authToken, ip} = socket.getUserData() + const {authToken, ip, protocol} = socket.getUserData() + if (protocol !== 'trebuchet-ws') { + sendToSentry(new Error(`WebSocket error: invalid protocol: ${protocol}`)) + socket.end(1002, 'Invalid protocol') + return + } + + if (!isAuthenticated(authToken)) { + socket.end(1008, TrebuchetCloseReason.EXPIRED_SESSION) + return + } + + // ALL async calls must come after the message listener, or we'll skip out on messages (e.g. resub after server restart) + const {sub: userId, iat} = authToken + const isBlacklistedJWT = await checkBlacklistJWT(userId, iat) + if (isBlacklistedJWT) { + socket.end(1008, TrebuchetCloseReason.EXPIRED_SESSION) + return + } + const connectionContext = (socket.getUserData().connectionContext = new ConnectionContext( socket, authToken, diff --git a/packages/server/socketHandlers/handleUpgrade.ts b/packages/server/socketHandlers/handleUpgrade.ts index 07874d2783d..9120b5459fe 100644 --- a/packages/server/socketHandlers/handleUpgrade.ts +++ b/packages/server/socketHandlers/handleUpgrade.ts @@ -1,38 +1,14 @@ import {WebSocketBehavior} from 'uWebSockets.js' -import {TrebuchetCloseReason} from '../../client/types/constEnums' -import safetyPatchRes from '../safetyPatchRes' -import {isAuthenticated} from '../utils/authorization' -import checkBlacklistJWT from '../utils/checkBlacklistJWT' import getQueryToken from '../utils/getQueryToken' -import sendToSentry from '../utils/sendToSentry' import uwsGetIP from '../utils/uwsGetIP' -const handleUpgrade: WebSocketBehavior['upgrade'] = async (res, req, context) => { - safetyPatchRes(res) - const protocol = req.getHeader('sec-websocket-protocol') - if (protocol !== 'trebuchet-ws') { - sendToSentry(new Error(`WebSocket error: invalid protocol: ${protocol}`)) - // WS Error 1002 is roughly HTTP 412 Precondition Failed because we can't support the req header - res.writeStatus('412').end() - return - } - const authToken = getQueryToken(req) - if (!isAuthenticated(authToken)) { - res.writeStatus('401').end() - return - } - +const handleUpgrade: WebSocketBehavior['upgrade'] = (res, req, context) => { const key = req.getHeader('sec-websocket-key') + const protocol = req.getHeader('sec-websocket-protocol') const extensions = req.getHeader('sec-websocket-extensions') const ip = uwsGetIP(res, req) - const {sub: userId, iat} = authToken - // ALL async calls must come after the message listener, or we'll skip out on messages (e.g. resub after server restart) - const isBlacklistedJWT = await checkBlacklistJWT(userId, iat) - if (isBlacklistedJWT) { - res.writeStatus('401').end(TrebuchetCloseReason.EXPIRED_SESSION) - return - } - res.upgrade({ip, authToken}, key, protocol, extensions, context) + const authToken = getQueryToken(req) + res.upgrade({ip, authToken, protocol}, key, protocol, extensions, context) } export default handleUpgrade diff --git a/static/images/illustrations/favorite-empty-state.png b/static/images/illustrations/favorite-empty-state.png new file mode 100644 index 00000000000..53067b97d41 Binary files /dev/null and b/static/images/illustrations/favorite-empty-state.png differ diff --git a/static/images/illustrations/pokerTutorialThumb.jpg b/static/images/illustrations/pokerTutorialThumb.jpg index 9bdf0230665..e10236a1417 100644 Binary files a/static/images/illustrations/pokerTutorialThumb.jpg and b/static/images/illustrations/pokerTutorialThumb.jpg differ diff --git a/static/images/illustrations/retroTutorialThumb.png b/static/images/illustrations/retroTutorialThumb.png new file mode 100644 index 00000000000..560c16a1e8d Binary files /dev/null and b/static/images/illustrations/retroTutorialThumb.png differ diff --git a/static/images/illustrations/standupTutorialThumb.jpg b/static/images/illustrations/standupTutorialThumb.jpg index 62c0f87467c..cd96d52cec0 100644 Binary files a/static/images/illustrations/standupTutorialThumb.jpg and b/static/images/illustrations/standupTutorialThumb.jpg differ diff --git a/yarn.lock b/yarn.lock index d5eaa0e63b8..85a16d38734 100644 --- a/yarn.lock +++ b/yarn.lock @@ -431,17 +431,17 @@ "@smithy/util-waiter" "^2.2.0" tslib "^2.6.2" -"@aws-sdk/client-s3@3.537.0": - version "3.537.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.537.0.tgz#887b2c743da49378104054b66aa135fae805263c" - integrity sha512-EMPN2toHz1QtSiDeLKS1zrazh+8J0g1Y5t5lCq25iTXqCSV9vB2jCKwG5+OB6L5tAKkwyl1uZofeWLmdFkztEg== +"@aws-sdk/client-s3@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.556.0.tgz#b32c12e7857326072df7c53c40b36bdf5d8e6169" + integrity sha512-6WF9Kuzz1/8zqX8hKBpqj9+FYwQ5uTsVcOKpTW94AMX2qtIeVRlwlnNnYyywWo61yqD3g59CMNHcqSsaqAwglg== dependencies: "@aws-crypto/sha1-browser" "3.0.0" "@aws-crypto/sha256-browser" "3.0.0" "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/client-sts" "3.535.0" - "@aws-sdk/core" "3.535.0" - "@aws-sdk/credential-provider-node" "3.535.0" + "@aws-sdk/client-sts" "3.556.0" + "@aws-sdk/core" "3.556.0" + "@aws-sdk/credential-provider-node" "3.556.0" "@aws-sdk/middleware-bucket-endpoint" "3.535.0" "@aws-sdk/middleware-expect-continue" "3.535.0" "@aws-sdk/middleware-flexible-checksums" "3.535.0" @@ -449,19 +449,19 @@ "@aws-sdk/middleware-location-constraint" "3.535.0" "@aws-sdk/middleware-logger" "3.535.0" "@aws-sdk/middleware-recursion-detection" "3.535.0" - "@aws-sdk/middleware-sdk-s3" "3.535.0" - "@aws-sdk/middleware-signing" "3.535.0" + "@aws-sdk/middleware-sdk-s3" "3.556.0" + "@aws-sdk/middleware-signing" "3.556.0" "@aws-sdk/middleware-ssec" "3.537.0" - "@aws-sdk/middleware-user-agent" "3.535.0" + "@aws-sdk/middleware-user-agent" "3.540.0" "@aws-sdk/region-config-resolver" "3.535.0" - "@aws-sdk/signature-v4-multi-region" "3.535.0" + "@aws-sdk/signature-v4-multi-region" "3.556.0" "@aws-sdk/types" "3.535.0" - "@aws-sdk/util-endpoints" "3.535.0" + "@aws-sdk/util-endpoints" "3.540.0" "@aws-sdk/util-user-agent-browser" "3.535.0" "@aws-sdk/util-user-agent-node" "3.535.0" "@aws-sdk/xml-builder" "3.535.0" "@smithy/config-resolver" "^2.2.0" - "@smithy/core" "^1.4.0" + "@smithy/core" "^1.4.2" "@smithy/eventstream-serde-browser" "^2.2.0" "@smithy/eventstream-serde-config-resolver" "^2.2.0" "@smithy/eventstream-serde-node" "^2.2.0" @@ -472,21 +472,21 @@ "@smithy/invalid-dependency" "^2.2.0" "@smithy/md5-js" "^2.2.0" "@smithy/middleware-content-length" "^2.2.0" - "@smithy/middleware-endpoint" "^2.5.0" - "@smithy/middleware-retry" "^2.2.0" + "@smithy/middleware-endpoint" "^2.5.1" + "@smithy/middleware-retry" "^2.3.1" "@smithy/middleware-serde" "^2.3.0" "@smithy/middleware-stack" "^2.2.0" "@smithy/node-config-provider" "^2.3.0" "@smithy/node-http-handler" "^2.5.0" "@smithy/protocol-http" "^3.3.0" - "@smithy/smithy-client" "^2.5.0" + "@smithy/smithy-client" "^2.5.1" "@smithy/types" "^2.12.0" "@smithy/url-parser" "^2.2.0" "@smithy/util-base64" "^2.3.0" "@smithy/util-body-length-browser" "^2.2.0" "@smithy/util-body-length-node" "^2.3.0" - "@smithy/util-defaults-mode-browser" "^2.2.0" - "@smithy/util-defaults-mode-node" "^2.3.0" + "@smithy/util-defaults-mode-browser" "^2.2.1" + "@smithy/util-defaults-mode-node" "^2.3.1" "@smithy/util-endpoints" "^1.2.0" "@smithy/util-retry" "^2.2.0" "@smithy/util-stream" "^2.2.0" @@ -541,60 +541,60 @@ tslib "^2.6.2" uuid "^9.0.1" -"@aws-sdk/client-sso-oidc@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.535.0.tgz#64666c2f7bed8510938ba2b481429fea8f97473d" - integrity sha512-M2cG4EQXDpAJQyq33ORIr6abmdX9p9zX0ssVy8XwFNB7lrgoIKxuVoGL+fX+XMgecl24x7ELz6b4QlILOevbCw== +"@aws-sdk/client-sso-oidc@3.552.0": + version "3.552.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.552.0.tgz#3215792bbce40a4373d6fca711e4b58fbf794284" + integrity sha512-6JYTgN/n4xTm3Z+JhEZq06pyYsgo7heYDmR+0smmauQS02Eu8lvUc2jPs/0GDAmty7J4tq3gS6TRwvf7181C2w== dependencies: "@aws-crypto/sha256-browser" "3.0.0" "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/client-sts" "3.535.0" - "@aws-sdk/core" "3.535.0" + "@aws-sdk/client-sts" "3.552.0" + "@aws-sdk/core" "3.552.0" "@aws-sdk/middleware-host-header" "3.535.0" "@aws-sdk/middleware-logger" "3.535.0" "@aws-sdk/middleware-recursion-detection" "3.535.0" - "@aws-sdk/middleware-user-agent" "3.535.0" + "@aws-sdk/middleware-user-agent" "3.540.0" "@aws-sdk/region-config-resolver" "3.535.0" "@aws-sdk/types" "3.535.0" - "@aws-sdk/util-endpoints" "3.535.0" + "@aws-sdk/util-endpoints" "3.540.0" "@aws-sdk/util-user-agent-browser" "3.535.0" "@aws-sdk/util-user-agent-node" "3.535.0" "@smithy/config-resolver" "^2.2.0" - "@smithy/core" "^1.4.0" + "@smithy/core" "^1.4.2" "@smithy/fetch-http-handler" "^2.5.0" "@smithy/hash-node" "^2.2.0" "@smithy/invalid-dependency" "^2.2.0" "@smithy/middleware-content-length" "^2.2.0" - "@smithy/middleware-endpoint" "^2.5.0" - "@smithy/middleware-retry" "^2.2.0" + "@smithy/middleware-endpoint" "^2.5.1" + "@smithy/middleware-retry" "^2.3.1" "@smithy/middleware-serde" "^2.3.0" "@smithy/middleware-stack" "^2.2.0" "@smithy/node-config-provider" "^2.3.0" "@smithy/node-http-handler" "^2.5.0" "@smithy/protocol-http" "^3.3.0" - "@smithy/smithy-client" "^2.5.0" + "@smithy/smithy-client" "^2.5.1" "@smithy/types" "^2.12.0" "@smithy/url-parser" "^2.2.0" "@smithy/util-base64" "^2.3.0" "@smithy/util-body-length-browser" "^2.2.0" "@smithy/util-body-length-node" "^2.3.0" - "@smithy/util-defaults-mode-browser" "^2.2.0" - "@smithy/util-defaults-mode-node" "^2.3.0" + "@smithy/util-defaults-mode-browser" "^2.2.1" + "@smithy/util-defaults-mode-node" "^2.3.1" "@smithy/util-endpoints" "^1.2.0" "@smithy/util-middleware" "^2.2.0" "@smithy/util-retry" "^2.2.0" "@smithy/util-utf8" "^2.3.0" tslib "^2.6.2" -"@aws-sdk/client-sso-oidc@3.552.0": - version "3.552.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.552.0.tgz#3215792bbce40a4373d6fca711e4b58fbf794284" - integrity sha512-6JYTgN/n4xTm3Z+JhEZq06pyYsgo7heYDmR+0smmauQS02Eu8lvUc2jPs/0GDAmty7J4tq3gS6TRwvf7181C2w== +"@aws-sdk/client-sso-oidc@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.556.0.tgz#4c19fccc35361de046d2cd74a7a685d71aa5dd1e" + integrity sha512-AXKd2TB6nNrksu+OfmHl8uI07PdgzOo4o8AxoRO8SHlwoMAGvcT9optDGVSYoVfgOKTymCoE7h8/UoUfPc11wQ== dependencies: "@aws-crypto/sha256-browser" "3.0.0" "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/client-sts" "3.552.0" - "@aws-sdk/core" "3.552.0" + "@aws-sdk/client-sts" "3.556.0" + "@aws-sdk/core" "3.556.0" "@aws-sdk/middleware-host-header" "3.535.0" "@aws-sdk/middleware-logger" "3.535.0" "@aws-sdk/middleware-recursion-detection" "3.535.0" @@ -631,58 +631,58 @@ "@smithy/util-utf8" "^2.3.0" tslib "^2.6.2" -"@aws-sdk/client-sso@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.535.0.tgz#c405aaf880cb695aa2f5070a8827955274fc9df2" - integrity sha512-h9eQRdFnjDRVBnPJIKXuX7D+isSAioIfZPC4PQwsL5BscTRlk4c90DX0R0uk64YUtp7LZu8TNtrosFZ/1HtTrQ== +"@aws-sdk/client-sso@3.552.0": + version "3.552.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.552.0.tgz#dea1533cc74e80f9bb49f8926c21912497a08616" + integrity sha512-IAjRj5gcuyoPe/OhciMY/UyW8C1kyXSUJFagxvbeSv8q0mEfaPBVjGgz2xSYRFhhZr3gFlGCS9SiukwOL2/VoA== dependencies: "@aws-crypto/sha256-browser" "3.0.0" "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/core" "3.535.0" + "@aws-sdk/core" "3.552.0" "@aws-sdk/middleware-host-header" "3.535.0" "@aws-sdk/middleware-logger" "3.535.0" "@aws-sdk/middleware-recursion-detection" "3.535.0" - "@aws-sdk/middleware-user-agent" "3.535.0" + "@aws-sdk/middleware-user-agent" "3.540.0" "@aws-sdk/region-config-resolver" "3.535.0" "@aws-sdk/types" "3.535.0" - "@aws-sdk/util-endpoints" "3.535.0" + "@aws-sdk/util-endpoints" "3.540.0" "@aws-sdk/util-user-agent-browser" "3.535.0" "@aws-sdk/util-user-agent-node" "3.535.0" "@smithy/config-resolver" "^2.2.0" - "@smithy/core" "^1.4.0" + "@smithy/core" "^1.4.2" "@smithy/fetch-http-handler" "^2.5.0" "@smithy/hash-node" "^2.2.0" "@smithy/invalid-dependency" "^2.2.0" "@smithy/middleware-content-length" "^2.2.0" - "@smithy/middleware-endpoint" "^2.5.0" - "@smithy/middleware-retry" "^2.2.0" + "@smithy/middleware-endpoint" "^2.5.1" + "@smithy/middleware-retry" "^2.3.1" "@smithy/middleware-serde" "^2.3.0" "@smithy/middleware-stack" "^2.2.0" "@smithy/node-config-provider" "^2.3.0" "@smithy/node-http-handler" "^2.5.0" "@smithy/protocol-http" "^3.3.0" - "@smithy/smithy-client" "^2.5.0" + "@smithy/smithy-client" "^2.5.1" "@smithy/types" "^2.12.0" "@smithy/url-parser" "^2.2.0" "@smithy/util-base64" "^2.3.0" "@smithy/util-body-length-browser" "^2.2.0" "@smithy/util-body-length-node" "^2.3.0" - "@smithy/util-defaults-mode-browser" "^2.2.0" - "@smithy/util-defaults-mode-node" "^2.3.0" + "@smithy/util-defaults-mode-browser" "^2.2.1" + "@smithy/util-defaults-mode-node" "^2.3.1" "@smithy/util-endpoints" "^1.2.0" "@smithy/util-middleware" "^2.2.0" "@smithy/util-retry" "^2.2.0" "@smithy/util-utf8" "^2.3.0" tslib "^2.6.2" -"@aws-sdk/client-sso@3.552.0": - version "3.552.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.552.0.tgz#dea1533cc74e80f9bb49f8926c21912497a08616" - integrity sha512-IAjRj5gcuyoPe/OhciMY/UyW8C1kyXSUJFagxvbeSv8q0mEfaPBVjGgz2xSYRFhhZr3gFlGCS9SiukwOL2/VoA== +"@aws-sdk/client-sso@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.556.0.tgz#7beeeebb6a437f09680edefc5c998822292a528a" + integrity sha512-unXdWS7uvHqCcOyC1de+Fr8m3F2vMg2m24GPea0bg7rVGTYmiyn9mhUX11VCt+ozydrw+F50FQwL6OqoqPocmw== dependencies: "@aws-crypto/sha256-browser" "3.0.0" "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/core" "3.552.0" + "@aws-sdk/core" "3.556.0" "@aws-sdk/middleware-host-header" "3.535.0" "@aws-sdk/middleware-logger" "3.535.0" "@aws-sdk/middleware-recursion-detection" "3.535.0" @@ -719,58 +719,58 @@ "@smithy/util-utf8" "^2.3.0" tslib "^2.6.2" -"@aws-sdk/client-sts@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.535.0.tgz#0f518fe338c6b7a8b8a897e2ccee65d06dc0040f" - integrity sha512-ii9OOm3TJwP3JmO1IVJXKWIShVKPl0VtdlgROc/SkDglO/kuAw9eDdlROgc+qbFl+gm6bBTguOVTUXt3tS3flw== +"@aws-sdk/client-sts@3.552.0": + version "3.552.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.552.0.tgz#ae6879022644348596e822e80accb468676a2005" + integrity sha512-rOZlAj8GyFgUBESyKezes67A8Kj5+KjRhfBHMXrkcM5h9UOIz5q7QdkSQOmzWwRoPDmmAqb6t+y041/76TnPEg== dependencies: "@aws-crypto/sha256-browser" "3.0.0" "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/core" "3.535.0" + "@aws-sdk/core" "3.552.0" "@aws-sdk/middleware-host-header" "3.535.0" "@aws-sdk/middleware-logger" "3.535.0" "@aws-sdk/middleware-recursion-detection" "3.535.0" - "@aws-sdk/middleware-user-agent" "3.535.0" + "@aws-sdk/middleware-user-agent" "3.540.0" "@aws-sdk/region-config-resolver" "3.535.0" "@aws-sdk/types" "3.535.0" - "@aws-sdk/util-endpoints" "3.535.0" + "@aws-sdk/util-endpoints" "3.540.0" "@aws-sdk/util-user-agent-browser" "3.535.0" "@aws-sdk/util-user-agent-node" "3.535.0" "@smithy/config-resolver" "^2.2.0" - "@smithy/core" "^1.4.0" + "@smithy/core" "^1.4.2" "@smithy/fetch-http-handler" "^2.5.0" "@smithy/hash-node" "^2.2.0" "@smithy/invalid-dependency" "^2.2.0" "@smithy/middleware-content-length" "^2.2.0" - "@smithy/middleware-endpoint" "^2.5.0" - "@smithy/middleware-retry" "^2.2.0" + "@smithy/middleware-endpoint" "^2.5.1" + "@smithy/middleware-retry" "^2.3.1" "@smithy/middleware-serde" "^2.3.0" "@smithy/middleware-stack" "^2.2.0" "@smithy/node-config-provider" "^2.3.0" "@smithy/node-http-handler" "^2.5.0" "@smithy/protocol-http" "^3.3.0" - "@smithy/smithy-client" "^2.5.0" + "@smithy/smithy-client" "^2.5.1" "@smithy/types" "^2.12.0" "@smithy/url-parser" "^2.2.0" "@smithy/util-base64" "^2.3.0" "@smithy/util-body-length-browser" "^2.2.0" "@smithy/util-body-length-node" "^2.3.0" - "@smithy/util-defaults-mode-browser" "^2.2.0" - "@smithy/util-defaults-mode-node" "^2.3.0" + "@smithy/util-defaults-mode-browser" "^2.2.1" + "@smithy/util-defaults-mode-node" "^2.3.1" "@smithy/util-endpoints" "^1.2.0" "@smithy/util-middleware" "^2.2.0" "@smithy/util-retry" "^2.2.0" "@smithy/util-utf8" "^2.3.0" tslib "^2.6.2" -"@aws-sdk/client-sts@3.552.0": - version "3.552.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.552.0.tgz#ae6879022644348596e822e80accb468676a2005" - integrity sha512-rOZlAj8GyFgUBESyKezes67A8Kj5+KjRhfBHMXrkcM5h9UOIz5q7QdkSQOmzWwRoPDmmAqb6t+y041/76TnPEg== +"@aws-sdk/client-sts@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.556.0.tgz#3aa20cca462839f1451f11efada2be119dd36a6b" + integrity sha512-TsK3js7Suh9xEmC886aY+bv0KdLLYtzrcmVt6sJ/W6EnDXYQhBuKYFhp03NrN2+vSvMGpqJwR62DyfKe1G0QzQ== dependencies: "@aws-crypto/sha256-browser" "3.0.0" "@aws-crypto/sha256-js" "3.0.0" - "@aws-sdk/core" "3.552.0" + "@aws-sdk/core" "3.556.0" "@aws-sdk/middleware-host-header" "3.535.0" "@aws-sdk/middleware-logger" "3.535.0" "@aws-sdk/middleware-recursion-detection" "3.535.0" @@ -807,27 +807,27 @@ "@smithy/util-utf8" "^2.3.0" tslib "^2.6.2" -"@aws-sdk/core@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.535.0.tgz#f3a726c297cea9634d19a1db4e958c918c506c8b" - integrity sha512-+Yusa9HziuaEDta1UaLEtMAtmgvxdxhPn7jgfRY6PplqAqgsfa5FR83sxy5qr2q7xjQTwHtV4MjQVuOjG9JsLw== +"@aws-sdk/core@3.552.0", "@aws-sdk/core@^3.535.0": + version "3.552.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.552.0.tgz#7f744d7cd303d1fa60006d81f75a6f999b64bfb0" + integrity sha512-T7ovljf6fCvIHG9SOSZqGmbVbqZPXPywLAcU+onk/fYLZJj6kjfzKZzSAUBI0nO1OKpuP/nCHaCp51NLWNqsnw== dependencies: - "@smithy/core" "^1.4.0" + "@smithy/core" "^1.4.2" "@smithy/protocol-http" "^3.3.0" - "@smithy/signature-v4" "^2.2.0" - "@smithy/smithy-client" "^2.5.0" + "@smithy/signature-v4" "^2.2.1" + "@smithy/smithy-client" "^2.5.1" "@smithy/types" "^2.12.0" fast-xml-parser "4.2.5" tslib "^2.6.2" -"@aws-sdk/core@3.552.0", "@aws-sdk/core@^3.535.0": - version "3.552.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.552.0.tgz#7f744d7cd303d1fa60006d81f75a6f999b64bfb0" - integrity sha512-T7ovljf6fCvIHG9SOSZqGmbVbqZPXPywLAcU+onk/fYLZJj6kjfzKZzSAUBI0nO1OKpuP/nCHaCp51NLWNqsnw== +"@aws-sdk/core@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.556.0.tgz#d0f4431a72282b71cfbcaedfb803f7f2807cf60b" + integrity sha512-vJaSaHw2kPQlo11j/Rzuz0gk1tEaKdz+2ser0f0qZ5vwFlANjt08m/frU17ctnVKC1s58bxpctO/1P894fHLrA== dependencies: "@smithy/core" "^1.4.2" "@smithy/protocol-http" "^3.3.0" - "@smithy/signature-v4" "^2.2.1" + "@smithy/signature-v4" "^2.3.0" "@smithy/smithy-client" "^2.5.1" "@smithy/types" "^2.12.0" fast-xml-parser "4.2.5" @@ -854,21 +854,6 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-http@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.535.0.tgz#0a42f6b1a61d927bbce9f4afd25112f486bd05da" - integrity sha512-kdj1wCmOMZ29jSlUskRqN04S6fJ4dvt0Nq9Z32SA6wO7UG8ht6Ot9h/au/eTWJM3E1somZ7D771oK7dQt9b8yw== - dependencies: - "@aws-sdk/types" "3.535.0" - "@smithy/fetch-http-handler" "^2.5.0" - "@smithy/node-http-handler" "^2.5.0" - "@smithy/property-provider" "^2.2.0" - "@smithy/protocol-http" "^3.3.0" - "@smithy/smithy-client" "^2.5.0" - "@smithy/types" "^2.12.0" - "@smithy/util-stream" "^2.2.0" - tslib "^2.6.2" - "@aws-sdk/credential-provider-http@3.552.0": version "3.552.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.552.0.tgz#ecc88d02cba95621887e6b85b2583e756ad29eb6" @@ -884,23 +869,6 @@ "@smithy/util-stream" "^2.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-ini@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.535.0.tgz#b121b1aba2916e3f45745cd690b4082421a7c286" - integrity sha512-bm3XOYlyCjtAb8eeHXLrxqRxYVRw2Iqv9IufdJb4gM13TbNSYniUT1WKaHxGIZ5p+FuNlXVhvk1OpHFM13+gXA== - dependencies: - "@aws-sdk/client-sts" "3.535.0" - "@aws-sdk/credential-provider-env" "3.535.0" - "@aws-sdk/credential-provider-process" "3.535.0" - "@aws-sdk/credential-provider-sso" "3.535.0" - "@aws-sdk/credential-provider-web-identity" "3.535.0" - "@aws-sdk/types" "3.535.0" - "@smithy/credential-provider-imds" "^2.3.0" - "@smithy/property-provider" "^2.2.0" - "@smithy/shared-ini-file-loader" "^2.4.0" - "@smithy/types" "^2.12.0" - tslib "^2.6.2" - "@aws-sdk/credential-provider-ini@3.552.0", "@aws-sdk/credential-provider-ini@^3.535.0": version "3.552.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.552.0.tgz#436f328ea0213efe3231354248ab0d82dade4345" @@ -918,17 +886,16 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-node@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.535.0.tgz#6739b4b52a9cce29dc8e70c9a7290b89cdc4b904" - integrity sha512-6JXp/EuL6euUkH5k4d+lQFF6gBwukrcCOWfNHCmq14mNJf/cqT3HAX1VMtWFRSK20am0IxfYQGccb0/nZykdKg== +"@aws-sdk/credential-provider-ini@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.556.0.tgz#bf780feb92a7920cc525cd7cb7870ea61b84c125" + integrity sha512-0Nz4ErOlXhe3muxWYMbPwRMgfKmVbBp36BAE2uv/z5wTbfdBkcgUwaflEvlKCLUTdHzuZsQk+BFS/gVyaUeOuA== dependencies: + "@aws-sdk/client-sts" "3.556.0" "@aws-sdk/credential-provider-env" "3.535.0" - "@aws-sdk/credential-provider-http" "3.535.0" - "@aws-sdk/credential-provider-ini" "3.535.0" "@aws-sdk/credential-provider-process" "3.535.0" - "@aws-sdk/credential-provider-sso" "3.535.0" - "@aws-sdk/credential-provider-web-identity" "3.535.0" + "@aws-sdk/credential-provider-sso" "3.556.0" + "@aws-sdk/credential-provider-web-identity" "3.556.0" "@aws-sdk/types" "3.535.0" "@smithy/credential-provider-imds" "^2.3.0" "@smithy/property-provider" "^2.2.0" @@ -954,24 +921,29 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-process@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.535.0.tgz#ea1e8a38a32e36bbdc3f75eb03352e6eafa0c659" - integrity sha512-9O1OaprGCnlb/kYl8RwmH7Mlg8JREZctB8r9sa1KhSsWFq/SWO0AuJTyowxD7zL5PkeS4eTvzFFHWCa3OO5epA== +"@aws-sdk/credential-provider-node@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.556.0.tgz#51f3dc4506053249f8593765d1ab2cef53732fa3" + integrity sha512-s1xVtKjyGc60O8qcNIzS1X3H+pWEwEfZ7TgNznVDNyuXvLrlNWiAcigPWGl2aAkc8tGcsSG0Qpyw2KYC939LFg== dependencies: + "@aws-sdk/credential-provider-env" "3.535.0" + "@aws-sdk/credential-provider-http" "3.552.0" + "@aws-sdk/credential-provider-ini" "3.556.0" + "@aws-sdk/credential-provider-process" "3.535.0" + "@aws-sdk/credential-provider-sso" "3.556.0" + "@aws-sdk/credential-provider-web-identity" "3.556.0" "@aws-sdk/types" "3.535.0" + "@smithy/credential-provider-imds" "^2.3.0" "@smithy/property-provider" "^2.2.0" "@smithy/shared-ini-file-loader" "^2.4.0" "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-sso@3.535.0": +"@aws-sdk/credential-provider-process@3.535.0": version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.535.0.tgz#dfc7c2f39f9ca965becd7e5b9414cd1bb2217490" - integrity sha512-2Dw0YIr8ETdFpq65CC4zK8ZIEbX78rXoNRZXUGNQW3oSKfL0tj8O8ErY6kg1IdEnYbGnEQ35q6luZ5GGNKLgDg== + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.535.0.tgz#ea1e8a38a32e36bbdc3f75eb03352e6eafa0c659" + integrity sha512-9O1OaprGCnlb/kYl8RwmH7Mlg8JREZctB8r9sa1KhSsWFq/SWO0AuJTyowxD7zL5PkeS4eTvzFFHWCa3OO5epA== dependencies: - "@aws-sdk/client-sso" "3.535.0" - "@aws-sdk/token-providers" "3.535.0" "@aws-sdk/types" "3.535.0" "@smithy/property-provider" "^2.2.0" "@smithy/shared-ini-file-loader" "^2.4.0" @@ -991,14 +963,16 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-web-identity@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.535.0.tgz#f1d3a72ff958cbd7e052c5109755379745ac35e0" - integrity sha512-t2/JWrKY0H66A7JW7CqX06/DG2YkJddikt5ymdQvx/Q7dRMJ3d+o/vgjoKr7RvEx/pNruCeyM1599HCvwrVMrg== +"@aws-sdk/credential-provider-sso@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.556.0.tgz#26dfdd2c6e034f66e82985d65bd6aa3ae09d5e19" + integrity sha512-ETuBgcnpfxqadEAqhQFWpKoV1C/NAgvs5CbBc5EJbelJ8f4prTdErIHjrRtVT8c02MXj92QwczsiNYd5IoOqyw== dependencies: - "@aws-sdk/client-sts" "3.535.0" + "@aws-sdk/client-sso" "3.556.0" + "@aws-sdk/token-providers" "3.556.0" "@aws-sdk/types" "3.535.0" "@smithy/property-provider" "^2.2.0" + "@smithy/shared-ini-file-loader" "^2.4.0" "@smithy/types" "^2.12.0" tslib "^2.6.2" @@ -1013,6 +987,17 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" +"@aws-sdk/credential-provider-web-identity@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.556.0.tgz#94cd55eaee6ca96354237569102dfaf6774544f4" + integrity sha512-R/YAL8Uh8i+dzVjzMnbcWLIGeeRi2mioHVGnVF+minmaIkCiQMZg2HPrdlKm49El+RljT28Nl5YHRuiqzEIwMA== + dependencies: + "@aws-sdk/client-sts" "3.556.0" + "@aws-sdk/types" "3.535.0" + "@smithy/property-provider" "^2.2.0" + "@smithy/types" "^2.12.0" + tslib "^2.6.2" + "@aws-sdk/credential-providers@^3.535.0": version "3.552.0" resolved "https://registry.yarnpkg.com/@aws-sdk/credential-providers/-/credential-providers-3.552.0.tgz#cda713016c555a87dafad8b20bb0c881b4e5469c" @@ -1110,21 +1095,6 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/middleware-sdk-s3@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.535.0.tgz#3cb76342d91a5e0e94d9a380dbaba9a9ee4849e0" - integrity sha512-/dLG/E3af6ohxkQ5GBHT8tZfuPIg6eItKxCXuulvYj0Tqgf3Mb+xTsvSkxQsJF06RS4sH7Qsg/PnB8ZfrJrXpg== - dependencies: - "@aws-sdk/types" "3.535.0" - "@aws-sdk/util-arn-parser" "3.535.0" - "@smithy/node-config-provider" "^2.3.0" - "@smithy/protocol-http" "^3.3.0" - "@smithy/signature-v4" "^2.2.0" - "@smithy/smithy-client" "^2.5.0" - "@smithy/types" "^2.12.0" - "@smithy/util-config-provider" "^2.3.0" - tslib "^2.6.2" - "@aws-sdk/middleware-sdk-s3@3.556.0": version "3.556.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.556.0.tgz#ff135d1fbfc843a93860eb3a4000da9d721442c0" @@ -1140,15 +1110,15 @@ "@smithy/util-config-provider" "^2.3.0" tslib "^2.6.2" -"@aws-sdk/middleware-signing@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.535.0.tgz#cf98354e6d48e275689db6a4a513f62bd1555518" - integrity sha512-Rb4sfus1Gc5paRl9JJgymJGsb/i3gJKK/rTuFZICdd1PBBE5osIOHP5CpzWYBtc5LlyZE1a2QoxPMCyG+QUGPw== +"@aws-sdk/middleware-signing@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-signing/-/middleware-signing-3.556.0.tgz#2892d76cddf3cb956122618588d163ff7a42c43f" + integrity sha512-kWrPmU8qd3gI5qzpuW9LtWFaH80cOz1ZJDavXx6PRpYZJ5JaKdUHghwfDlVTzzFYAeJmVsWIkPcLT5d5mY5ZTQ== dependencies: "@aws-sdk/types" "3.535.0" "@smithy/property-provider" "^2.2.0" "@smithy/protocol-http" "^3.3.0" - "@smithy/signature-v4" "^2.2.0" + "@smithy/signature-v4" "^2.3.0" "@smithy/types" "^2.12.0" "@smithy/util-middleware" "^2.2.0" tslib "^2.6.2" @@ -1162,17 +1132,6 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/middleware-user-agent@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.535.0.tgz#2877ff5e42d943dd0c488e8b1ad82bd9da121227" - integrity sha512-Uvb2WJ+zdHdCOtsWVPI/M0BcfNrjOYsicDZWtaljucRJKLclY5gNWwD+RwIC+8b5TvfnVOlH+N5jhvpi5Impog== - dependencies: - "@aws-sdk/types" "3.535.0" - "@aws-sdk/util-endpoints" "3.535.0" - "@smithy/protocol-http" "^3.3.0" - "@smithy/types" "^2.12.0" - tslib "^2.6.2" - "@aws-sdk/middleware-user-agent@3.540.0": version "3.540.0" resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.540.0.tgz#4981c64c1eeb6b5c453bce02d060b8c71d44994d" @@ -1210,18 +1169,6 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/signature-v4-multi-region@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.535.0.tgz#6a5413ab087d984794e12b04cac5d64c1e37a53f" - integrity sha512-tqCsEsEj8icW0SAh3NvyhRUq54Gz2pu4NM2tOSrFp7SO55heUUaRLSzYteNZCTOupH//AAaZvbN/UUTO/DrOog== - dependencies: - "@aws-sdk/middleware-sdk-s3" "3.535.0" - "@aws-sdk/types" "3.535.0" - "@smithy/protocol-http" "^3.3.0" - "@smithy/signature-v4" "^2.2.0" - "@smithy/types" "^2.12.0" - tslib "^2.6.2" - "@aws-sdk/signature-v4-multi-region@3.556.0": version "3.556.0" resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.556.0.tgz#34ff26a1617b885a845752e62aca7bc29deb33ac" @@ -1234,24 +1181,24 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/token-providers@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.535.0.tgz#0d5aa221449d5b56730427b28d3319005c5700ed" - integrity sha512-4g+l/B9h1H/SiDtFRosW3pMwc+3PTXljZit+5NUBcET2XqcdUyHmgj3lBdu+CJ9CHdIMggRalYMAFXnRFe3Psg== +"@aws-sdk/token-providers@3.552.0": + version "3.552.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.552.0.tgz#e0cfbeb1ff9fb212ab214f2ade9827e1032fdf42" + integrity sha512-5dNE2KqtgkT+DQXfkSmzmVSB72LpjSIK86lLD9LeQ1T+b0gfEd74MAl/AGC15kQdKLg5I3LlN5q32f1fkmYR8g== dependencies: - "@aws-sdk/client-sso-oidc" "3.535.0" + "@aws-sdk/client-sso-oidc" "3.552.0" "@aws-sdk/types" "3.535.0" "@smithy/property-provider" "^2.2.0" "@smithy/shared-ini-file-loader" "^2.4.0" "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/token-providers@3.552.0": - version "3.552.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.552.0.tgz#e0cfbeb1ff9fb212ab214f2ade9827e1032fdf42" - integrity sha512-5dNE2KqtgkT+DQXfkSmzmVSB72LpjSIK86lLD9LeQ1T+b0gfEd74MAl/AGC15kQdKLg5I3LlN5q32f1fkmYR8g== +"@aws-sdk/token-providers@3.556.0": + version "3.556.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.556.0.tgz#96b4dd4fec67ae62f8c98ae8c2f94e4ed050073a" + integrity sha512-tvIiugNF0/+2wfuImMrpKjXMx4nCnFWQjQvouObny+wrif/PGqqQYrybwxPJDvzbd965bu1I+QuSv85/ug7xsg== dependencies: - "@aws-sdk/client-sso-oidc" "3.552.0" + "@aws-sdk/client-sso-oidc" "3.556.0" "@aws-sdk/types" "3.535.0" "@smithy/property-provider" "^2.2.0" "@smithy/shared-ini-file-loader" "^2.4.0" @@ -1281,16 +1228,6 @@ dependencies: tslib "^2.6.2" -"@aws-sdk/util-endpoints@3.535.0": - version "3.535.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.535.0.tgz#46f4b61b2661d6414ded8c98e4ad3c82a0bf597b" - integrity sha512-c8TlaQsiPchOOmTTR6qvHCO2O7L7NJwlKWAoQJ2GqWDZuC5es/fyuF2rp1h+ZRrUVraUomS0YdGkAmaDC7hJQg== - dependencies: - "@aws-sdk/types" "3.535.0" - "@smithy/types" "^2.12.0" - "@smithy/util-endpoints" "^1.2.0" - tslib "^2.6.2" - "@aws-sdk/util-endpoints@3.540.0": version "3.540.0" resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.540.0.tgz#a7fea1d2a5e64623353aaa6ee32dbb86ab9cd3f8" @@ -4980,10 +4917,10 @@ resolved "https://registry.yarnpkg.com/@mattkrick/sanitize-svg/-/sanitize-svg-0.4.0.tgz#388c29614cf72aa0dd9803c77c9c9d070bd3cd2d" integrity sha512-TnPI97WVAxo8SQcPy8aV3OF9/2WjXB5/+pRNVudIWR7Bhi5ZjtR/ur162So08GkvsvB914AXCW2sxFh1x6KhHA== -"@mattkrick/trebuchet-client@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@mattkrick/trebuchet-client/-/trebuchet-client-3.0.2.tgz#336d687256fb9ac7bb407f656bf2f69f35f817e1" - integrity sha512-JLOx8gd+cGkDeHhdnns0oor2UNv5uRZ8A/Jfw3NhQcVqQe6R+x9xIHW29M2T78TDHUWqItTgntX+cdDLqVjVvg== +"@mattkrick/trebuchet-client@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@mattkrick/trebuchet-client/-/trebuchet-client-3.0.1.tgz#3fc49f7858652a55dca92cb0c14c0313df931619" + integrity sha512-5uHCldCqmVntoyujTzRfmGtjld8k4JuBdFN0SvhvRFf83FPaNeoit6Mh8VgrcxxxKujKeYCQDMQH6LWwpsshgQ== dependencies: "@mattkrick/fast-rtc-peer" "^0.4.1" eventemitter3 "^4.0.7" @@ -6707,7 +6644,7 @@ "@smithy/util-middleware" "^2.2.0" tslib "^2.6.2" -"@smithy/core@^1.4.0", "@smithy/core@^1.4.2": +"@smithy/core@^1.4.2": version "1.4.2" resolved "https://registry.yarnpkg.com/@smithy/core/-/core-1.4.2.tgz#1c3ed886d403041ce5bd2d816448420c57baa19c" integrity sha512-2fek3I0KZHWJlRLvRTqxTEri+qV0GRHrJIoLFuBMZB4EMg4WgeBGfF0X6abnrNYpq55KJ6R4D6x4f0vLnhzinA== @@ -6850,7 +6787,7 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@smithy/middleware-endpoint@^2.5.0", "@smithy/middleware-endpoint@^2.5.1": +"@smithy/middleware-endpoint@^2.5.1": version "2.5.1" resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-2.5.1.tgz#1333c58304aff4d843e8ef4b85c8cb88975dd5ad" integrity sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ== @@ -6863,7 +6800,7 @@ "@smithy/util-middleware" "^2.2.0" tslib "^2.6.2" -"@smithy/middleware-retry@^2.2.0", "@smithy/middleware-retry@^2.3.1": +"@smithy/middleware-retry@^2.3.1": version "2.3.1" resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-2.3.1.tgz#d6fdce94f2f826642c01b4448e97a509c4556ede" integrity sha512-P2bGufFpFdYcWvqpyqqmalRtwFUNUA8vHjJR5iGqbfR6mp65qKOLcUd6lTr4S9Gn/enynSrSf3p3FVgVAf6bXA== @@ -6978,10 +6915,10 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@smithy/signature-v4@^2.2.0", "@smithy/signature-v4@^2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.3.0.tgz#c30dd4028ae50c607db99459981cce8cdab7a3fd" - integrity sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q== +"@smithy/signature-v4@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.2.1.tgz#9b32571e9785c8f69aa4115517bf2a784f690c4d" + integrity sha512-j5fHgL1iqKTsKJ1mTcw88p0RUcidDu95AWSeZTgiYJb+QcfwWU/UpBnaqiB59FNH5MiAZuSbOBnZlwzeeY2tIw== dependencies: "@smithy/is-array-buffer" "^2.2.0" "@smithy/types" "^2.12.0" @@ -6991,10 +6928,10 @@ "@smithy/util-utf8" "^2.3.0" tslib "^2.6.2" -"@smithy/signature-v4@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.2.1.tgz#9b32571e9785c8f69aa4115517bf2a784f690c4d" - integrity sha512-j5fHgL1iqKTsKJ1mTcw88p0RUcidDu95AWSeZTgiYJb+QcfwWU/UpBnaqiB59FNH5MiAZuSbOBnZlwzeeY2tIw== +"@smithy/signature-v4@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-2.3.0.tgz#c30dd4028ae50c607db99459981cce8cdab7a3fd" + integrity sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q== dependencies: "@smithy/is-array-buffer" "^2.2.0" "@smithy/types" "^2.12.0" @@ -7004,7 +6941,7 @@ "@smithy/util-utf8" "^2.3.0" tslib "^2.6.2" -"@smithy/smithy-client@^2.5.0", "@smithy/smithy-client@^2.5.1": +"@smithy/smithy-client@^2.5.1": version "2.5.1" resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-2.5.1.tgz#0fd2efff09dc65500d260e590f7541f8a387eae3" integrity sha512-jrbSQrYCho0yDaaf92qWgd+7nAeap5LtHTI51KXqmpIFCceKU3K9+vIVTUH72bOJngBMqa4kyu1VJhRcSrk/CQ== @@ -7077,7 +7014,7 @@ dependencies: tslib "^2.6.2" -"@smithy/util-defaults-mode-browser@^2.2.0", "@smithy/util-defaults-mode-browser@^2.2.1": +"@smithy/util-defaults-mode-browser@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.2.1.tgz#9db31416daf575d2963c502e0528cfe8055f0c4e" integrity sha512-RtKW+8j8skk17SYowucwRUjeh4mCtnm5odCL0Lm2NtHQBsYKrNW0od9Rhopu9wF1gHMfHeWF7i90NwBz/U22Kw== @@ -7088,7 +7025,7 @@ bowser "^2.11.0" tslib "^2.6.2" -"@smithy/util-defaults-mode-node@^2.3.0", "@smithy/util-defaults-mode-node@^2.3.1": +"@smithy/util-defaults-mode-node@^2.3.1": version "2.3.1" resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.3.1.tgz#4613210a3d107aadb3f85bd80cb71c796dd8bf0a" integrity sha512-vkMXHQ0BcLFysBMWgSBLSk3+leMpFSyyFj8zQtv5ZyUBx8/owVh1/pPEkzmW/DR/Gy/5c8vjLDD9gZjXNKbrpA== @@ -20311,7 +20248,7 @@ string-similarity@^3.0.0: resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-3.0.0.tgz#07b0bc69fae200ad88ceef4983878d03793847c7" integrity sha512-7kS7LyTp56OqOI2BDWQNVnLX/rCxIQn+/5M0op1WV6P8Xx6TZNdajpuqQdiJ7Xx+p1C5CsWMvdiBp9ApMhxzEQ== -"string-width-cjs@npm:string-width@^4.2.0": +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -20329,15 +20266,6 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.0.tgz#5ab00980cfb29f43e736b113a120a73a0fb569d3" @@ -20414,7 +20342,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -20428,13 +20356,6 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" @@ -22287,7 +22208,7 @@ workbox-window@6.5.4: "@types/trusted-types" "^2.0.2" workbox-core "6.5.4" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -22305,15 +22226,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"