From 059c552307a0fe091a35caebc66e49a9cac6ad3f Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Thu, 10 Oct 2024 03:22:25 +0800 Subject: [PATCH 01/54] misc: initial setup for github integration with Github app auth --- .env.example | 3 + backend/src/lib/config/env.ts | 7 +- .../routes/v1/integration-auth-router.ts | 1 + .../integration-auth-service.ts | 15 ++- .../integration-auth-types.ts | 1 + .../integration-auth/integration-list.ts | 5 +- .../integration-auth/integration-token.ts | 77 ++++++++++- .../src/hooks/api/integrationAuth/queries.tsx | 3 + .../src/hooks/api/integrationAuth/types.ts | 3 + .../github/auth-mode-selection.tsx | 89 +++++++++++++ .../integrations/github/oauth2/callback.tsx | 9 +- .../integrations/select-integration-auth.tsx | 121 ++++++++++++++++++ .../IntegrationPage.utils.tsx | 2 +- 13 files changed, 323 insertions(+), 13 deletions(-) create mode 100644 frontend/src/pages/integrations/github/auth-mode-selection.tsx create mode 100644 frontend/src/pages/integrations/select-integration-auth.tsx diff --git a/.env.example b/.env.example index be7e0a621..6c76a75fd 100644 --- a/.env.example +++ b/.env.example @@ -36,12 +36,15 @@ CLIENT_ID_HEROKU= CLIENT_ID_VERCEL= CLIENT_ID_NETLIFY= CLIENT_ID_GITHUB= +CLIENT_ID_GITHUB_APP= +CLIENT_SLUG_GITHUB= CLIENT_ID_GITLAB= CLIENT_ID_BITBUCKET= CLIENT_SECRET_HEROKU= CLIENT_SECRET_VERCEL= CLIENT_SECRET_NETLIFY= CLIENT_SECRET_GITHUB= +CLIENT_SECRET_GITHUB_APP= CLIENT_SECRET_GITLAB= CLIENT_SECRET_BITBUCKET= CLIENT_SLUG_VERCEL= diff --git a/backend/src/lib/config/env.ts b/backend/src/lib/config/env.ts index b047de755..a11762564 100644 --- a/backend/src/lib/config/env.ts +++ b/backend/src/lib/config/env.ts @@ -117,9 +117,14 @@ const envSchema = z // gcp secret manager CLIENT_ID_GCP_SECRET_MANAGER: zpStr(z.string().optional()), CLIENT_SECRET_GCP_SECRET_MANAGER: zpStr(z.string().optional()), - // github + // github oauth CLIENT_ID_GITHUB: zpStr(z.string().optional()), CLIENT_SECRET_GITHUB: zpStr(z.string().optional()), + CLIENT_SLUG_GITHUB: zpStr(z.string().optional()), + // github app + CLIENT_ID_GITHUB_APP: zpStr(z.string().optional()), + CLIENT_SECRET_GITHUB_APP: zpStr(z.string().optional()), + // azure CLIENT_ID_AZURE: zpStr(z.string().optional()), CLIENT_SECRET_AZURE: zpStr(z.string().optional()), diff --git a/backend/src/server/routes/v1/integration-auth-router.ts b/backend/src/server/routes/v1/integration-auth-router.ts index 4baa39f76..1e6a88129 100644 --- a/backend/src/server/routes/v1/integration-auth-router.ts +++ b/backend/src/server/routes/v1/integration-auth-router.ts @@ -189,6 +189,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider) workspaceId: z.string().trim(), code: z.string().trim(), integration: z.string().trim(), + installationId: z.string().trim().optional(), url: z.string().trim().url().optional() }), response: { diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index c3e0dfe06..83e880b3e 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -109,7 +109,8 @@ export const integrationAuthServiceFactory = ({ actorAuthMethod, integration, url, - code + code, + installationId }: TOauthExchangeDTO) => { if (!Object.values(Integrations).includes(integration as Integrations)) throw new BadRequestError({ message: "Invalid integration" }); @@ -123,7 +124,7 @@ export const integrationAuthServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); - const tokenExchange = await exchangeCode({ integration, code, url }); + const tokenExchange = await exchangeCode({ integration, code, url, installationId }); const updateDoc: TIntegrationAuthsInsert = { projectId, integration, @@ -141,6 +142,16 @@ export const integrationAuthServiceFactory = ({ updateDoc.metadata = { authMethod: "oauth2" }; + } else if (integration === Integrations.GITHUB && installationId) { + updateDoc.metadata = { + installationId, + installationName: tokenExchange.installationName, + authMethod: "app" + }; + } + + if (installationId && integration === Integrations.GITHUB) { + return integrationAuthDAL.create(updateDoc); } const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(projectId); diff --git a/backend/src/services/integration-auth/integration-auth-types.ts b/backend/src/services/integration-auth/integration-auth-types.ts index af390297a..b8afe5ecb 100644 --- a/backend/src/services/integration-auth/integration-auth-types.ts +++ b/backend/src/services/integration-auth/integration-auth-types.ts @@ -9,6 +9,7 @@ export type TOauthExchangeDTO = { integration: string; code: string; url?: string; + installationId?: string; } & TProjectPermission; export type TSaveIntegrationAccessTokenDTO = { diff --git a/backend/src/services/integration-auth/integration-list.ts b/backend/src/services/integration-auth/integration-list.ts index ef6d0160e..8019ae9b8 100644 --- a/backend/src/services/integration-auth/integration-list.ts +++ b/backend/src/services/integration-auth/integration-list.ts @@ -96,7 +96,9 @@ export enum IntegrationUrls { GCP_SECRET_MANAGER_SERVICE_NAME = "secretmanager.googleapis.com", GCP_SECRET_MANAGER_URL = `https://${GCP_SECRET_MANAGER_SERVICE_NAME}`, GCP_SERVICE_USAGE_URL = "https://serviceusage.googleapis.com", - GCP_CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform" + GCP_CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform", + + GITHUB_USER_INSTALLATIONS = "https://api.github.com/user/installations" } export const getIntegrationOptions = async () => { @@ -138,6 +140,7 @@ export const getIntegrationOptions = async () => { isAvailable: true, type: "oauth", clientId: appCfg.CLIENT_ID_GITHUB, + clientSlug: appCfg.CLIENT_SLUG_GITHUB, docsLink: "" }, { diff --git a/backend/src/services/integration-auth/integration-token.ts b/backend/src/services/integration-auth/integration-token.ts index ba26a3aaa..6daacd62a 100644 --- a/backend/src/services/integration-auth/integration-token.ts +++ b/backend/src/services/integration-auth/integration-token.ts @@ -2,7 +2,7 @@ import jwt from "jsonwebtoken"; import { getConfig } from "@app/lib/config/env"; import { request } from "@app/lib/config/request"; -import { BadRequestError, NotFoundError } from "@app/lib/errors"; +import { BadRequestError, ForbiddenRequestError, InternalServerError, NotFoundError } from "@app/lib/errors"; import { Integrations, IntegrationUrls } from "./integration-list"; @@ -234,12 +234,73 @@ const exchangeCodeNetlify = async ({ code }: { code: string }) => { }; }; -const exchangeCodeGithub = async ({ code }: { code: string }) => { +const exchangeCodeGithub = async ({ code, installationId }: { code: string; installationId?: string }) => { const appCfg = getConfig(); - if (!appCfg.CLIENT_ID_GITHUB || !appCfg.CLIENT_SECRET_GITHUB) { - throw new BadRequestError({ message: "Missing client id and client secret" }); + + if (!installationId && (!appCfg.CLIENT_ID_GITHUB || !appCfg.CLIENT_SECRET_GITHUB)) { + throw new InternalServerError({ message: "Missing client id and client secret" }); } + if (installationId && (!appCfg.CLIENT_ID_GITHUB_APP || !appCfg.CLIENT_SECRET_GITHUB_APP)) { + throw new InternalServerError({ + message: "Missing Github app client ID and client secret" + }); + } + + if (installationId) { + // handle app installations + const res = ( + await request.get(IntegrationUrls.GITHUB_TOKEN_URL, { + params: { + client_id: appCfg.CLIENT_ID_GITHUB_APP, + client_secret: appCfg.CLIENT_SECRET_GITHUB_APP, + code, + redirect_uri: `${appCfg.SITE_URL}/integrations/github/oauth2/callback` + }, + headers: { + Accept: "application/json", + "Accept-Encoding": "application/json" + } + }) + ).data; + + // use access token to validate installation ID + const installationsRes = ( + await request.get<{ + installations: { + id: number; + account: { + login: string; + }; + }[]; + }>(IntegrationUrls.GITHUB_USER_INSTALLATIONS, { + headers: { + Accept: "application/json", + Authorization: `Bearer ${res.access_token}`, + "Accept-Encoding": "application/json" + } + }) + ).data; + + const matchingInstallation = installationsRes.installations.find( + (installation) => installation.id === +installationId + ); + + if (!matchingInstallation) { + throw new ForbiddenRequestError({ + message: "User has no access to the provided installation" + }); + } + + return { + accessToken: "", + refreshToken: null, + accessExpiresAt: null, + installationName: matchingInstallation.account.login + }; + } + + // handle normal oauth const res = ( await request.get(IntegrationUrls.GITHUB_TOKEN_URL, { params: { @@ -346,6 +407,7 @@ type TExchangeReturn = { url?: string; teamId?: string; accountId?: string; + installationName?: string; }; /** @@ -355,11 +417,13 @@ type TExchangeReturn = { export const exchangeCode = async ({ integration, code, - url + url, + installationId }: { integration: string; code: string; url?: string; + installationId?: string; }): Promise => { switch (integration) { case Integrations.GCP_SECRET_MANAGER: @@ -384,7 +448,8 @@ export const exchangeCode = async ({ }); case Integrations.GITHUB: return exchangeCodeGithub({ - code + code, + installationId }); case Integrations.GITLAB: return exchangeCodeGitlab({ diff --git a/frontend/src/hooks/api/integrationAuth/queries.tsx b/frontend/src/hooks/api/integrationAuth/queries.tsx index 914c3a71c..6688f9a99 100644 --- a/frontend/src/hooks/api/integrationAuth/queries.tsx +++ b/frontend/src/hooks/api/integrationAuth/queries.tsx @@ -777,11 +777,13 @@ export const useAuthorizeIntegration = () => { workspaceId, code, integration, + installationId, url }: { workspaceId: string; code: string; integration: string; + installationId?: string; url?: string; }) => { const { @@ -790,6 +792,7 @@ export const useAuthorizeIntegration = () => { workspaceId, code, integration, + installationId, url }); diff --git a/frontend/src/hooks/api/integrationAuth/types.ts b/frontend/src/hooks/api/integrationAuth/types.ts index b73528384..a32dab8ce 100644 --- a/frontend/src/hooks/api/integrationAuth/types.ts +++ b/frontend/src/hooks/api/integrationAuth/types.ts @@ -9,6 +9,9 @@ export type IntegrationAuth = { keyEncoding: string; url?: string; teamId?: string; + metadata: { + installationName?: string; + }; }; export type App = { diff --git a/frontend/src/pages/integrations/github/auth-mode-selection.tsx b/frontend/src/pages/integrations/github/auth-mode-selection.tsx new file mode 100644 index 000000000..5426cd562 --- /dev/null +++ b/frontend/src/pages/integrations/github/auth-mode-selection.tsx @@ -0,0 +1,89 @@ +import crypto from "crypto"; + +import Head from "next/head"; +import Image from "next/image"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +import { Button, Card, CardTitle } from "@app/components/v2"; +import { useGetCloudIntegrations } from "@app/hooks/api"; + +export default function GithubIntegrationAuthModeSelectionPage() { + const router = useRouter(); + const { data: cloudIntegrations } = useGetCloudIntegrations(); + const githubIntegration = cloudIntegrations?.find((integration) => integration.slug === "github"); + + return ( +
+ + Select Github Integration Auth + + + + +
+
+ Github logo +
+ Github Integration + + +
+ + Docs + +
+
+ +
+
+
+ + +
+
+
+ ); +} + +GithubIntegrationAuthModeSelectionPage.requireAuth = true; diff --git a/frontend/src/pages/integrations/github/oauth2/callback.tsx b/frontend/src/pages/integrations/github/oauth2/callback.tsx index c60338283..0ea8b20f7 100644 --- a/frontend/src/pages/integrations/github/oauth2/callback.tsx +++ b/frontend/src/pages/integrations/github/oauth2/callback.tsx @@ -8,18 +8,23 @@ export default function GitHubOAuth2CallbackPage() { const router = useRouter(); const { mutateAsync } = useAuthorizeIntegration(); - const { code, state } = queryString.parse(router.asPath.split("?")[1]); + // eslint-disable-next-line @typescript-eslint/naming-convention + const { code, state, installation_id } = queryString.parse(router.asPath.split("?")[1]); useEffect(() => { (async () => { try { // validate state - if (state !== localStorage.getItem("latestCSRFToken")) return; + if (state !== localStorage.getItem("latestCSRFToken")) { + return; + } + localStorage.removeItem("latestCSRFToken"); const integrationAuth = await mutateAsync({ workspaceId: localStorage.getItem("projectData.id") as string, code: code as string, + installationId: installation_id as string, integration: "github" }); diff --git a/frontend/src/pages/integrations/select-integration-auth.tsx b/frontend/src/pages/integrations/select-integration-auth.tsx new file mode 100644 index 000000000..bb55fc01c --- /dev/null +++ b/frontend/src/pages/integrations/select-integration-auth.tsx @@ -0,0 +1,121 @@ +import crypto from "crypto"; + +import { useCallback } from "react"; +import Head from "next/head"; +import Image from "next/image"; +import { useRouter } from "next/router"; + +import { Button, Card, CardTitle } from "@app/components/v2"; +import { useWorkspace } from "@app/context"; +import { useGetCloudIntegrations, useGetWorkspaceAuthorizations } from "@app/hooks/api"; +import { IntegrationAuth } from "@app/hooks/api/types"; + +export default function SelectIntegrationAuthPage() { + const router = useRouter(); + const { data: cloudIntegrations } = useGetCloudIntegrations(); + const { currentWorkspace } = useWorkspace(); + const workspaceId = currentWorkspace?.id || ""; + + const integrationSlug = router.query.integrationSlug as string; + + const currentIntegration = cloudIntegrations?.find( + (integration) => integration.slug === integrationSlug + ); + + const { data: integrationAuths, isLoading: isLoadingIntegrationAuths } = + useGetWorkspaceAuthorizations( + workspaceId, + useCallback((data: IntegrationAuth[]) => { + const filteredIntegrationAuths = data.filter( + (integrationAuth) => integrationAuth.integration === integrationSlug + ); + + if (integrationSlug === "github") { + // for now, we only display the integration auths for Github apps + return filteredIntegrationAuths.filter((integrationAuth) => + Boolean(integrationAuth.metadata?.installationName) + ); + } + + return []; + }, []) + ); + + const logo = integrationSlug === "github" ? "/images/integrations/GitHub.png" : ""; + + const handleConnectionSelect = (integrationAuthId: string) => { + if (integrationSlug === "github") { + router.push(`/integrations/github/create?integrationAuthId=${integrationAuthId}`); + } + }; + + const handleNewConnection = () => { + const state = crypto.randomBytes(16).toString("hex"); + localStorage.setItem("latestCSRFToken", state); + + if (integrationSlug === "github") { + // for now we only handle Github apps + window.location.assign( + `https://github.com/apps/${currentIntegration?.clientSlug}/installations/new?state=${state}` + ); + } + }; + + return ( +
+ + Select Connection + + + + +
+
+ Integration logo +
+ Select Connection +
+
+
+ {!isLoadingIntegrationAuths && integrationAuths?.length + ? integrationAuths.map((integrationAuth) => { + let connectionName = ""; + + if (integrationAuth.integration === "github") { + connectionName = integrationAuth.metadata?.installationName || ""; + } + + return ( + + ); + }) + : undefined} + +
+
+
+ ); +} + +SelectIntegrationAuthPage.requireAuth = true; diff --git a/frontend/src/views/IntegrationsPage/IntegrationPage.utils.tsx b/frontend/src/views/IntegrationsPage/IntegrationPage.utils.tsx index 18b9022ca..be7366259 100644 --- a/frontend/src/views/IntegrationsPage/IntegrationPage.utils.tsx +++ b/frontend/src/views/IntegrationsPage/IntegrationPage.utils.tsx @@ -60,7 +60,7 @@ export const redirectForProviderAuth = (integrationOption: TCloudIntegration) => link = `https://app.netlify.com/authorize?client_id=${integrationOption.clientId}&response_type=code&state=${state}&redirect_uri=${window.location.origin}/integrations/netlify/oauth2/callback`; break; case "github": - link = `https://github.com/login/oauth/authorize?client_id=${integrationOption.clientId}&response_type=code&scope=repo,admin:org&redirect_uri=${window.location.origin}/integrations/github/oauth2/callback&state=${state}`; + link = `${window.location.origin}/integrations/github/auth-mode-selection`; break; case "gitlab": link = `${window.location.origin}/integrations/gitlab/authorize`; From b8f3814df01723079d0cc627c3f574d2f2b760d8 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Mon, 14 Oct 2024 16:17:39 +0800 Subject: [PATCH 02/54] feat: added support for app octokit --- .env.example | 3 + backend/package-lock.json | 573 ++++++++++++++++-- backend/package.json | 1 + backend/src/lib/config/env.ts | 2 + .../integration-auth/integration-app-list.ts | 39 +- .../integration-auth-schema.ts | 7 + .../integration-auth-service.ts | 76 ++- .../integration-delete-secret.ts | 28 +- .../integration-sync-secret.ts | 26 +- .../integration/integration-service.ts | 22 +- 10 files changed, 676 insertions(+), 101 deletions(-) create mode 100644 backend/src/services/integration-auth/integration-auth-schema.ts diff --git a/.env.example b/.env.example index 6c76a75fd..929278081 100644 --- a/.env.example +++ b/.env.example @@ -49,6 +49,9 @@ CLIENT_SECRET_GITLAB= CLIENT_SECRET_BITBUCKET= CLIENT_SLUG_VERCEL= +GITHUB_APP_PRIVATE_KEY= +GITHUB_APP_ID= + # Sentry (optional) for monitoring errors SENTRY_DSN= diff --git a/backend/package-lock.json b/backend/package-lock.json index 847eb2ba6..62ac1d209 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -27,6 +27,7 @@ "@fastify/swagger": "^8.14.0", "@fastify/swagger-ui": "^2.1.0", "@node-saml/passport-saml": "^4.0.4", + "@octokit/auth-app": "^7.1.1", "@octokit/plugin-retry": "^5.0.5", "@octokit/rest": "^20.0.2", "@octokit/webhooks-types": "^7.3.1", @@ -4976,24 +4977,73 @@ } }, "node_modules/@octokit/auth-app": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.0.3.tgz", - "integrity": "sha512-9N7IlBAKEJR3tJgPSubCxIDYGXSdc+2xbkjYpk9nCyqREnH8qEMoMhiEB1WgoA9yTFp91El92XNXAi+AjuKnfw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-7.1.1.tgz", + "integrity": "sha512-kRAd6yelV9OgvlEJE88H0VLlQdZcag9UlLr7dV0YYP37X8PPDvhgiTy66QVhDXdyoT0AleFN2w/qXkPdrSzINg==", "dependencies": { - "@octokit/auth-oauth-app": "^7.0.0", - "@octokit/auth-oauth-user": "^4.0.0", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "deprecation": "^2.3.1", + "@octokit/auth-oauth-app": "^8.1.0", + "@octokit/auth-oauth-user": "^5.1.0", + "@octokit/request": "^9.1.1", + "@octokit/request-error": "^6.1.1", + "@octokit/types": "^13.4.1", "lru-cache": "^10.0.0", - "universal-github-app-jwt": "^1.1.2", - "universal-user-agent": "^6.0.0" + "universal-github-app-jwt": "^2.2.0", + "universal-user-agent": "^7.0.0" }, "engines": { "node": ">= 18" } }, + "node_modules/@octokit/auth-app/node_modules/@octokit/endpoint": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz", + "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==", + "dependencies": { + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-app/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" + }, + "node_modules/@octokit/auth-app/node_modules/@octokit/request": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.3.tgz", + "integrity": "sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==", + "dependencies": { + "@octokit/endpoint": "^10.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-app/node_modules/@octokit/request-error": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.5.tgz", + "integrity": "sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==", + "dependencies": { + "@octokit/types": "^13.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-app/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, "node_modules/@octokit/auth-app/node_modules/lru-cache": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", @@ -5002,53 +5052,220 @@ "node": "14 || >=16.14" } }, + "node_modules/@octokit/auth-app/node_modules/universal-user-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==" + }, "node_modules/@octokit/auth-oauth-app": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.0.1.tgz", - "integrity": "sha512-RE0KK0DCjCHXHlQBoubwlLijXEKfhMhKm9gO56xYvFmP1QTMb+vvwRPmQLLx0V+5AvV9N9I3lr1WyTzwL3rMDg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-8.1.1.tgz", + "integrity": "sha512-5UtmxXAvU2wfcHIPPDWzVSAWXVJzG3NWsxb7zCFplCWEmMCArSZV0UQu5jw5goLQXbFyOr5onzEH37UJB3zQQg==", "dependencies": { - "@octokit/auth-oauth-device": "^6.0.0", - "@octokit/auth-oauth-user": "^4.0.0", - "@octokit/request": "^8.0.2", - "@octokit/types": "^12.0.0", - "@types/btoa-lite": "^1.0.0", - "btoa-lite": "^1.0.0", - "universal-user-agent": "^6.0.0" + "@octokit/auth-oauth-device": "^7.0.0", + "@octokit/auth-oauth-user": "^5.0.1", + "@octokit/request": "^9.0.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.0" }, "engines": { "node": ">= 18" } }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/endpoint": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz", + "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==", + "dependencies": { + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/request": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.3.tgz", + "integrity": "sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==", + "dependencies": { + "@octokit/endpoint": "^10.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/request-error": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.5.tgz", + "integrity": "sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==", + "dependencies": { + "@octokit/types": "^13.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@octokit/auth-oauth-app/node_modules/universal-user-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==" + }, "node_modules/@octokit/auth-oauth-device": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.0.1.tgz", - "integrity": "sha512-yxU0rkL65QkjbqQedgVx3gmW7YM5fF+r5uaSj9tM/cQGVqloXcqP2xK90eTyYvl29arFVCW8Vz4H/t47mL0ELw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-7.1.1.tgz", + "integrity": "sha512-HWl8lYueHonuyjrKKIup/1tiy0xcmQCdq5ikvMO1YwkNNkxb6DXfrPjrMYItNLyCP/o2H87WuijuE+SlBTT8eg==", "dependencies": { - "@octokit/oauth-methods": "^4.0.0", - "@octokit/request": "^8.0.0", - "@octokit/types": "^12.0.0", - "universal-user-agent": "^6.0.0" + "@octokit/oauth-methods": "^5.0.0", + "@octokit/request": "^9.0.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.0" }, "engines": { "node": ">= 18" } }, - "node_modules/@octokit/auth-oauth-user": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.0.1.tgz", - "integrity": "sha512-N94wWW09d0hleCnrO5wt5MxekatqEJ4zf+1vSe8MKMrhZ7gAXKFOKrDEZW2INltvBWJCyDUELgGRv8gfErH1Iw==", + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/endpoint": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz", + "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==", "dependencies": { - "@octokit/auth-oauth-device": "^6.0.0", - "@octokit/oauth-methods": "^4.0.0", - "@octokit/request": "^8.0.2", - "@octokit/types": "^12.0.0", - "btoa-lite": "^1.0.0", - "universal-user-agent": "^6.0.0" + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.2" }, "engines": { "node": ">= 18" } }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" + }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/request": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.3.tgz", + "integrity": "sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==", + "dependencies": { + "@octokit/endpoint": "^10.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/request-error": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.5.tgz", + "integrity": "sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==", + "dependencies": { + "@octokit/types": "^13.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@octokit/auth-oauth-device/node_modules/universal-user-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==" + }, + "node_modules/@octokit/auth-oauth-user": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-5.1.1.tgz", + "integrity": "sha512-rRkMz0ErOppdvEfnemHJXgZ9vTPhBuC6yASeFaB7I2yLMd7QpjfrL1mnvRPlyKo+M6eeLxrKanXJ9Qte29SRsw==", + "dependencies": { + "@octokit/auth-oauth-device": "^7.0.1", + "@octokit/oauth-methods": "^5.0.0", + "@octokit/request": "^9.0.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/endpoint": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz", + "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==", + "dependencies": { + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/request": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.3.tgz", + "integrity": "sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==", + "dependencies": { + "@octokit/endpoint": "^10.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/request-error": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.5.tgz", + "integrity": "sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==", + "dependencies": { + "@octokit/types": "^13.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@octokit/auth-oauth-user/node_modules/universal-user-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==" + }, "node_modules/@octokit/auth-token": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", @@ -5112,28 +5329,82 @@ } }, "node_modules/@octokit/oauth-authorization-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz", - "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-7.1.1.tgz", + "integrity": "sha512-ooXV8GBSabSWyhLUowlMIVd9l1s2nsOGQdlP2SQ4LnkEsGXzeCvbSbCPdZThXhEFzleGPwbapT0Sb+YhXRyjCA==", "engines": { "node": ">= 18" } }, "node_modules/@octokit/oauth-methods": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-4.0.1.tgz", - "integrity": "sha512-1NdTGCoBHyD6J0n2WGXg9+yDLZrRNZ0moTEex/LSPr49m530WNKcCfXDghofYptr3st3eTii+EHoG5k/o+vbtw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-5.1.2.tgz", + "integrity": "sha512-C5lglRD+sBlbrhCUTxgJAFjWgJlmTx5bQ7Ch0+2uqRjYv7Cfb5xpX4WuSC9UgQna3sqRGBL9EImX9PvTpMaQ7g==", "dependencies": { - "@octokit/oauth-authorization-url": "^6.0.2", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "btoa-lite": "^1.0.0" + "@octokit/oauth-authorization-url": "^7.0.0", + "@octokit/request": "^9.1.0", + "@octokit/request-error": "^6.1.0", + "@octokit/types": "^13.0.0" }, "engines": { "node": ">= 18" } }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/endpoint": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz", + "integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==", + "dependencies": { + "@octokit/types": "^13.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/request": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.3.tgz", + "integrity": "sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==", + "dependencies": { + "@octokit/endpoint": "^10.0.0", + "@octokit/request-error": "^6.0.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/request-error": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.5.tgz", + "integrity": "sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==", + "dependencies": { + "@octokit/types": "^13.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@octokit/oauth-methods/node_modules/universal-user-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz", + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==" + }, "node_modules/@octokit/openapi-types": { "version": "19.1.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz", @@ -5248,13 +5519,13 @@ } }, "node_modules/@octokit/request": { - "version": "8.1.6", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz", - "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", + "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", "dependencies": { - "@octokit/endpoint": "^9.0.0", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", + "@octokit/endpoint": "^9.0.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", "universal-user-agent": "^6.0.0" }, "engines": { @@ -5262,11 +5533,11 @@ } }, "node_modules/@octokit/request-error": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", - "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", + "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", "dependencies": { - "@octokit/types": "^12.0.0", + "@octokit/types": "^13.1.0", "deprecation": "^2.0.0", "once": "^1.4.0" }, @@ -5274,6 +5545,32 @@ "node": ">= 18" } }, + "node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" + }, + "node_modules/@octokit/request-error/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@octokit/request/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" + }, + "node_modules/@octokit/request/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, "node_modules/@octokit/rest": { "version": "20.0.2", "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", @@ -14160,6 +14457,154 @@ "@octokit/core": ">=5" } }, + "node_modules/octokit-auth-probot/node_modules/@octokit/auth-app": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.1.2.tgz", + "integrity": "sha512-fWjIOpxnL8/YFY3kqquciFQ4o99aCqHw5kMFoGPYbz/h5HNZ11dJlV9zag5wS2nt0X1wJ5cs9BUo+CsAPfW4jQ==", + "dependencies": { + "@octokit/auth-oauth-app": "^7.1.0", + "@octokit/auth-oauth-user": "^4.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", + "deprecation": "^2.3.1", + "lru-cache": "^10.0.0", + "universal-github-app-jwt": "^1.1.2", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/auth-app/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/auth-oauth-app": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.1.0.tgz", + "integrity": "sha512-w+SyJN/b0l/HEb4EOPRudo7uUOSW51jcK1jwLa+4r7PA8FPFpoxEnHBHMITqCsc/3Vo2qqFjgQfz/xUUvsSQnA==", + "dependencies": { + "@octokit/auth-oauth-device": "^6.1.0", + "@octokit/auth-oauth-user": "^4.1.0", + "@octokit/request": "^8.3.1", + "@octokit/types": "^13.0.0", + "@types/btoa-lite": "^1.0.0", + "btoa-lite": "^1.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/auth-oauth-app/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/auth-oauth-device": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.1.0.tgz", + "integrity": "sha512-FNQ7cb8kASufd6Ej4gnJ3f1QB5vJitkoV1O0/g6e6lUsQ7+VsSNRHRmFScN2tV4IgKA12frrr/cegUs0t+0/Lw==", + "dependencies": { + "@octokit/oauth-methods": "^4.1.0", + "@octokit/request": "^8.3.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/auth-oauth-device/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/auth-oauth-user": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.1.0.tgz", + "integrity": "sha512-FrEp8mtFuS/BrJyjpur+4GARteUCrPeR/tZJzD8YourzoVhRics7u7we/aDcKv+yywRNwNi/P4fRi631rG/OyQ==", + "dependencies": { + "@octokit/auth-oauth-device": "^6.1.0", + "@octokit/oauth-methods": "^4.1.0", + "@octokit/request": "^8.3.1", + "@octokit/types": "^13.0.0", + "btoa-lite": "^1.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/auth-oauth-user/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/oauth-authorization-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz", + "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/oauth-methods": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-4.1.0.tgz", + "integrity": "sha512-4tuKnCRecJ6CG6gr0XcEXdZtkTDbfbnD5oaHBmLERTjTMZNi2CbfEHZxPU41xXLDG4DfKf+sonu00zvKI9NSbw==", + "dependencies": { + "@octokit/oauth-authorization-url": "^6.0.2", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", + "btoa-lite": "^1.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/oauth-methods/node_modules/@octokit/types": { + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.1.tgz", + "integrity": "sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==", + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/octokit-auth-probot/node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==" + }, + "node_modules/octokit-auth-probot/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/octokit-auth-probot/node_modules/universal-github-app-jwt": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.2.0.tgz", + "integrity": "sha512-dncpMpnsKBk0eetwfN8D8OUHGfiDhhJ+mtsbMl+7PfW7mYjiH8LIcqRmYMtzYLgSh47HjfdBtrBwIQ/gizKR3g==", + "dependencies": { + "@types/jsonwebtoken": "^9.0.0", + "jsonwebtoken": "^9.0.2" + } + }, "node_modules/oidc-token-hash": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", @@ -18143,13 +18588,9 @@ } }, "node_modules/universal-github-app-jwt": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.2.tgz", - "integrity": "sha512-t1iB2FmLFE+yyJY9+3wMx0ejB+MQpEVkH0gQv7dR6FZyltyq+ZZO0uDpbopxhrZ3SLEO4dCEkIujOMldEQ2iOA==", - "dependencies": { - "@types/jsonwebtoken": "^9.0.0", - "jsonwebtoken": "^9.0.2" - } + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-2.2.0.tgz", + "integrity": "sha512-G5o6f95b5BggDGuUfKDApKaCgNYy2x7OdHY0zSMF081O0EJobw+1130VONhrA7ezGSV2FNOGyM+KQpQZAr9bIQ==" }, "node_modules/universal-user-agent": { "version": "6.0.1", diff --git a/backend/package.json b/backend/package.json index 332c5a961..7b02a7b4d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -131,6 +131,7 @@ "@fastify/swagger": "^8.14.0", "@fastify/swagger-ui": "^2.1.0", "@node-saml/passport-saml": "^4.0.4", + "@octokit/auth-app": "^7.1.1", "@octokit/plugin-retry": "^5.0.5", "@octokit/rest": "^20.0.2", "@octokit/webhooks-types": "^7.3.1", diff --git a/backend/src/lib/config/env.ts b/backend/src/lib/config/env.ts index a11762564..7c10c433c 100644 --- a/backend/src/lib/config/env.ts +++ b/backend/src/lib/config/env.ts @@ -124,6 +124,8 @@ const envSchema = z // github app CLIENT_ID_GITHUB_APP: zpStr(z.string().optional()), CLIENT_SECRET_GITHUB_APP: zpStr(z.string().optional()), + GITHUB_APP_PRIVATE_KEY: zpStr(z.string().optional()), + GITHUB_APP_ID: z.coerce.number().optional(), // azure CLIENT_ID_AZURE: zpStr(z.string().optional()), diff --git a/backend/src/services/integration-auth/integration-app-list.ts b/backend/src/services/integration-auth/integration-app-list.ts index e61aa4a54..85fff9857 100644 --- a/backend/src/services/integration-auth/integration-app-list.ts +++ b/backend/src/services/integration-auth/integration-app-list.ts @@ -1,9 +1,12 @@ /* eslint-disable no-await-in-loop */ +import { createAppAuth } from "@octokit/auth-app"; import { Octokit } from "@octokit/rest"; +import { getConfig } from "@app/lib/config/env"; import { request } from "@app/lib/config/request"; import { NotFoundError } from "@app/lib/errors"; +import { TIntegrationAuthMetadata } from "./integration-auth-schema"; import { Integrations, IntegrationUrls } from "./integration-list"; // akhilmhdh: check this part later. Copied from old base @@ -230,7 +233,13 @@ const getAppsNetlify = async ({ accessToken }: { accessToken: string }) => { /** * Return list of repositories for Github integration */ -const getAppsGithub = async ({ accessToken }: { accessToken: string }) => { +const getAppsGithub = async ({ + accessToken, + authMetadata +}: { + accessToken: string; + authMetadata?: TIntegrationAuthMetadata; +}) => { interface GitHubApp { id: string; name: string; @@ -242,6 +251,29 @@ const getAppsGithub = async ({ accessToken }: { accessToken: string }) => { }; } + if (authMetadata?.installationId) { + const appCfg = getConfig(); + const octokit = new Octokit({ + authStrategy: createAppAuth, + auth: { + appId: appCfg.GITHUB_APP_ID, + privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + installationId: authMetadata.installationId + } + }); + + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const repos = await octokit.paginate("GET /installation/repositories", { + per_page: 100 + }); + + return repos.map((a) => ({ + appId: String(a.id), + name: a.name, + owner: a.owner.login + })); + } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion const repos = (await new Octokit({ auth: accessToken @@ -1061,11 +1093,13 @@ export const getApps = async ({ teamId, azureDevOpsOrgName, workspaceSlug, + authMetadata, url }: { integration: string; accessToken: string; accessId?: string; + authMetadata: TIntegrationAuthMetadata; teamId?: string | null; azureDevOpsOrgName?: string | null; workspaceSlug?: string; @@ -1099,7 +1133,8 @@ export const getApps = async ({ case Integrations.GITHUB: return getAppsGithub({ - accessToken + accessToken, + authMetadata }); case Integrations.GITLAB: diff --git a/backend/src/services/integration-auth/integration-auth-schema.ts b/backend/src/services/integration-auth/integration-auth-schema.ts new file mode 100644 index 000000000..94a68cc72 --- /dev/null +++ b/backend/src/services/integration-auth/integration-auth-schema.ts @@ -0,0 +1,7 @@ +import { z } from "zod"; + +export const IntegrationAuthMetadataSchema = z.object({ + installationId: z.string().optional() +}); + +export type TIntegrationAuthMetadata = z.infer; diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index 83e880b3e..08b5e64fc 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -1,10 +1,12 @@ import { ForbiddenError } from "@casl/ability"; +import { createAppAuth } from "@octokit/auth-app"; import { Octokit } from "@octokit/rest"; import AWS from "aws-sdk"; import { SecretEncryptionAlgo, SecretKeyEncoding, TIntegrationAuths, TIntegrationAuthsInsert } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; +import { getConfig } from "@app/lib/config/env"; import { request } from "@app/lib/config/request"; import { decryptSymmetric128BitHexKeyUTF8, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; @@ -16,6 +18,7 @@ import { KmsDataKey } from "../kms/kms-types"; import { TProjectBotServiceFactory } from "../project-bot/project-bot-service"; import { getApps } from "./integration-app-list"; import { TIntegrationAuthDALFactory } from "./integration-auth-dal"; +import { IntegrationAuthMetadataSchema } from "./integration-auth-schema"; import { TBitbucketWorkspace, TChecklyGroups, @@ -345,6 +348,13 @@ export const integrationAuthServiceFactory = ({ ) { return { accessToken: "", accessId: "" }; } + if ( + integrationAuth.integration === Integrations.GITHUB && + IntegrationAuthMetadataSchema.parse(integrationAuth.metadata).installationId + ) { + return { accessToken: "", accessId: "" }; + } + if (shouldUseSecretV2Bridge) { const { decryptor: secretManagerDecryptor, encryptor: secretManagerEncryptor } = await kmsService.createCipherPairWithDataKey({ @@ -471,6 +481,7 @@ export const integrationAuthServiceFactory = ({ const { accessToken, accessId } = await getIntegrationAccessToken(integrationAuth, shouldUseSecretV2Bridge, botKey); const apps = await getApps({ integration: integrationAuth.integration, + authMetadata: IntegrationAuthMetadataSchema.parse(integrationAuth.metadata), accessToken, accessId, teamId, @@ -586,6 +597,7 @@ export const integrationAuthServiceFactory = ({ }; const getGithubOrgs = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TIntegrationAuthGithubOrgsDTO) => { + const appCfg = getConfig(); const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" }); @@ -598,9 +610,44 @@ export const integrationAuthServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); - const { accessToken } = await getIntegrationAccessToken(integrationAuth, shouldUseSecretV2Bridge, botKey); - const octokit = new Octokit({ + let octokit: Octokit; + const { installationId } = integrationAuth.metadata as { installationId: string }; + if (installationId) { + octokit = new Octokit({ + authStrategy: createAppAuth, + auth: { + appId: appCfg.GITHUB_APP_ID, + privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + installationId + } + }); + + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const repos = await octokit.paginate("GET /installation/repositories", { + per_page: 100 + }); + + const orgSet: Set = new Set(); + + return repos + .filter((repo) => repo.owner.type === "Organization") + .map((repo) => ({ + name: repo.owner.login, + orgId: String(repo.owner.id) + })) + .filter((org) => { + const isOrgProcessed = !orgSet.has(org.orgId); + if (!isOrgProcessed) { + orgSet.add(org.orgId); + } + + return isOrgProcessed; + }); + } + + const { accessToken } = await getIntegrationAccessToken(integrationAuth, shouldUseSecretV2Bridge, botKey); + octokit = new Octokit({ auth: accessToken }); @@ -609,7 +656,9 @@ export const integrationAuthServiceFactory = ({ "X-GitHub-Api-Version": "2022-11-28" } }); - if (!data) return []; + if (!data) { + return []; + } return data.map(({ login: name, id: orgId }) => ({ name, orgId: String(orgId) })); }; @@ -637,9 +686,24 @@ export const integrationAuthServiceFactory = ({ const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, shouldUseSecretV2Bridge, botKey); - const octokit = new Octokit({ - auth: accessToken - }); + let octokit: Octokit; + const appCfg = getConfig(); + + const authMetadata = IntegrationAuthMetadataSchema.parse(integrationAuth.metadata); + if (authMetadata.installationId) { + octokit = new Octokit({ + authStrategy: createAppAuth, + auth: { + appId: appCfg.GITHUB_APP_ID, + privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + installationId: authMetadata.installationId + } + }); + } else { + octokit = new Octokit({ + auth: accessToken + }); + } const { data: { environments } diff --git a/backend/src/services/integration-auth/integration-delete-secret.ts b/backend/src/services/integration-auth/integration-delete-secret.ts index bd9619ad4..a404f5911 100644 --- a/backend/src/services/integration-auth/integration-delete-secret.ts +++ b/backend/src/services/integration-auth/integration-delete-secret.ts @@ -1,7 +1,10 @@ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import { createAppAuth } from "@octokit/auth-app"; import { retry } from "@octokit/plugin-retry"; import { Octokit } from "@octokit/rest"; import { TIntegrationAuths, TIntegrations } from "@app/db/schemas"; +import { getConfig } from "@app/lib/config/env"; import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; @@ -15,6 +18,7 @@ import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretImportDALFactory } from "../secret-import/secret-import-dal"; import { fnSecretsV2FromImports } from "../secret-import/secret-import-fns"; import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal"; +import { IntegrationAuthMetadataSchema, TIntegrationAuthMetadata } from "./integration-auth-schema"; import { TIntegrationAuthServiceFactory } from "./integration-auth-service"; import { Integrations } from "./integration-list"; @@ -154,10 +158,12 @@ const getIntegrationSecretsV1 = async ( export const deleteGithubSecrets = async ({ integration, + authMetadata, secrets, accessToken }: { integration: Omit; + authMetadata: TIntegrationAuthMetadata; secrets: Record; accessToken: string; }) => { @@ -170,9 +176,23 @@ export const deleteGithubSecrets = async ({ } const OctokitWithRetry = Octokit.plugin(retry); - const octokit = new OctokitWithRetry({ - auth: accessToken - }); + let octokit: Octokit; + const appCfg = getConfig(); + + if (authMetadata.installationId) { + octokit = new OctokitWithRetry({ + authStrategy: createAppAuth, + auth: { + appId: appCfg.GITHUB_APP_ID, + privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + installationId: authMetadata.installationId + } + }); + } else { + octokit = new OctokitWithRetry({ + auth: accessToken + }); + } enum GithubScope { Repo = "github-repo", @@ -192,6 +212,7 @@ export const deleteGithubSecrets = async ({ break; } case GithubScope.Env: { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment encryptedGithubSecrets = ( await octokit.request("GET /repositories/{repository_id}/environments/{environment_name}/secrets", { repository_id: Number(integration.appId), @@ -346,6 +367,7 @@ export const deleteIntegrationSecrets = async ({ case Integrations.GITHUB: { await deleteGithubSecrets({ integration, + authMetadata: IntegrationAuthMetadataSchema.parse(integrationAuth.metadata), accessToken, secrets: Object.keys(suffixedSecrets).length !== 0 ? suffixedSecrets : secrets }); diff --git a/backend/src/services/integration-auth/integration-sync-secret.ts b/backend/src/services/integration-auth/integration-sync-secret.ts index c9711c7df..c08cff98d 100644 --- a/backend/src/services/integration-auth/integration-sync-secret.ts +++ b/backend/src/services/integration-auth/integration-sync-secret.ts @@ -18,6 +18,7 @@ import { UpdateSecretCommand } from "@aws-sdk/client-secrets-manager"; import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts"; +import { createAppAuth } from "@octokit/auth-app"; import { Octokit } from "@octokit/rest"; import AWS, { AWSError } from "aws-sdk"; import { AxiosError } from "axios"; @@ -35,6 +36,7 @@ import { TCreateManySecretsRawFn, TUpdateManySecretsRawFn } from "@app/services/ import { TIntegrationDALFactory } from "../integration/integration-dal"; import { IntegrationMetadataSchema } from "../integration/integration-schema"; +import { IntegrationAuthMetadataSchema } from "./integration-auth-schema"; import { TIntegrationsWithEnvironment } from "./integration-auth-types"; import { IntegrationInitialSyncBehavior, @@ -1527,11 +1529,13 @@ const syncSecretsNetlify = async ({ */ const syncSecretsGitHub = async ({ integration, + integrationAuth, secrets, accessToken, appendices }: { integration: TIntegrations; + integrationAuth: TIntegrationAuths; secrets: Record; accessToken: string; appendices?: { prefix: string; suffix: string }; @@ -1553,9 +1557,24 @@ const syncSecretsGitHub = async ({ selected_repositories_url?: string | undefined; } - const octokit = new Octokit({ - auth: accessToken - }); + const authMetadata = IntegrationAuthMetadataSchema.parse(integrationAuth.metadata); + let octokit: Octokit; + const appCfg = getConfig(); + + if (authMetadata.installationId) { + octokit = new Octokit({ + authStrategy: createAppAuth, + auth: { + appId: appCfg.GITHUB_APP_ID, + privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + installationId: authMetadata.installationId + } + }); + } else { + octokit = new Octokit({ + auth: accessToken + }); + } enum GithubScope { Repo = "github-repo", @@ -4054,6 +4073,7 @@ export const syncIntegrationSecrets = async ({ case Integrations.GITHUB: await syncSecretsGitHub({ integration, + integrationAuth, secrets, accessToken, appendices diff --git a/backend/src/services/integration/integration-service.ts b/backend/src/services/integration/integration-service.ts index 24e1dd5c4..47a92c384 100644 --- a/backend/src/services/integration/integration-service.ts +++ b/backend/src/services/integration/integration-service.ts @@ -258,27 +258,7 @@ export const integrationServiceFactory = ({ }); } - const deletedIntegration = await integrationDAL.transaction(async (tx) => { - // delete integration - const deletedIntegrationResult = await integrationDAL.deleteById(id, tx); - - // check if there are other integrations that share the same integration auth - const integrations = await integrationDAL.find( - { - integrationAuthId: integration.integrationAuthId - }, - tx - ); - - if (integrations.length === 0) { - // no other integration shares the same integration auth - // -> delete the integration auth - await integrationAuthDAL.deleteById(integration.integrationAuthId, tx); - } - - return deletedIntegrationResult; - }); - + const deletedIntegration = await integrationDAL.deleteById(id); return { ...integration, ...deletedIntegration }; }; From faf2c6df90ddc1f5392cfcae7130ff4eb459097c Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Mon, 14 Oct 2024 17:06:28 +0800 Subject: [PATCH 03/54] misc: moved metadata parsing into github scope --- .../services/integration-auth/integration-app-list.ts | 9 +++++---- .../integration-auth/integration-auth-service.ts | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/src/services/integration-auth/integration-app-list.ts b/backend/src/services/integration-auth/integration-app-list.ts index 85fff9857..d429c0da4 100644 --- a/backend/src/services/integration-auth/integration-app-list.ts +++ b/backend/src/services/integration-auth/integration-app-list.ts @@ -2,11 +2,12 @@ import { createAppAuth } from "@octokit/auth-app"; import { Octokit } from "@octokit/rest"; +import { TIntegrationAuths } from "@app/db/schemas"; import { getConfig } from "@app/lib/config/env"; import { request } from "@app/lib/config/request"; import { NotFoundError } from "@app/lib/errors"; -import { TIntegrationAuthMetadata } from "./integration-auth-schema"; +import { IntegrationAuthMetadataSchema, TIntegrationAuthMetadata } from "./integration-auth-schema"; import { Integrations, IntegrationUrls } from "./integration-list"; // akhilmhdh: check this part later. Copied from old base @@ -1088,18 +1089,18 @@ const getAppsAzureDevOps = async ({ accessToken, orgName }: { accessToken: strin export const getApps = async ({ integration, + integrationAuth, accessToken, accessId, teamId, azureDevOpsOrgName, workspaceSlug, - authMetadata, url }: { integration: string; accessToken: string; accessId?: string; - authMetadata: TIntegrationAuthMetadata; + integrationAuth: TIntegrationAuths; teamId?: string | null; azureDevOpsOrgName?: string | null; workspaceSlug?: string; @@ -1134,7 +1135,7 @@ export const getApps = async ({ case Integrations.GITHUB: return getAppsGithub({ accessToken, - authMetadata + authMetadata: IntegrationAuthMetadataSchema.parse(integrationAuth.metadata) }); case Integrations.GITLAB: diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index 08b5e64fc..1b1cc9c0c 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -481,7 +481,7 @@ export const integrationAuthServiceFactory = ({ const { accessToken, accessId } = await getIntegrationAccessToken(integrationAuth, shouldUseSecretV2Bridge, botKey); const apps = await getApps({ integration: integrationAuth.integration, - authMetadata: IntegrationAuthMetadataSchema.parse(integrationAuth.metadata), + integrationAuth, accessToken, accessId, teamId, From 73382c5363dbc43604c730c96b82a97900d4ba10 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 15 Oct 2024 03:37:11 +0800 Subject: [PATCH 04/54] feat: added handling of using same connection with different projects --- .../routes/v1/integration-auth-router.ts | 34 +++++++ .../server/routes/v1/organization-router.ts | 31 +++++++ .../integration-auth/integration-app-list.ts | 2 +- .../integration-auth/integration-auth-dal.ts | 19 +++- .../integration-auth-service.ts | 84 ++++++++++++++++-- .../integration-auth-types.ts | 4 + .../integration-delete-secret.ts | 2 +- .../integration-sync-secret.ts | 2 +- .../src/hooks/api/integrationAuth/index.tsx | 1 + .../hooks/api/integrationAuth/mutations.tsx | 19 ++++ .../src/hooks/api/integrationAuth/types.ts | 6 ++ frontend/src/hooks/api/organization/index.ts | 5 +- .../src/hooks/api/organization/queries.tsx | 22 ++++- .../github/auth-mode-selection.tsx | 6 +- .../integrations/select-integration-auth.tsx | 88 ++++++++++++++----- 15 files changed, 287 insertions(+), 38 deletions(-) create mode 100644 frontend/src/hooks/api/integrationAuth/mutations.tsx diff --git a/backend/src/server/routes/v1/integration-auth-router.ts b/backend/src/server/routes/v1/integration-auth-router.ts index 1e6a88129..1d2959f5b 100644 --- a/backend/src/server/routes/v1/integration-auth-router.ts +++ b/backend/src/server/routes/v1/integration-auth-router.ts @@ -453,6 +453,40 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider) } }); + server.route({ + method: "POST", + url: "/:integrationAuthId/duplicate", + config: { + rateLimit: writeLimit + }, + onRequest: verifyAuth([AuthMode.JWT]), + schema: { + params: z.object({ + integrationAuthId: z.string().trim() + }), + body: z.object({ + projectId: z.string().trim() + }), + response: { + 200: z.object({ + integrationAuth: integrationAuthPubSchema + }) + } + }, + handler: async (req) => { + const integrationAuth = await server.services.integrationAuth.duplicateIntegrationAuth({ + actorId: req.permission.id, + actor: req.permission.type, + actorOrgId: req.permission.orgId, + actorAuthMethod: req.permission.authMethod, + id: req.params.integrationAuthId, + projectId: req.body.projectId + }); + + return { integrationAuth }; + } + }); + server.route({ method: "GET", url: "/:integrationAuthId/github/envs", diff --git a/backend/src/server/routes/v1/organization-router.ts b/backend/src/server/routes/v1/organization-router.ts index d19317c4b..3f9e3c300 100644 --- a/backend/src/server/routes/v1/organization-router.ts +++ b/backend/src/server/routes/v1/organization-router.ts @@ -16,6 +16,8 @@ import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ActorType, AuthMode } from "@app/services/auth/auth-type"; +import { integrationAuthPubSchema } from "../sanitizedSchemas"; + export const registerOrgRouter = async (server: FastifyZodProvider) => { server.route({ method: "GET", @@ -67,6 +69,35 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { } }); + server.route({ + method: "GET", + url: "/:organizationId/integration-authorizations", + config: { + rateLimit: readLimit + }, + schema: { + params: z.object({ + organizationId: z.string().trim() + }), + response: { + 200: z.object({ + authorizations: integrationAuthPubSchema.array() + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT]), + handler: async (req) => { + const authorizations = await server.services.integrationAuth.listOrgIntegrationAuth({ + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actor: req.permission.type, + actorOrgId: req.permission.orgId + }); + + return { authorizations }; + } + }); + server.route({ method: "GET", url: "/audit-logs", diff --git a/backend/src/services/integration-auth/integration-app-list.ts b/backend/src/services/integration-auth/integration-app-list.ts index d429c0da4..5882983e0 100644 --- a/backend/src/services/integration-auth/integration-app-list.ts +++ b/backend/src/services/integration-auth/integration-app-list.ts @@ -1135,7 +1135,7 @@ export const getApps = async ({ case Integrations.GITHUB: return getAppsGithub({ accessToken, - authMetadata: IntegrationAuthMetadataSchema.parse(integrationAuth.metadata) + authMetadata: IntegrationAuthMetadataSchema.parse(integrationAuth.metadata || {}) }); case Integrations.GITLAB: diff --git a/backend/src/services/integration-auth/integration-auth-dal.ts b/backend/src/services/integration-auth/integration-auth-dal.ts index d32cd1579..7a56afcbb 100644 --- a/backend/src/services/integration-auth/integration-auth-dal.ts +++ b/backend/src/services/integration-auth/integration-auth-dal.ts @@ -3,7 +3,7 @@ import { Knex } from "knex"; import { TDbClient } from "@app/db"; import { TableName, TIntegrationAuths, TIntegrationAuthsUpdate } from "@app/db/schemas"; import { BadRequestError, DatabaseError } from "@app/lib/errors"; -import { ormify } from "@app/lib/knex"; +import { ormify, selectAllTableCols } from "@app/lib/knex"; export type TIntegrationAuthDALFactory = ReturnType; @@ -28,8 +28,23 @@ export const integrationAuthDALFactory = (db: TDbClient) => { } }; + const getByOrg = async (orgId: string, tx?: Knex) => { + try { + const integrationAuths = await (tx || db)(TableName.IntegrationAuth) + .join(TableName.Project, `${TableName.Project}.id`, `${TableName.IntegrationAuth}.projectId`) + .join(TableName.Organization, `${TableName.Organization}.id`, `${TableName.Project}.orgId`) + .where(`${TableName.Organization}.id`, "=", orgId) + .select(selectAllTableCols(TableName.IntegrationAuth)); + + return integrationAuths; + } catch (error) { + throw new DatabaseError({ error, name: "get by org" }); + } + }; + return { ...integrationAuthOrm, - bulkUpdate + bulkUpdate, + getByOrg }; }; diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index 1b1cc9c0c..8c0c309ca 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -10,7 +10,7 @@ import { getConfig } from "@app/lib/config/env"; import { request } from "@app/lib/config/request"; import { decryptSymmetric128BitHexKeyUTF8, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; -import { TProjectPermission } from "@app/lib/types"; +import { TGenericPermission, TProjectPermission } from "@app/lib/types"; import { TIntegrationDALFactory } from "../integration/integration-dal"; import { TKmsServiceFactory } from "../kms/kms-service"; @@ -24,6 +24,7 @@ import { TChecklyGroups, TDeleteIntegrationAuthByIdDTO, TDeleteIntegrationAuthsDTO, + TDuplicateGithubIntegrationAuthDTO, TGetIntegrationAuthDTO, TGetIntegrationAuthTeamCityBuildConfigDTO, THerokuPipelineCoupling, @@ -89,6 +90,24 @@ export const integrationAuthServiceFactory = ({ return authorizations; }; + const listOrgIntegrationAuth = async ({ actorId, actor, actorOrgId, actorAuthMethod }: TGenericPermission) => { + const authorizations = await integrationAuthDAL.getByOrg(actorOrgId as string); + + return Promise.all( + authorizations.filter(async (auth) => { + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + auth.projectId, + actorAuthMethod, + actorOrgId + ); + + return permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); + }) + ); + }; + const getIntegrationAuth = async ({ actor, id, actorId, actorAuthMethod, actorOrgId }: TGetIntegrationAuthDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new NotFoundError({ message: "Failed to find integration" }); @@ -350,7 +369,7 @@ export const integrationAuthServiceFactory = ({ } if ( integrationAuth.integration === Integrations.GITHUB && - IntegrationAuthMetadataSchema.parse(integrationAuth.metadata).installationId + IntegrationAuthMetadataSchema.parse(integrationAuth.metadata || {}).installationId ) { return { accessToken: "", accessId: "" }; } @@ -612,7 +631,7 @@ export const integrationAuthServiceFactory = ({ const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); let octokit: Octokit; - const { installationId } = integrationAuth.metadata as { installationId: string }; + const { installationId } = (integrationAuth.metadata as { installationId: string }) || {}; if (installationId) { octokit = new Octokit({ authStrategy: createAppAuth, @@ -637,12 +656,12 @@ export const integrationAuthServiceFactory = ({ orgId: String(repo.owner.id) })) .filter((org) => { - const isOrgProcessed = !orgSet.has(org.orgId); + const isOrgProcessed = orgSet.has(org.orgId); if (!isOrgProcessed) { orgSet.add(org.orgId); } - return isOrgProcessed; + return !isOrgProcessed; }); } @@ -689,7 +708,7 @@ export const integrationAuthServiceFactory = ({ let octokit: Octokit; const appCfg = getConfig(); - const authMetadata = IntegrationAuthMetadataSchema.parse(integrationAuth.metadata); + const authMetadata = IntegrationAuthMetadataSchema.parse(integrationAuth.metadata || {}); if (authMetadata.installationId) { octokit = new Octokit({ authStrategy: createAppAuth, @@ -1390,8 +1409,58 @@ export const integrationAuthServiceFactory = ({ return delIntegrationAuth; }; + // At the moment, we only use this for Github App integration as it's a special case + const duplicateIntegrationAuth = async ({ + id, + actorId, + actor, + actorAuthMethod, + actorOrgId, + projectId + }: TDuplicateGithubIntegrationAuthDTO) => { + const integrationAuth = await integrationAuthDAL.findById(id); + if (!integrationAuth) { + throw new NotFoundError({ message: "Failed to find integration" }); + } + + const { permission: sourcePermission } = await permissionService.getProjectPermission( + actor, + actorId, + integrationAuth.projectId, + actorAuthMethod, + actorOrgId + ); + + ForbiddenError.from(sourcePermission).throwUnlessCan( + ProjectPermissionActions.Create, + ProjectPermissionSub.Integrations + ); + + const { permission: targetPermission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); + + ForbiddenError.from(targetPermission).throwUnlessCan( + ProjectPermissionActions.Create, + ProjectPermissionSub.Integrations + ); + + const newIntegrationAuth: Omit & { id?: string } = { + ...integrationAuth, + id: undefined, + projectId + }; + + return integrationAuthDAL.create(newIntegrationAuth); + }; + return { listIntegrationAuthByProjectId, + listOrgIntegrationAuth, getIntegrationOptions, getIntegrationAuth, oauthExchange, @@ -1418,6 +1487,7 @@ export const integrationAuthServiceFactory = ({ getNorthFlankSecretGroups, getTeamcityBuildConfigs, getBitbucketWorkspaces, - getIntegrationAccessToken + getIntegrationAccessToken, + duplicateIntegrationAuth }; }; diff --git a/backend/src/services/integration-auth/integration-auth-types.ts b/backend/src/services/integration-auth/integration-auth-types.ts index b8afe5ecb..eb8b8044d 100644 --- a/backend/src/services/integration-auth/integration-auth-types.ts +++ b/backend/src/services/integration-auth/integration-auth-types.ts @@ -108,6 +108,10 @@ export type TDeleteIntegrationAuthByIdDTO = { id: string; } & Omit; +export type TDuplicateGithubIntegrationAuthDTO = { + id: string; +} & TProjectPermission; + export type TGetIntegrationAuthTeamCityBuildConfigDTO = { id: string; appId: string; diff --git a/backend/src/services/integration-auth/integration-delete-secret.ts b/backend/src/services/integration-auth/integration-delete-secret.ts index a404f5911..d8ec89b15 100644 --- a/backend/src/services/integration-auth/integration-delete-secret.ts +++ b/backend/src/services/integration-auth/integration-delete-secret.ts @@ -367,7 +367,7 @@ export const deleteIntegrationSecrets = async ({ case Integrations.GITHUB: { await deleteGithubSecrets({ integration, - authMetadata: IntegrationAuthMetadataSchema.parse(integrationAuth.metadata), + authMetadata: IntegrationAuthMetadataSchema.parse(integrationAuth.metadata || {}), accessToken, secrets: Object.keys(suffixedSecrets).length !== 0 ? suffixedSecrets : secrets }); diff --git a/backend/src/services/integration-auth/integration-sync-secret.ts b/backend/src/services/integration-auth/integration-sync-secret.ts index c08cff98d..a46b62f5e 100644 --- a/backend/src/services/integration-auth/integration-sync-secret.ts +++ b/backend/src/services/integration-auth/integration-sync-secret.ts @@ -1557,7 +1557,7 @@ const syncSecretsGitHub = async ({ selected_repositories_url?: string | undefined; } - const authMetadata = IntegrationAuthMetadataSchema.parse(integrationAuth.metadata); + const authMetadata = IntegrationAuthMetadataSchema.parse(integrationAuth.metadata || {}); let octokit: Octokit; const appCfg = getConfig(); diff --git a/frontend/src/hooks/api/integrationAuth/index.tsx b/frontend/src/hooks/api/integrationAuth/index.tsx index 5f0503eee..0ae3511de 100644 --- a/frontend/src/hooks/api/integrationAuth/index.tsx +++ b/frontend/src/hooks/api/integrationAuth/index.tsx @@ -1,3 +1,4 @@ +export { useDuplicateIntegrationAuth } from "./mutations"; export { useAuthorizeIntegration, useDeleteIntegrationAuth, diff --git a/frontend/src/hooks/api/integrationAuth/mutations.tsx b/frontend/src/hooks/api/integrationAuth/mutations.tsx new file mode 100644 index 000000000..b7a3f18bd --- /dev/null +++ b/frontend/src/hooks/api/integrationAuth/mutations.tsx @@ -0,0 +1,19 @@ +import { useMutation } from "@tanstack/react-query"; + +import { apiRequest } from "@app/config/request"; + +import { IntegrationAuth, TDuplicateIntegrationAuthDTO } from "./types"; + +// For now, this should only be used in the Github app integration flow. +export const useDuplicateIntegrationAuth = () => { + return useMutation({ + mutationFn: async (body) => { + const { data } = await apiRequest.post<{ integrationAuth: IntegrationAuth }>( + `/api/v1/integration-auth/${body.integrationAuthId}/duplicate`, + body + ); + + return data.integrationAuth; + } + }); +}; diff --git a/frontend/src/hooks/api/integrationAuth/types.ts b/frontend/src/hooks/api/integrationAuth/types.ts index a32dab8ce..9a8ca0e31 100644 --- a/frontend/src/hooks/api/integrationAuth/types.ts +++ b/frontend/src/hooks/api/integrationAuth/types.ts @@ -11,6 +11,7 @@ export type IntegrationAuth = { teamId?: string; metadata: { installationName?: string; + installationId?: string; }; }; @@ -87,3 +88,8 @@ export type TeamCityBuildConfig = { name: string; buildConfigId: string; }; + +export type TDuplicateIntegrationAuthDTO = { + integrationAuthId: string; + projectId: string; +}; diff --git a/frontend/src/hooks/api/organization/index.ts b/frontend/src/hooks/api/organization/index.ts index f7a898ef0..fece19e5f 100644 --- a/frontend/src/hooks/api/organization/index.ts +++ b/frontend/src/hooks/api/organization/index.ts @@ -8,8 +8,9 @@ export { useDeleteOrgTaxId, useGetIdentityMembershipOrgs, useGetOrganizationGroups, - useGetOrganizations, + useGetOrganizations, useGetOrgBillingDetails, + useGetOrgIntegrationAuths, useGetOrgInvoices, useGetOrgLicenses, useGetOrgPlanBillingInfo, @@ -20,4 +21,4 @@ export { useGetOrgTrialUrl, useUpdateOrg, useUpdateOrgBillingDetails -} from "./queries"; \ No newline at end of file +} from "./queries"; diff --git a/frontend/src/hooks/api/organization/queries.tsx b/frontend/src/hooks/api/organization/queries.tsx index 670f39146..5e3dfbfa7 100644 --- a/frontend/src/hooks/api/organization/queries.tsx +++ b/frontend/src/hooks/api/organization/queries.tsx @@ -4,6 +4,7 @@ import { apiRequest } from "@app/config/request"; import { OrderByDirection } from "@app/hooks/api/generic/types"; import { TGroupOrgMembership } from "../groups/types"; +import { IntegrationAuth } from "../types"; import { BillingDetails, Invoice, @@ -39,7 +40,8 @@ export const organizationKeys = { ...params }: TListOrgIdentitiesDTO) => [...organizationKeys.getOrgIdentityMemberships(orgId), params] as const, - getOrgGroups: (orgId: string) => [{ orgId }, "organization-groups"] as const + getOrgGroups: (orgId: string) => [{ orgId }, "organization-groups"] as const, + getOrgIntegrationAuths: (orgId: string) => [{ orgId }, "integration-auths"] as const }; export const fetchOrganizations = async () => { @@ -463,3 +465,21 @@ export const useGetOrganizationGroups = (organizationId: string) => { } }); }; + +export const useGetOrgIntegrationAuths = ( + organizationId: string, + select?: (data: IntegrationAuth[]) => TData +) => { + return useQuery({ + queryKey: organizationKeys.getOrgIntegrationAuths(organizationId), + queryFn: async () => { + const { data } = await apiRequest.get<{ authorizations: IntegrationAuth[] }>( + `/api/v1/organization/${organizationId}/integration-authorizations` + ); + + return data.authorizations; + }, + enabled: Boolean(organizationId), + select + }); +}; diff --git a/frontend/src/pages/integrations/github/auth-mode-selection.tsx b/frontend/src/pages/integrations/github/auth-mode-selection.tsx index 5426cd562..e5f96636f 100644 --- a/frontend/src/pages/integrations/github/auth-mode-selection.tsx +++ b/frontend/src/pages/integrations/github/auth-mode-selection.tsx @@ -24,7 +24,7 @@ export default function GithubIntegrationAuthModeSelectionPage() {
@@ -61,7 +61,7 @@ export default function GithubIntegrationAuthModeSelectionPage() { router.push("/integrations/select-integration-auth?integrationSlug=github"); }} > - Connect with Github App + Connect with App
diff --git a/frontend/src/pages/integrations/select-integration-auth.tsx b/frontend/src/pages/integrations/select-integration-auth.tsx index bb55fc01c..6bfa0ae6e 100644 --- a/frontend/src/pages/integrations/select-integration-auth.tsx +++ b/frontend/src/pages/integrations/select-integration-auth.tsx @@ -6,46 +6,93 @@ import Image from "next/image"; import { useRouter } from "next/router"; import { Button, Card, CardTitle } from "@app/components/v2"; -import { useWorkspace } from "@app/context"; -import { useGetCloudIntegrations, useGetWorkspaceAuthorizations } from "@app/hooks/api"; +import { useOrganization, useWorkspace } from "@app/context"; +import { + useDuplicateIntegrationAuth, + useGetCloudIntegrations, + useGetOrgIntegrationAuths +} from "@app/hooks/api"; import { IntegrationAuth } from "@app/hooks/api/types"; export default function SelectIntegrationAuthPage() { const router = useRouter(); const { data: cloudIntegrations } = useGetCloudIntegrations(); + const { currentOrg } = useOrganization(); const { currentWorkspace } = useWorkspace(); - const workspaceId = currentWorkspace?.id || ""; + const orgId = currentOrg?.id || ""; const integrationSlug = router.query.integrationSlug as string; const currentIntegration = cloudIntegrations?.find( (integration) => integration.slug === integrationSlug ); + const { mutateAsync: duplicateIntegrationAuth, isLoading: isIntegrationAuthSelectLoading } = + useDuplicateIntegrationAuth(); + // for Github, we want to reuse the same connection across the Infisical organization + // when we do need to reuse this page for other integrations, add handling to fetch workspace integration auths instead const { data: integrationAuths, isLoading: isLoadingIntegrationAuths } = - useGetWorkspaceAuthorizations( - workspaceId, - useCallback((data: IntegrationAuth[]) => { - const filteredIntegrationAuths = data.filter( - (integrationAuth) => integrationAuth.integration === integrationSlug - ); - - if (integrationSlug === "github") { - // for now, we only display the integration auths for Github apps - return filteredIntegrationAuths.filter((integrationAuth) => - Boolean(integrationAuth.metadata?.installationName) + useGetOrgIntegrationAuths( + orgId, + useCallback( + (data: IntegrationAuth[]) => { + const filteredIntegrationAuths = data.filter( + (integrationAuth) => integrationAuth.integration === integrationSlug ); - } - return []; - }, []) + if (integrationSlug === "github") { + const sameProjectIntegrationAuths = filteredIntegrationAuths.filter( + (auth) => auth.projectId === currentWorkspace?.id + ); + const differentProjectIntegrationAuths = filteredIntegrationAuths.filter( + (auth) => auth.projectId !== currentWorkspace?.id + ); + + const installationIds = new Set(); + + // for now, we only display the integration auths for Github apps + return ( + // we concatenate it this way so that integration auths from the same project are prioritized for display + sameProjectIntegrationAuths + .concat(differentProjectIntegrationAuths) + .filter((integrationAuth) => Boolean(integrationAuth.metadata?.installationId)) + // we filter it so that we only show unique installations because the same installation/connection + // can be used in multiple integration auths + .filter((integrationAuth) => { + const isProcessedInstallationId = installationIds.has( + integrationAuth.metadata.installationId as string + ); + + if (!isProcessedInstallationId) { + installationIds.add(integrationAuth.metadata.installationId as string); + } + + return !isProcessedInstallationId; + }) + ); + } + + return []; + }, + [integrationSlug] + ) ); const logo = integrationSlug === "github" ? "/images/integrations/GitHub.png" : ""; - const handleConnectionSelect = (integrationAuthId: string) => { + const handleConnectionSelect = async (integrationAuth: IntegrationAuth) => { if (integrationSlug === "github") { - router.push(`/integrations/github/create?integrationAuthId=${integrationAuthId}`); + if (integrationAuth.projectId === currentWorkspace?.id) { + router.push(`/integrations/github/create?integrationAuthId=${integrationAuth.id}`); + } else { + // we create a copy of the existing integration auth from another project to the current project + const newIntegrationAuth = await duplicateIntegrationAuth({ + projectId: currentWorkspace?.id || "", + integrationAuthId: integrationAuth.id + }); + + router.push(`/integrations/github/create?integrationAuthId=${newIntegrationAuth.id}`); + } } }; @@ -93,10 +140,11 @@ export default function SelectIntegrationAuthPage() { colorSchema="gray" variant="outline" className="mt-3 w-3/4" + isDisabled={isIntegrationAuthSelectLoading} key={integrationAuth.id} size="sm" type="submit" - onClick={() => handleConnectionSelect(integrationAuth.id)} + onClick={() => handleConnectionSelect(integrationAuth)} > {connectionName} From bdae136bedca8f802d7b0311111aa37b568b282c Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 15 Oct 2024 17:20:23 +0800 Subject: [PATCH 05/54] misc: added proper selection of existing github oauth --- .../integration-auth-service.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index 8c0c309ca..8f5dbe1b3 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -209,12 +209,23 @@ export const integrationAuthServiceFactory = ({ updateDoc.accessCiphertext = accessEncToken.ciphertext; } } + return integrationAuthDAL.transaction(async (tx) => { - const doc = await integrationAuthDAL.findOne({ projectId, integration }, tx); - if (!doc) { + const integrationAuths = await integrationAuthDAL.find({ projectId, integration }, { tx }); + let existingIntegrationAuth: TIntegrationAuths | undefined; + + // we need to ensure that the integration auth that we use for Github is actually Oauth + if (integration === Integrations.GITHUB) { + existingIntegrationAuth = integrationAuths.find((integAuth) => !integAuth.metadata); + } else { + [existingIntegrationAuth] = integrationAuths; + } + + if (!existingIntegrationAuth) { return integrationAuthDAL.create(updateDoc, tx); } - return integrationAuthDAL.updateById(doc.id, updateDoc, tx); + + return integrationAuthDAL.updateById(existingIntegrationAuth.id, updateDoc, tx); }); }; From 94b799e80b5e9d13fb9ce685f99cabe65f2b1d9c Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 15 Oct 2024 18:17:57 +0800 Subject: [PATCH 06/54] misc: finalized variable names --- .env.example | 6 +++--- backend/src/lib/config/env.ts | 6 +++--- .../src/services/integration-auth/integration-app-list.ts | 4 ++-- .../services/integration-auth/integration-auth-service.ts | 8 ++++---- .../integration-auth/integration-delete-secret.ts | 4 ++-- backend/src/services/integration-auth/integration-list.ts | 2 +- .../services/integration-auth/integration-sync-secret.ts | 4 ++-- .../src/services/integration-auth/integration-token.ts | 8 ++++---- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.env.example b/.env.example index 929278081..8bcb4039d 100644 --- a/.env.example +++ b/.env.example @@ -37,7 +37,7 @@ CLIENT_ID_VERCEL= CLIENT_ID_NETLIFY= CLIENT_ID_GITHUB= CLIENT_ID_GITHUB_APP= -CLIENT_SLUG_GITHUB= +CLIENT_SLUG_GITHUB_APP= CLIENT_ID_GITLAB= CLIENT_ID_BITBUCKET= CLIENT_SECRET_HEROKU= @@ -49,8 +49,8 @@ CLIENT_SECRET_GITLAB= CLIENT_SECRET_BITBUCKET= CLIENT_SLUG_VERCEL= -GITHUB_APP_PRIVATE_KEY= -GITHUB_APP_ID= +CLIENT_PRIVATE_KEY_GITHUB_APP= +CLIENT_APP_ID_GITHUB_APP= # Sentry (optional) for monitoring errors SENTRY_DSN= diff --git a/backend/src/lib/config/env.ts b/backend/src/lib/config/env.ts index 7c10c433c..376b03005 100644 --- a/backend/src/lib/config/env.ts +++ b/backend/src/lib/config/env.ts @@ -120,12 +120,12 @@ const envSchema = z // github oauth CLIENT_ID_GITHUB: zpStr(z.string().optional()), CLIENT_SECRET_GITHUB: zpStr(z.string().optional()), - CLIENT_SLUG_GITHUB: zpStr(z.string().optional()), + CLIENT_SLUG_GITHUB_APP: zpStr(z.string().optional()), // github app CLIENT_ID_GITHUB_APP: zpStr(z.string().optional()), CLIENT_SECRET_GITHUB_APP: zpStr(z.string().optional()), - GITHUB_APP_PRIVATE_KEY: zpStr(z.string().optional()), - GITHUB_APP_ID: z.coerce.number().optional(), + CLIENT_PRIVATE_KEY_GITHUB_APP: zpStr(z.string().optional()), + CLIENT_APP_ID_GITHUB_APP: z.coerce.number().optional(), // azure CLIENT_ID_AZURE: zpStr(z.string().optional()), diff --git a/backend/src/services/integration-auth/integration-app-list.ts b/backend/src/services/integration-auth/integration-app-list.ts index 5882983e0..44ac825c7 100644 --- a/backend/src/services/integration-auth/integration-app-list.ts +++ b/backend/src/services/integration-auth/integration-app-list.ts @@ -257,8 +257,8 @@ const getAppsGithub = async ({ const octokit = new Octokit({ authStrategy: createAppAuth, auth: { - appId: appCfg.GITHUB_APP_ID, - privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + appId: appCfg.CLIENT_APP_ID_GITHUB_APP, + privateKey: appCfg.CLIENT_PRIVATE_KEY_GITHUB_APP, installationId: authMetadata.installationId } }); diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index 8f5dbe1b3..bcfe2c773 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -647,8 +647,8 @@ export const integrationAuthServiceFactory = ({ octokit = new Octokit({ authStrategy: createAppAuth, auth: { - appId: appCfg.GITHUB_APP_ID, - privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + appId: appCfg.CLIENT_APP_ID_GITHUB_APP, + privateKey: appCfg.CLIENT_PRIVATE_KEY_GITHUB_APP, installationId } }); @@ -724,8 +724,8 @@ export const integrationAuthServiceFactory = ({ octokit = new Octokit({ authStrategy: createAppAuth, auth: { - appId: appCfg.GITHUB_APP_ID, - privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + appId: appCfg.CLIENT_APP_ID_GITHUB_APP, + privateKey: appCfg.CLIENT_PRIVATE_KEY_GITHUB_APP, installationId: authMetadata.installationId } }); diff --git a/backend/src/services/integration-auth/integration-delete-secret.ts b/backend/src/services/integration-auth/integration-delete-secret.ts index d8ec89b15..7cf77cb26 100644 --- a/backend/src/services/integration-auth/integration-delete-secret.ts +++ b/backend/src/services/integration-auth/integration-delete-secret.ts @@ -183,8 +183,8 @@ export const deleteGithubSecrets = async ({ octokit = new OctokitWithRetry({ authStrategy: createAppAuth, auth: { - appId: appCfg.GITHUB_APP_ID, - privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + appId: appCfg.CLIENT_APP_ID_GITHUB_APP, + privateKey: appCfg.CLIENT_PRIVATE_KEY_GITHUB_APP, installationId: authMetadata.installationId } }); diff --git a/backend/src/services/integration-auth/integration-list.ts b/backend/src/services/integration-auth/integration-list.ts index 8019ae9b8..af9d358ed 100644 --- a/backend/src/services/integration-auth/integration-list.ts +++ b/backend/src/services/integration-auth/integration-list.ts @@ -140,7 +140,7 @@ export const getIntegrationOptions = async () => { isAvailable: true, type: "oauth", clientId: appCfg.CLIENT_ID_GITHUB, - clientSlug: appCfg.CLIENT_SLUG_GITHUB, + clientSlug: appCfg.CLIENT_SLUG_GITHUB_APP, docsLink: "" }, { diff --git a/backend/src/services/integration-auth/integration-sync-secret.ts b/backend/src/services/integration-auth/integration-sync-secret.ts index a46b62f5e..6b81b31a8 100644 --- a/backend/src/services/integration-auth/integration-sync-secret.ts +++ b/backend/src/services/integration-auth/integration-sync-secret.ts @@ -1565,8 +1565,8 @@ const syncSecretsGitHub = async ({ octokit = new Octokit({ authStrategy: createAppAuth, auth: { - appId: appCfg.GITHUB_APP_ID, - privateKey: appCfg.GITHUB_APP_PRIVATE_KEY, + appId: appCfg.CLIENT_APP_ID_GITHUB_APP, + privateKey: appCfg.CLIENT_PRIVATE_KEY_GITHUB_APP, installationId: authMetadata.installationId } }); diff --git a/backend/src/services/integration-auth/integration-token.ts b/backend/src/services/integration-auth/integration-token.ts index 6daacd62a..9b4e5c20f 100644 --- a/backend/src/services/integration-auth/integration-token.ts +++ b/backend/src/services/integration-auth/integration-token.ts @@ -249,7 +249,7 @@ const exchangeCodeGithub = async ({ code, installationId }: { code: string; inst if (installationId) { // handle app installations - const res = ( + const oauthRes = ( await request.get(IntegrationUrls.GITHUB_TOKEN_URL, { params: { client_id: appCfg.CLIENT_ID_GITHUB_APP, @@ -276,7 +276,7 @@ const exchangeCodeGithub = async ({ code, installationId }: { code: string; inst }>(IntegrationUrls.GITHUB_USER_INSTALLATIONS, { headers: { Accept: "application/json", - Authorization: `Bearer ${res.access_token}`, + Authorization: `Bearer ${oauthRes.access_token}`, "Accept-Encoding": "application/json" } }) @@ -293,14 +293,14 @@ const exchangeCodeGithub = async ({ code, installationId }: { code: string; inst } return { - accessToken: "", + accessToken: "", // for github app integrations, we only need the installationID from the metadata refreshToken: null, accessExpiresAt: null, installationName: matchingInstallation.account.login }; } - // handle normal oauth + // handle oauth github integration const res = ( await request.get(IntegrationUrls.GITHUB_TOKEN_URL, { params: { From 4a1adb76ab2aad5bccba35f74ae12e0de00790b7 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 15 Oct 2024 18:21:02 +0800 Subject: [PATCH 07/54] misc: finalized auth method selection ui/ux --- .../github/auth-mode-selection.tsx | 81 ++++++++++++------- 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/frontend/src/pages/integrations/github/auth-mode-selection.tsx b/frontend/src/pages/integrations/github/auth-mode-selection.tsx index e5f96636f..d47d22ec6 100644 --- a/frontend/src/pages/integrations/github/auth-mode-selection.tsx +++ b/frontend/src/pages/integrations/github/auth-mode-selection.tsx @@ -1,5 +1,6 @@ import crypto from "crypto"; +import { useState } from "react"; import Head from "next/head"; import Image from "next/image"; import Link from "next/link"; @@ -7,13 +8,27 @@ import { useRouter } from "next/router"; import { faArrowUpRightFromSquare, faBookOpen } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Button, Card, CardTitle } from "@app/components/v2"; +import { + Button, + Card, + CardBody, + CardTitle, + FormControl, + Select, + SelectItem +} from "@app/components/v2"; import { useGetCloudIntegrations } from "@app/hooks/api"; +enum AuthMethod { + APP = "APP", + OAUTH = "OAUTH" +} + export default function GithubIntegrationAuthModeSelectionPage() { const router = useRouter(); const { data: cloudIntegrations } = useGetCloudIntegrations(); const githubIntegration = cloudIntegrations?.find((integration) => integration.slug === "github"); + const [selectedAuthMethod, setSelectedAuthMethod] = useState(AuthMethod.APP); return (
@@ -50,37 +65,41 @@ export default function GithubIntegrationAuthModeSelectionPage() {
-
- - -
+ window.location.assign( + `https://github.com/login/oauth/authorize?client_id=${githubIntegration?.clientId}&response_type=code&scope=repo,admin:org&redirect_uri=${window.location.origin}/integrations/github/oauth2/callback&state=${state}` + ); + } + }} + colorSchema="primary" + variant="outline_bg" + className="mb-4 mt-4 ml-auto w-min" + > + Connect to Github + +
+
); From 82c8ca9c3d5376a1f68e2de37c3a803d599daa5d Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 15 Oct 2024 19:04:40 +0800 Subject: [PATCH 08/54] misc: added auto redirect to new connection flow --- .../integrations/select-integration-auth.tsx | 124 ++++++++++-------- 1 file changed, 72 insertions(+), 52 deletions(-) diff --git a/frontend/src/pages/integrations/select-integration-auth.tsx b/frontend/src/pages/integrations/select-integration-auth.tsx index 6bfa0ae6e..3c71ad0b3 100644 --- a/frontend/src/pages/integrations/select-integration-auth.tsx +++ b/frontend/src/pages/integrations/select-integration-auth.tsx @@ -1,11 +1,11 @@ import crypto from "crypto"; -import { useCallback } from "react"; +import { useCallback, useEffect } from "react"; import Head from "next/head"; import Image from "next/image"; import { useRouter } from "next/router"; -import { Button, Card, CardTitle } from "@app/components/v2"; +import { Button, Card, CardTitle, ContentLoader } from "@app/components/v2"; import { useOrganization, useWorkspace } from "@app/context"; import { useDuplicateIntegrationAuth, @@ -31,52 +31,77 @@ export default function SelectIntegrationAuthPage() { // for Github, we want to reuse the same connection across the Infisical organization // when we do need to reuse this page for other integrations, add handling to fetch workspace integration auths instead - const { data: integrationAuths, isLoading: isLoadingIntegrationAuths } = - useGetOrgIntegrationAuths( - orgId, - useCallback( - (data: IntegrationAuth[]) => { - const filteredIntegrationAuths = data.filter( - (integrationAuth) => integrationAuth.integration === integrationSlug + const { + data: integrationAuths, + isLoading: isLoadingIntegrationAuths, + isSuccess: isLoadingIntegrationAuthsSuccess + } = useGetOrgIntegrationAuths( + orgId, + useCallback( + (data: IntegrationAuth[]) => { + const filteredIntegrationAuths = data.filter( + (integrationAuth) => integrationAuth.integration === integrationSlug + ); + + if (integrationSlug === "github") { + const sameProjectIntegrationAuths = filteredIntegrationAuths.filter( + (auth) => auth.projectId === currentWorkspace?.id + ); + const differentProjectIntegrationAuths = filteredIntegrationAuths.filter( + (auth) => auth.projectId !== currentWorkspace?.id ); - if (integrationSlug === "github") { - const sameProjectIntegrationAuths = filteredIntegrationAuths.filter( - (auth) => auth.projectId === currentWorkspace?.id - ); - const differentProjectIntegrationAuths = filteredIntegrationAuths.filter( - (auth) => auth.projectId !== currentWorkspace?.id - ); + const installationIds = new Set(); - const installationIds = new Set(); + // for now, we only display the integration auths for Github apps + return ( + // we concatenate it this way so that integration auths from the same project are prioritized for display + sameProjectIntegrationAuths + .concat(differentProjectIntegrationAuths) + .filter((integrationAuth) => Boolean(integrationAuth.metadata?.installationId)) + // we filter it so that we only show unique installations because the same installation/connection + // can be used in multiple integration auths + .filter((integrationAuth) => { + const isProcessedInstallationId = installationIds.has( + integrationAuth.metadata.installationId as string + ); - // for now, we only display the integration auths for Github apps - return ( - // we concatenate it this way so that integration auths from the same project are prioritized for display - sameProjectIntegrationAuths - .concat(differentProjectIntegrationAuths) - .filter((integrationAuth) => Boolean(integrationAuth.metadata?.installationId)) - // we filter it so that we only show unique installations because the same installation/connection - // can be used in multiple integration auths - .filter((integrationAuth) => { - const isProcessedInstallationId = installationIds.has( - integrationAuth.metadata.installationId as string - ); + if (!isProcessedInstallationId) { + installationIds.add(integrationAuth.metadata.installationId as string); + } - if (!isProcessedInstallationId) { - installationIds.add(integrationAuth.metadata.installationId as string); - } + return !isProcessedInstallationId; + }) + ); + } - return !isProcessedInstallationId; - }) - ); - } + return []; + }, + [integrationSlug] + ) + ); - return []; - }, - [integrationSlug] - ) - ); + const handleNewConnection = () => { + const state = crypto.randomBytes(16).toString("hex"); + localStorage.setItem("latestCSRFToken", state); + + if (integrationSlug === "github") { + // for now we only handle Github apps + window.location.assign( + `https://github.com/apps/${currentIntegration?.clientSlug}/installations/new?state=${state}` + ); + } + }; + + useEffect(() => { + if ( + !isLoadingIntegrationAuths && + integrationAuths?.length === 0 && + isLoadingIntegrationAuthsSuccess + ) { + handleNewConnection(); + } + }, [isLoadingIntegrationAuths, integrationAuths, isLoadingIntegrationAuthsSuccess]); const logo = integrationSlug === "github" ? "/images/integrations/GitHub.png" : ""; @@ -96,17 +121,12 @@ export default function SelectIntegrationAuthPage() { } }; - const handleNewConnection = () => { - const state = crypto.randomBytes(16).toString("hex"); - localStorage.setItem("latestCSRFToken", state); - - if (integrationSlug === "github") { - // for now we only handle Github apps - window.location.assign( - `https://github.com/apps/${currentIntegration?.clientSlug}/installations/new?state=${state}` - ); - } - }; + if ( + isLoadingIntegrationAuths || + (integrationAuths?.length === 0 && isLoadingIntegrationAuthsSuccess) + ) { + return ; + } return (
From 192d1b0be33aefb306aad4fa09ba07607a6c5d41 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 15 Oct 2024 19:07:39 +0800 Subject: [PATCH 09/54] misc: finalized ui design --- frontend/src/pages/integrations/github/auth-mode-selection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/integrations/github/auth-mode-selection.tsx b/frontend/src/pages/integrations/github/auth-mode-selection.tsx index d47d22ec6..514e48b4c 100644 --- a/frontend/src/pages/integrations/github/auth-mode-selection.tsx +++ b/frontend/src/pages/integrations/github/auth-mode-selection.tsx @@ -94,7 +94,7 @@ export default function GithubIntegrationAuthModeSelectionPage() { }} colorSchema="primary" variant="outline_bg" - className="mb-4 mt-4 ml-auto w-min" + className="mt-4 ml-auto w-min" > Connect to Github From 986bcaf0df8f16333c3cde695cb2cd598f3d94f9 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Tue, 15 Oct 2024 16:20:48 +0400 Subject: [PATCH 10/54] feat: cloud EU region support --- cli/packages/cmd/login.go | 28 ++++++++++++++++++---------- cli/packages/cmd/root.go | 2 +- cli/packages/cmd/user.go | 3 ++- cli/packages/util/constants.go | 4 ++-- cli/packages/util/init.go | 4 ++-- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/cli/packages/cmd/login.go b/cli/packages/cmd/login.go index f66197517..6cba897f3 100644 --- a/cli/packages/cmd/login.go +++ b/cli/packages/cmd/login.go @@ -216,7 +216,9 @@ var loginCmd = &cobra.Command{ } //override domain domainQuery := true - if config.INFISICAL_URL_MANUAL_OVERRIDE != "" && config.INFISICAL_URL_MANUAL_OVERRIDE != util.INFISICAL_DEFAULT_API_URL { + if config.INFISICAL_URL_MANUAL_OVERRIDE != "" && + config.INFISICAL_URL_MANUAL_OVERRIDE != fmt.Sprintf("%s/api", util.INFISICAL_DEFAULT_EU_URL) && + config.INFISICAL_URL_MANUAL_OVERRIDE != fmt.Sprintf("%s/api", util.INFISICAL_DEFAULT_US_URL) { overrideDomain, err := DomainOverridePrompt() if err != nil { util.HandleError(err) @@ -526,16 +528,17 @@ func askForDomain() error { // query user to choose between Infisical cloud or self hosting const ( - INFISICAL_CLOUD = "Infisical Cloud" - SELF_HOSTING = "Self Hosting" - ADD_NEW_DOMAIN = "Add a new domain" + INFISICAL_CLOUD_US = "Infisical Cloud (US Region)" + INFISICAL_CLOUD_EU = "Infisical Cloud (EU Region)" + SELF_HOSTING = "Self Hosting" + ADD_NEW_DOMAIN = "Add a new domain" ) - options := []string{INFISICAL_CLOUD, SELF_HOSTING} + options := []string{INFISICAL_CLOUD_US, INFISICAL_CLOUD_EU, SELF_HOSTING} optionsPrompt := promptui.Select{ Label: "Select your hosting option", Items: options, - Size: 2, + Size: 3, } _, selectedHostingOption, err := optionsPrompt.Run() @@ -543,10 +546,15 @@ func askForDomain() error { return err } - if selectedHostingOption == INFISICAL_CLOUD { - //cloud option - config.INFISICAL_URL = fmt.Sprintf("%s/api", util.INFISICAL_DEFAULT_URL) - config.INFISICAL_LOGIN_URL = fmt.Sprintf("%s/login", util.INFISICAL_DEFAULT_URL) + if selectedHostingOption == INFISICAL_CLOUD_US { + // US cloud option + config.INFISICAL_URL = fmt.Sprintf("%s/api", util.INFISICAL_DEFAULT_US_URL) + config.INFISICAL_LOGIN_URL = fmt.Sprintf("%s/login", util.INFISICAL_DEFAULT_US_URL) + return nil + } else if selectedHostingOption == INFISICAL_CLOUD_EU { + // EU cloud option + config.INFISICAL_URL = fmt.Sprintf("%s/api", util.INFISICAL_DEFAULT_EU_URL) + config.INFISICAL_LOGIN_URL = fmt.Sprintf("%s/login", util.INFISICAL_DEFAULT_EU_URL) return nil } diff --git a/cli/packages/cmd/root.go b/cli/packages/cmd/root.go index e40c07022..c533f3415 100644 --- a/cli/packages/cmd/root.go +++ b/cli/packages/cmd/root.go @@ -40,7 +40,7 @@ func init() { cobra.OnInitialize(initLog) rootCmd.PersistentFlags().StringP("log-level", "l", "info", "log level (trace, debug, info, warn, error, fatal)") rootCmd.PersistentFlags().Bool("telemetry", true, "Infisical collects non-sensitive telemetry data to enhance features and improve user experience. Participation is voluntary") - rootCmd.PersistentFlags().StringVar(&config.INFISICAL_URL, "domain", util.INFISICAL_DEFAULT_API_URL, "Point the CLI to your own backend [can also set via environment variable name: INFISICAL_API_URL]") + rootCmd.PersistentFlags().StringVar(&config.INFISICAL_URL, "domain", fmt.Sprintf("%s/api", util.INFISICAL_DEFAULT_US_URL), "Point the CLI to your own backend [can also set via environment variable name: INFISICAL_API_URL]") rootCmd.PersistentFlags().Bool("silent", false, "Disable output of tip/info messages. Useful when running in scripts or CI/CD pipelines.") rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) { silent, err := cmd.Flags().GetBool("silent") diff --git a/cli/packages/cmd/user.go b/cli/packages/cmd/user.go index 844213e18..d3e6096a9 100644 --- a/cli/packages/cmd/user.go +++ b/cli/packages/cmd/user.go @@ -2,6 +2,7 @@ package cmd import ( "errors" + "fmt" "net/url" "github.com/Infisical/infisical-merge/packages/config" @@ -119,7 +120,7 @@ var domainCmd = &cobra.Command{ domain := "" domainQuery := true - if config.INFISICAL_URL_MANUAL_OVERRIDE != util.INFISICAL_DEFAULT_API_URL { + if config.INFISICAL_URL_MANUAL_OVERRIDE != fmt.Sprintf("%s/api", util.INFISICAL_DEFAULT_EU_URL) && config.INFISICAL_URL_MANUAL_OVERRIDE != fmt.Sprintf("%s/api", util.INFISICAL_DEFAULT_US_URL) { override, err := DomainOverridePrompt() if err != nil { diff --git a/cli/packages/util/constants.go b/cli/packages/util/constants.go index 1f9ec0c65..8b4c586e6 100644 --- a/cli/packages/util/constants.go +++ b/cli/packages/util/constants.go @@ -3,8 +3,8 @@ package util const ( CONFIG_FILE_NAME = "infisical-config.json" CONFIG_FOLDER_NAME = ".infisical" - INFISICAL_DEFAULT_API_URL = "https://app.infisical.com/api" - INFISICAL_DEFAULT_URL = "https://app.infisical.com" + INFISICAL_DEFAULT_US_URL = "https://app.infisical.com" + INFISICAL_DEFAULT_EU_URL = "https://eu.infisical.com" INFISICAL_WORKSPACE_CONFIG_FILE_NAME = ".infisical.json" INFISICAL_TOKEN_NAME = "INFISICAL_TOKEN" INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN_NAME = "INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN" diff --git a/cli/packages/util/init.go b/cli/packages/util/init.go index 33350f3b7..fe705999a 100644 --- a/cli/packages/util/init.go +++ b/cli/packages/util/init.go @@ -11,7 +11,7 @@ func GetOrganizationsNameList(organizationResponse api.GetOrganizationsResponse) organizations := organizationResponse.Organizations if len(organizations) == 0 { - message := fmt.Sprintf("You don't have any organization created in Infisical. You must first create a organization at %s", INFISICAL_DEFAULT_URL) + message := fmt.Sprintf("You don't have any organization created in Infisical. You must first create a organization at %s", INFISICAL_DEFAULT_US_URL) PrintErrorMessageAndExit(message) } @@ -37,7 +37,7 @@ func GetWorkspacesInOrganization(workspaceResponse api.GetWorkSpacesResponse, or } if len(filteredWorkspaces) == 0 { - message := fmt.Sprintf("You don't have any projects created in Infisical organization. You must first create a project at %s", INFISICAL_DEFAULT_URL) + message := fmt.Sprintf("You don't have any projects created in Infisical organization. You must first create a project at %s", INFISICAL_DEFAULT_US_URL) PrintErrorMessageAndExit(message) } From cf092d8b4f39c970fde80e5e5e684c127f5544c1 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 15 Oct 2024 21:01:37 +0800 Subject: [PATCH 11/54] doc: updated github action docs --- .../github/app/github-app-installation.png | Bin 0 -> 294158 bytes .../app/github-app-method-selection.png | Bin 0 -> 515398 bytes .../github/app/integration-overview.png | Bin 0 -> 912035 bytes .../self-hosted-github-app-basic-details.png | Bin 0 -> 303769 bytes .../self-hosted-github-app-create-confirm.png | Bin 0 -> 314022 bytes .../app/self-hosted-github-app-create.png | Bin 0 -> 238508 bytes .../self-hosted-github-app-credentials.png | Bin 0 -> 415229 bytes .../self-hosted-github-app-organization.png | Bin 0 -> 391870 bytes .../self-hosted-github-app-private-key.png | Bin 0 -> 245192 bytes .../app/self-hosted-github-app-repository.png | Bin 0 -> 371698 bytes .../app/self-hosted-github-app-secret.png | Bin 0 -> 338103 bytes .../app/self-hosted-github-app-webhook.png | Bin 0 -> 291086 bytes .../github/github-oauth-method-selection.png | Bin 0 -> 509195 bytes .../github/integration-overview.png | Bin 0 -> 912035 bytes docs/integrations/cicd/githubactions.mdx | 116 +++++++++++++++++- 15 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 docs/images/integrations/github/app/github-app-installation.png create mode 100644 docs/images/integrations/github/app/github-app-method-selection.png create mode 100644 docs/images/integrations/github/app/integration-overview.png create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-basic-details.png create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-create-confirm.png create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-create.png create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-credentials.png create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-organization.png create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-private-key.png create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-repository.png create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-secret.png create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-webhook.png create mode 100644 docs/images/integrations/github/github-oauth-method-selection.png create mode 100644 docs/images/integrations/github/integration-overview.png diff --git a/docs/images/integrations/github/app/github-app-installation.png b/docs/images/integrations/github/app/github-app-installation.png new file mode 100644 index 0000000000000000000000000000000000000000..60a2ec4fcd7c787527d35940cd0aa137fe24cfdd GIT binary patch literal 294158 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

z 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

c%@dW>JK@_M6ws42yZR?i(9Sn^D$wtQ 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%0D=e7wi=F)5IT9P$zaPU2I5 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

Manage SCIM configuration

+

Enable SCIM

diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgNameChangeSection/OrgNameChangeSection.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgNameChangeSection/OrgNameChangeSection.tsx index 8b5d52d31..b24f2a205 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgNameChangeSection/OrgNameChangeSection.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgNameChangeSection/OrgNameChangeSection.tsx @@ -12,8 +12,8 @@ import { useOrganization, useOrgPermission } from "@app/context"; +import { isCustomOrgRole } from "@app/helpers/roles"; import { useGetOrgRoles, useUpdateOrg } from "@app/hooks/api"; -import { isCustomOrgRole } from "@app/views/Org/MembersPage/components/OrgRoleTabSection/OrgRoleTable"; const formSchema = yup.object({ name: yup From 08ed544e523d0cdc0caa0b1513c7d6cc01179c61 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Wed, 16 Oct 2024 01:38:13 +0800 Subject: [PATCH 13/54] misc: added missing section regarding enabling of user auth --- .../self-hosted-github-app-enable-oauth.png | Bin 0 -> 353580 bytes docs/integrations/cicd/githubactions.mdx | 3 +++ 2 files changed, 3 insertions(+) create mode 100644 docs/images/integrations/github/app/self-hosted-github-app-enable-oauth.png diff --git a/docs/images/integrations/github/app/self-hosted-github-app-enable-oauth.png b/docs/images/integrations/github/app/self-hosted-github-app-enable-oauth.png new file mode 100644 index 0000000000000000000000000000000000000000..45d50c7b29800ccf26d443a4cb47c6775f6a8ddb GIT binary patch literal 353580 zcmeEuXIN9)wl+-=l_IDJND&1@dY2N)rYd#QYl6}VJ@imTv4GN~LqJ48>Ag2W=?Ojb zBE5uO6CmGm_q)%%&vVZH^ZhySBw4Jr#++-;ImR6Cc*h8@v^7;IE-_ppARwT4sH&(# zKybN_fPl2{A}Mf&EI_c1fZ&R}y@G=FLj?s^ZFd(Ndq-;m0@YV>hGa&%oi`AsF;Q}M zgd|zdrb(h12gnv@X<7(9OjzJ-7e)}!j7v;uPmRQtRjROqiH3$4d(f}>TbsV^^<$OmJKak>(lBB1nk!-RZ=N~*YrCE_i9$P z6)ISssNB|KC6RkWS)!$h)MIYrqBd1vyxOJ{pu9#Uxf(R6&NQ;%I`E>zpRY9Y8f(XO zYnaVx`s(ovJEy78LMx3y+!Z&~2oI!yOI2BR*u#=bZ2@0~UaGzny?xF)+qrRDnTtLq z%BKe8(A;a?l1j+*lF2tUSl}fEDCe@V9oBeuLQ zmhx5C@>*jbRzxuT(=5Mhn^2Pugo@pGNB#Nv`V|?|_mQ7&*tD_#bj6U-2EniTGT7+) zlNXcuqXN%+N55P#Xp4GdM04lO%&qS?8wExog^`OnuR@<(J7kxrQP}$`W_xk;>Lq_x z{yTh%2$uZk-O*pEmY*g(91f7kvXq+GrupmeSe;m+IP=a`uGwxr4cJZUkJ&F zp1^f0B6(AY0!w}D5eXqBb*M)(+2JJ{JH^a=m5W6s8PuobS6LP)Bli*xcI9OjnkdV5 z^FXSx2TR?`Rv|gm%fSLs6kF`2KYw}bLOx4wMS|Z(hQwW-?+w!*$8Vk7K9p*Gre6It z`igH>9)&Rt@hieM>L=9wr0DhlSAOYR;4=%)FZ9*zebS8+vKUNq9-< zsPBe|*Hx)7Q36RX8fcqI$-ItqeJ!HH03B6z(^%SATV&=Cg1)|`699vL8!>jlJaq6^@t;wgd1luwa z4<7jJOVRn!1fOlX;#f|Q#=^5X3iQF3RjO&+8dF<8(h>Qq<+h|{lSKs67l-Y+5ji(s zJ`RzizQiVfOO+`0@jkt4T6l|xz~vsYuNl|!383;9MoB84rdd!uAYf<~bY(~-PH540 zrJW4T%VDf1IGbfUj$pk={+>-lkxEdRhgzzQ{4uMHDl5&~Hr9u#mtx*tyh<)~**N$e zTVB*9tIIl}8!B&EbE3mlrQFGUpY5|1MQhy)`SeGlyF-|AD5nhwp|l{-{pKM++rw;W!NWtN_H95wP>hVbrK{K>pAz~M zbs{

fkYp8=Ge9YBk8L<+hJB@@vi;w1`p! z5K)?mn)f)~U9F_0q(y#d7}D@jxl7~u(m>I>nlAQbQd?5n$2N+#hBnM5E;uc4>|S>lKM__6eWJ9J-S)E(*B;m6JIOBNu7EB^Yiny=YpO*% z>yTaPMfb&kF1mLtTtRyMdL{agKdI|Q=kn-|y?1}K__mAjew@R@gAW|Kd%4}YqC>(% zFNUZ-i|CW-SKin1EOhwj(6A;toZw(3dRa7k+^XWI3ZaTn2g4!kQ0H3w8jt5&?5%@G z2Y1$()`%HI-Uu>8Ge|I~iF(l_8=oR69kf3mt-N3UxuVuZqvEgv zVPozT&>CjfTHIMWW&s<%QQ=w9TU=1y@Z`mK%^3NH*l0y0Tg2{7_FMX(&#mCE2>Wyw z2o&ET-+p`YeaHKjxkbCZ{>~4EZ)Ie$DIfAIE9b@9;g%xp&)#w|42mpO#1_z^KMkyg z2@gwj_!h!G>~Ygc(KU7}CrlKIpxp|?%~H&pYHR9VO|4D(P4!OcPUcNY-86}~_f6;9 z1*)enn%d1GEty$BQ__3VR6gg6)?0Cl72SEZ`NKx%qfVA}^%@Nl)28)O0V^_GGARL) z0UG`ijl+$RXFaDrffHv4L8ru|o~fRM^S9?u@U7=t#)$l}d|g5#Iaj%da;6zJ7XB7W zv#qRy8T%RI8Rr)0*`$`7pDx~he4ATAax~15uP$tgWsO-i*BzLO0;>pl>X^y0)f=-UFRdA(pk?CIKdc{?z)9A`3F`OEr=jEX9Ae->j zygi_0Z@yse06-{t$Ebn&L4%J6S@4`9&8^<;-h16Ew8bRXpBg6JPD&A)u~o9cbTIU2 z_DrXIco!Q3Q_SV+p{Z0CO*RpzFt_5of5TIAFSXLkr0IcrJ&3L|?cGFT&V`@_Q}&S< z$lb`@fL-oAS#_<%z+$-%az=fUtzO?^=uwwKF9oH%LMrX z;=X@VIgQcA%;4$jY5%j=2ax+h_ni%}hMNUK zxh6UXfy6GY6>kC=*Tv|a?@#U9ms#v#cw0=@@_6&QD`~2hTmou&A5Waj+-w?lM9+Y0 z&(`AyPpxLeH%VMAFWmDmev=q?7l+u=8Vg#N z8x2_sjR^I8!9%Ifl+DEVNoCD;=t$g3#6yfjw33A!G%&d^>~Wmi+RxOk{#KtEEz@{P zve@>8Hk9+S7G)|;+L}~aU~Qi7qrC>7>2kt4fqVtJLuv@4{6cJY^ zyl(QWvwWhm>@J;%lxk-Dgo>5S<-6sPo7;BCL1nxbQ^H?nzPlP2l?gc(S| z**vZe@(M!H2*xUJ^}em*b4ek~BxP>w_B}cY=p<{Pl9CmYLEzsVuZ}IRLR2ALP2>Jf z*c*qKa|`5b#>+cP9f21FjQYz(2*6te!O0{96bRHk+J$9VWBCPJ19~Dnc{l21>332& zrqiIv&CnomCW4I#(nyFl#EFgIXFY=N(gbT8(q=D^4yCY<<VM1juu3uTP{TGKwkia<;eZ*BC@Mni+(K5%@I-~u5H0Woky2>cQdG7wz& z<(Por5h3Fr$2x@fe!GW=fZ&Ba0m*Oom;j$YexiUEApP4XaZDHi8Sobk@OqX(^!weH z`!a}sKPD{%t`W%VDm;7$eCk@dTU$HB>|8uzE^I)76XdR{#xMec8|*(`gb#J@ZW9m? zP1)-ic^GM^OIo@(@jbS3d1B4y6*TKm}l*^@Kuw_yPT z{o0-MkH#eRVb<;nE>2F?&K@#<&bah1J^hc1e?I50g4*^z){aJs_JAY|7?X^!fRM;< zVt>E%zls|FDJm!~DDYR&zg+r@=#N22>R7{E96f(bqQ0}ehm4Rk|NnOS?@~s8ipdCy zi0}*kCid6!f0r@-KV<%T{_iqc?)JbuKK}7|GQaon*K@z!FU|i$0sf*8ziQhrX90DS zxg^d1hw92)N^v@oAs~<=c&I3^=R>$LMP5&_h;QC0;)!nfs`)aC=l$2l%F(0JY#L*= z1DDuGb%DI)DqRe5rFYA@q@wRBzAt^=#ZY<|zbus`D1792G!5GV9U)MAe&)9EwumHO zlzS?y5#=qk*a?|^r%f$KKuGcr-a2N9Y^}G?ERX(y>@QswlU&SLR{V#(zr0LHv@-u) zpe*(xYcK)PfBr_&2c!IFk{8>a6A-uXO_YmjDYmkr^+=KWvq{hxT_|9bEL zWVU|s_y6_Y{}5^Z7o7jcp~?SWaNa>f2k-p1F{+haNLiU}g8vCJ&a4Kec6e)9HJ-=# zu5PwEyp-;$2lk0RQIX zwSN8f?_%#!qUE%pkZasO4|IwI9dAFD@Y{Eh2t2J$mG&Jd{Kidmv8`HesV9luw9+vK z1gGpw63(fpNKOjGjXM{d24GeoUcBBSNPHVy#dmHxB1T(uiZD( z6SD5Q`+|yv!$(HH&6u3Xo-;#!->+a@v?OBZzs|Re_;^&< zrTYELNCms2i)x%0R9 zIEs)&B&yV7bpQ#$NO}r2gTEsA${mNhXr+rxN9uj|f*FlUtvWMW_6X@-es3crCgZRx zfZ)%`vjqtWNd}taOw6_lOsfu?tvh3s#=Tc&lfGU2AL<#!?d^PdZl%AeMUEik0Znm{ zFOHd7r4Cv6+d9f!0;2YGqFj;xh3c>iTch9zZ#>IMqkbC49!|%ZSYbc^jbzZ{DQN{( z7{wy#p&HL?em^|``>9^o?Md@url8w<-`(IQ9`n*R*;j5P18H(k3eg@_u!obg<<-+@ zm(eH-C>>d~EJtn|$zN6dC3nb%1hVAt=y+$|tzu?_hiHe-0 z_bl!ID*0>3&zd3kiiSO3<E;K?(M{IbFc^o-fHjE$gwO4IRa6 zU5BuqCyPR}o;<%a&~IhG>D$dKbo!j`G+fci|I6{tF0klQ7^jI^edVT;Y+)p@W$UvF zqM?3M?QPE9zo?6%D->1G~C-WIj`IJlmh;BKm;MVmnNNsx@C8_TXiN$ri1WP-trS8 zauDxTbWY?cZmVhYA(vSG`X@+L;X5u}<+sdI$`;Vq4+jN^?D?Yr9ggH6Zt%MJS+Aya zW3(E)fP+l3F^jko`% zufcM)G^156=_`<2cccU!lx?ZK0z68JA|6xwc#=ov|{+@3ga6&wY8mySdOgcY{g-KM6y{5mwFc zUB9mvm8lf|2-y4IXuuI$aocrmqo2~RvGcO34S5vDtu|Hb z`BC`|gU;di@B+`=&Mh0J!5ocP!1_#pDV%O^IfIa z*P@&7=M#S4zl@7Q^Y`ve4qn4j-DH)3EtMw^!xjtrKTPFad|;NVeY>Vah01ms@Ca$J zI}+%;L5tv!w@gxx;Cngi$TX>{Thgv_UYq0WEb2)#{Q;dbSqMwNqJh1S!8I(amR&*k zGw-p+fV!SU8FQJl1zJ2C`8O!Kkhfxe$Su1Gw^>)}*?j|wW4%Y{U#z)_btQ*Wc(;H{nIKEHok1 zH(7Mw@YDDD_ET&(f9W^J!G(vhR`Xi2#=~dJqvG5K9SKVTY$c1O-F&fmMK#}y9hX#C zI{o$#w1q1t2A@6b^OBjH62Sg~3k~2mjH1pw2W!Kz_ibj}mpd&%or*KDH~3BNswMDU z50F(?w;!pmDYqNbd6W#tU0AvW^4rfnJ)CeUwVzjB570-Uwb?%{=hSHg$mUxk_ed!i zO^&P@+BYU^bocE^)o$>|pDYEa&cN>di_QFD^|^A{(kGWwpA!A60bXR!kRK=3D6TaZ zbD8F$P~SE$*2y#A_1#%aC?FWH@D%AgcBWl88_P-WO7>j83u*M%99HHaKvHUYa3Glb zwb;)Z(!M?Wt3OHAk_b6w&C%I`V2Xt1HCr%p<|QoasJn3p=IjP}T#cP*USGjt%>BLy&S+ zA^~p3YannlKmuoOM)Re?_X~Y!ca2YMUA_UnjJnpj*CG* zX-?bKkY3L(v#MTA94HKc&!j&4;HTlSKCbVTXn7;o5vE}{p~GP$Zno-N_&f&@IR2>; zISDNkmhb9p0LzM|+5G}trdp0>_{(fj@fSDFEJDZ>;3DDPb1(UyjQ zZ#4#1g<+|Td;w}GG2R;8naBK`7b~ZM_F9jyo32W`UPCHmi{vS4Jg*gT8W#z9lb7s& zy3;PyQO^$!Iy=}MDt?U2X9+x(FKoa%*h&wCM1N3zMVdKb{pA^X=CXcu=}10mb12I* zv>|9M@QrZgcoK(RKin#4@YUnD66vkiF+JNEzAkP}LAZqeqgTUAASD#eA}uS%FK~Q) z0G~by+iF05j5VR~$c!m=Ad3zROyG6H(U`;Z}6v9nm#= z8y5<7&jh4=>1f^hiYp5(!4@AwDwGUWm&0jeMEpcl4W66HbYtJA;Rf49qXhKHk?giy z$E@-Vm`F>zs#Jj*ho8`M6MVv-8}};5?2a z&+~4}-Z(g^)Y>|loQEHXbno`I>!p?T(sDKm7`H22K&_Le!;lgqXC?M!Hn*$rUlYJF zk5SUJKfBi2JVI-7TYh_Uc`O^A4UR-5Q!1a&`g*7B3*G9)Rm#j+yk8~hpCl=LQP!Um z#v`gV+HothOh5nT4L&oY_@F(F(OKUqaDaQ~y}=!IRExHfRQ8I*wfjEc1oV*u#-qH= zXtm^ZmZD#vLk__iKFn+P@=*{`T2WejqX^Sr%;4&s7);Lp8NSJFTn2Juxb~O4f6tAv zPF=K%nuKz|Tr%V;ft}t^q}a5qxwdD2edOP z5M;Lo-Ld^J61?j;R{Gp50XdWb_3r2C?&Q+XGq~P+AH(lNmexP!eLoZ?c$zH-8}VOFy=4qfDkrI0my^^237J5*SP zh8;${(VTaVRM+AnS1(++WR!#==A*ttdyt&$B1wB)U}BBWul^7-!P#_<&0E1m zG_6P+FX(EWaGK6DNEc~&U(`EQ_F}?FXC6J9lt;qr5RJ-yfyh)*H3xJd20X+t!r8YH zcy`jxLOvZ?VHqiN_4)q-_kIO_)H6Rafk!*GTYsAJuLk+@bMp#8Qss}xPCQAj?s7O? zLb!&_D$Uo|oo5`T`J~nM{T4bD+m{WenWe2QSO^3wV+Kg&uVl*m5F|KO0%0c>xWI#ghKPFaL$_} z7Rzi(uYIy3Z^}#xBSx>*2|p)=z7?l0HBIh89`1a0+7NS^Ow8z%GhR73_M|92+gt99 zH4%lHIK^|BoABKSz>@EY_42KY2}}|#U7_lIuyU=LMnsJtqCwQJyc|0CP4dvMa0Sbm z!fG=G@vgD#V?DBKp0hKypXc)BC7tw{QKYCJX7%$nuJbDJG}mw3*Xe#(MAu*wgu{q? zivm1CkzISjJD&bVFa|ySWksZ<6LEtBJCNm6lh((kK;R8`NUhC85 zBHeX$db!&29<_D3gN)fg-Q_1`{rmbc?JRJfmNWCRi6$rMJG}3aD1hHkWiMm)9;<*R ztVkHYH~hju3!2~u=MbH_4XGUohC476KNQ^? zYd^1#8}cINt=dgl9697OFYOS<%_p%);C{}x``H!|xNM12zbT7MVh$&6IpqB`VN&C6 zy)K<+TBSK^`96JkKXphph=>BzcqomB*0|3#@q6;8(=03M1Q=2N4$o8z<&Ggav2~>J zzY;HhacMwV!-_M}+9|!WXr7bPoEErBX&})abZx4kgVpR%0qBq;)G@X85GMHn!E();gLA ziQ8D@>HzF*KbjHJBWC<+DkO?sgCM)9{&+x*T&M}^b=uhIG}63c8%7bU#3ARg3*TZl z`ZnX7HD6#-b$Dv@Nxt_Dqu4b}+Zxg|I#+FLS zJK_XwEhpoqj%-*k@EC(Wc>7@El^HAvm3RN*u+z@>ubZ9j0QpKgDPS}$ynO5tt1&UP z`Gc`bPlnz%>*stbBHVJABIe}&nY2rBvq$}#oXX(OUuFa|3{i+oLR9~~{%V&Q0LYMw zEfz{`sk<_-?O+D$s#a*Zut~_PCE(ML@9XFyDj(iLvl^YX;ZJvF3c;9qeyD{a?H==Y znRMkOO$9Go7Whm>Y==5J_6`u~bAM2NTYe4}FXA;RFV5@IU-CmYQ%=3rW}iG6oAmhR zPDfFRe#?EHxolLHtzrG?1g|VO`2H)O_@rwnPonG$^Wyd2l?kAX6v^u)9Dtx1`w9y3 zo4jWTK7hDCR}^)xEydx{NkZ&0WZ5TO+?^i*XSh3{b|*`_vi}bgd5w?{Wj7EbTy}?J0j#u80OjKn#e}@(|vPr-Ymb}yTN_iyY z7bh`qZ=TohH8`d>o-M2wB}kP)d>7eK-h9Z2L1OGw>(&zPv-r#{UfmoH|CkT(lS+)_ zOAhAue^3YX^0Pg7IpHtU#Z>h%TsTr+;Eu9pSiWq>i3Ya zYwf2@Nw1^oP&eC%3)4cGDzM{pMd{4F169pds^mNwu=+I%A40Dra{bTcL z1~XiWj?c(~io<6LAc=+vI|GVfvbVnj+{*PJvYh2~IFeR+%SCT%aJ;Z?f7jFB9W^+o ziqz_5+u{R=ZLdg+;75<}Qf+tTtKVtE zqLlT;eTG|GRDOr(BNrDpLuJ#TsdDBYtQVqLNpxjxeZ|7%18F`TmrfgVg(RmP>73oQ zAlLFH4b1kejDcj+x5Wgh;qeNWttaNV=Gtt0izA_KkB!wOQtZSMU@hs}W@ zkNrN)hb>)p@uUm8}3kk7uK%;MS4e41&B7ork)*)XFa4vRR`UT*@FR5JmRZJ zhKyc2BW7cEn!myMuk^!RC06ZVH?*^P%z$1pFA$_GcWl!kU^0w$oFk%3pX{|{4$AGa z_c#$gk1A_qghz@XTFm~guE|dP+;0)hD^=6+IS6K(GZ1caZ+C9!(-N1rZKEt^Vp*&v z-(h&AAS(X%r4PAzp39mLlV$oWO9g!uIO%PLLQt7`=xcAt4 z&mB!(6=8nFNV~tmC+aZd3MeeN-tOn8_UGj5LB}n^4}&}+7KM6Gsh9ZDG@5NQ1||}& z9>Zxx=r>jgL*l8#G>GTVS{g#uHmB;)!edMqeaEa5e3$GwU$_#E9TIUH7M7Fgo{5^- zUcr+pwE{j%34f>zlOC9-@AXtJD>zt3zi@I!7n&Q`IC(31tAscV=hfNzKD{n2Ocb#~ zOFzkOM(T&5j$v4wI+~94KiQSYlLVNRa+iq_`p9o`BAXK*)e;UJyRrqwdN5tsthltM zGn>e73+qIXZ@vLq=I6cQ?g}}Yh_@8cj{XgP2hzi*%W1aRP^-+&r7b?+y(Ldzyl)py zQy)v(RI82T8(T+r-p2=J@4dy0#W$2Gzs#wbS{%lmoWtxu_T80T z3n8ro;6a@RzY3C>56?{vCW;&pVg^;tOr3GuhSh7gmu1h7KOiu}!E220Ngfve?e{CX zxgxo>`sN`;vi<|9)?p_S@MyCDbS_5)UVWr_`03M>5i z8Iq&QaqJ7d%^$D{V8Vg#ogqtH{?(00648Nu9zVSv0H8ba>jbrqAKk%bYb@dutB z7FnG?-FidwDdAk3jzyVvN~vW#CCVo^`ef;JK(7DYJ;ULAE?(2hcWg^L7zXO( z2`dehy`6+pr%rYp0;}(IiYM{jPR_iD;)w7%YVa2TN%t!~|y=%n>=n zmTe9hdA%Z^e3NxcHqZYHWblNY>>|li%ulT-cM}yoWi@hN8 zvD@5xhBpD?_PmUNg0E&;`pxY2Tr0BN?uz1kV}U%+X6d-}o4W&<#tfqOKnC4)v7Bl% zfoIY!w;AkqC-+d@#kPp(-W0J{h$i7|tpr!5w@4|xKg!ua)R=rZrDyXMFT-SJi>x1r z0CVlH1L~ zk*Rogo#Vv>h}HUt(?EuNz&d^+O>&BLzFq6$DB`^70HBkz08SBc0tsrE?80s)-L$Ye zzKjaD2|>ME?aArDEaB_Dr+p2B$LBbQKbcQ_DsMhb2NN$7$HBMiAn|<0R%dvS%G+B8 z+ci?Tjs7R@yWd~VWu^;GDoNewK?tjaQ3mvYB<{B|h~QWHRPwhhHb^}KEZg74qQOTp zXI+S*vAv0M=f&0XjP##HlN7clu#bw7En3n$i9_{k_xra*HZqw$9pF;H4Y&>c4#@eFvMg=(EOiUCt76V#6pMv*uy^Y z0R_~bW6OT}dv-|(Ax93`&aj~$VS%u5NqKKxqgX=5uy3QUv8%BYVB%OsZ5yb;$#B?-{uzFEV%4bw$U=l9LkIWr$_ zHKxoWK5o@5b|qAuJ2x)g=+CiO8MFiov>eo?Hj&i6jl~A~zpqJfp!Rov)QUYQAP5Y4 zah2l!0HrY&U1=`0j=$-r4iRGNy1@@lP1P^u`6Eh{OT9d~_DEa6Y23pYD#-~YXo#o8 zOkB8`?mXjF0Jl>oi9;R2`z%v*ifaSwF`K2AI2!k?@4(qZaz+%;|!b!W`* z1R`|<{nPVHU3(}{ibYy&Be=mi&b-dMd+5`k^m>wDz~|#8?*2>I8u=zFIKH8CV1lGI zXnkF^pndU@VUBCv&maVLsxLoMHpbKi!wXe^ap-D&T3w>KeLB~w(zE>T@M@3?Lm|el z*ISmp4^J;)vYx^8yI!%5kRV@IP&|SE?ppsaO4c)SyCo;@egbUUyALXnqy?ME-D~AK z&xA{pScblrM2Hg3Yz_dy;Zbg9rDuxmX&ygHI&(t!&Ku>^%IK3E%bK$4GfZ z6{#!ZO6ee}tkj|=>#ELD0LQ^$GqK-3B9R_=KLC5!yWO()%8guKysU^e+J-iw+;OV( ztFGvHnw0dL7xeu-ud(l_y=@d5a_U9>JQCRlohzj-Dps*+Tc{Nma2w@n7aI!-n}>dz zNXm&=iM=G!{iHZk>sep$-t+A9M7MbwJ(w)$c1w?C^QH+V%{p1|=y|7#056vJTY9ZN&#iu2i;vr|}@2IQ}*0$O_I&Qf=G6U2NU^?B==H8O&IFUQJ%dILM zv|7^a+y?&hL;VqFn>or7!Z8n`_#raTw24ZmSaJ?aZ2njoNJ|3lx=pN8IQdm`J-J|- z5`nfnYI;K=&tWb!Cmd`n3`_LZ=FYm0RgR~1b|48KmME&fL^QwpK zsN?TC^@smeWek~GB9r!hsNPq1PC$RZEV{|b90lZOC-W{#rh?#J{lRil3OipeTz)#z z+ab)MnaHZZ5-`-c3jtg!bd>UeqZ1MLlu{X0yUthxG{F|ug+OL+CEc{j>KryCONy=T z6rb`hlRj^wCBHGiqC>?Z!voh~U6$XwxEV@D_1fkRy2m_C(%UOgU9;HYlEyZKzrX$l zZCR&U)4AkqeK97_Ty})R#+?3RAt_&V=<7VaPi!!C0lB*$ z{oXJj9Oj5vrQ<$G??(IjJ(udk{wPpL@!Nm7YmzyU3a;{_9AE6pD~u7J@gHQSI5C;u z?N&fW#w7u;@Le_<480IZbyGktxytUbwH?*regd$obij49J1Cf>BXJl z;j+!aP2VejDPf>~l;OK)gFL#QBIe>ngi1)}d@AZN+GnCCJS4l@kD#}ZDZeUqWn^ijT`)14Qf z#9YHOd=+0_`qmLLWJ$Abk_IGrc^|m=4 z5_FKSS|(s0hF0LncwkmjuJbWU{#(=OX;}_AMg6*eD+R(n;@OS9jV?$^@X~k%)bu(= zu9bYgJ)G2tPBikYGWr)$O7J=eKZLqdW_B1B@w}vAky-vP|^Dh+2hi>$X1PsGA(q7RP$WBFlXMdzh zwl@?d<}~qWb>JgtB6|xS2|BO7BEm%e*Dz7>e&6tcNYm<|?SpUtad;Eyx4ED;qZb=~h3-22h2d{|mj*pE~BC00(wt6?uo8VcW zSNEAe+ueZIS$>VaqoSDZkjvCFSgU^K`g+ewD8M}xx9V2wgnbuE1(aj1x3*z_%Yd-P zk+9)Da>a>-{R!`W*El)swZ2)Sppwvvv%#}@&-IZ5t=$Nh@$ydLLfH*H%Dp>rwuH(& zAqmP6+o~R`J`X5m;gNHK7s{k=C$@n?_^ zROJTL&V8jzs90OUCruH4n+d`<*aes0z_@-kUc>-J3>t9lO6Q5CD|KWdp#d2&oLbEN zB-c$ujKEUm*zT^l87${>Chs6H&l90?&Kx_jLvYpMyAsRk%2H&|&WUZQ-5e38kBo#9 znTY}MI5Ei0Y3_@X=7Aj3Dl`e@9LiEXV}(n%vW`qY8crzn=w##6o;Du6A|f&a8MU4e zbNPu3js-lpbz3;UaZpGpYTXSwi0$#dGo|tEbgFJp#s^#lX)+w%(%VO|NXtS;9POv; zKQ^S)|52Gq4+aWVuLQjulmELr)d9-|@eD+0Z4Q)JsvOz%&1t4dk)`Dbi%7-F#s<`R zVSeJH4Hv%C%aN)x@q_wD2@YK8X7C@Y)nG*3hltTVd@brV338pcf3auh2dV+ zUo#~k!v3-@PvfS3R1n0BPt1XXo`lWZ67AA8-(nHA?G-Y<2=mFVQ`zriisc|fTCEh) zt!^_zmQ=izPc588oCofX=HJyw7qWh>e&m_?*`T3zFdp2!>HfYm+n#K{I;VYn8`y?F zHm&x|@txz|!I@isw=zI^jxPZDku?%VXx~oh$MD68IPO$gisGtnrv~^~D8d4Zk$+ke zbUa6v(+JP_>AA30`C#*ooRV-0*`<3_dT2x?Y*`bojZ|x+Jx_hEN#(K9H+@NY3tdzM zM5ANUQ^hasx6B5|&LW-%B`v(g@2Jd1oZt>IutslJ*^g>3MD5Op4I%MBxzkIV95iYi z@Tgb4K}TM3Fi&kfrfO!gEJj+|aa8vqcmyl}Tk1KqXf`~%#rW`KDJ3qGiC}*V4XJt% zp8CM;i}a^;^7j6umOsoPD&ztijzy1@)B^pl0A7*^s5Ckd$)f+*{f_)BafvRBDj|l0 zfZyz-D}m`a9s&CJ^9SYIbb}dPZxZ%ScHKK6!fbo<$(BfL zs|mmcWF>NUm)PLYEKHUq>c02@l+Eg4(DvL5ntNr5$P}PvStsAe4JGuDNy2X<(YD`J z*2H14UEK>?e*edwQ>w+OPDbnvWQM%~+PIsquE%P(Zd6vHVZjJnC531(Y*Ek5y07k%FfXBwj6i)xH(R7dJ_Eo$q_(AjGUR&uun*@=(t_4wrA29LwfUqCFYXWb*d8K4 zE+yw(3HYs5TLvEd>?~P6&r)r^%+5nv@dy^#maeWwXY*N2!uKPzo%NT!&qk|y~Tw+cS$O3Vv&dCvD_lfIH4-&*XUxCaa>Hcf>HG7411x-lv zT1hQ~A=n&Y?8iT=?b~9TgYcmdIUpOz-|GP6Sd~bW6D@pz3=WO#$%Zf&<6Qv*Vw@y6 zr~w|G(b}qEW9i+8s5~1<6x0z^C3QHP+pvrc89O8XaIU>X^@Xzb%e|h_I`5*KxJsu9 zzi)$26q%+Lr*WIG$Yd4g$eoDxfexTVA(^!rQl`LWfXUb zH>p6LTBJ>$9Y3B*V$rJL1>pf$85i8^P>i`1dvdJ>M89YYVALEHOZb2VXO(7!)h-FWRQrAcFI4huNN^RXN`PML@ji8XAD^%rjJZ44M z`C8Ij)oL1hiM|w3R0jL?O@;Qls0~r*NJj`Une?EJyVXG5*6V2)#vRC7+RwvFpM&`0 zA@Kc`Ip6etCtgTny{9Zal&GDBS#ro~9zJ=g(#Ud?d>O$g*>Sf7CpmF6M9_e$2YKa_ ztQCJ?YMT~h0{+pGtn2p6hD{g4!hMp175J0fy-!)IeItEn38z@@Srw@gf6L99O&ufv zFiE(71m`VOGAl`Ei<32oowm0tUUu;sqNR9_#y!nG$72T9p!BUX=b#9$8*2F%4*pzA zz!ynX)}~wR_p1n7kC(5KpKtK?_beUsF6;A#)A3hws=Z=u85J$6?fNv&+?T)S<>h;J zWtK9ka$Ua&+>4bh0Wo*3|0wYQO3e~4BaoB9u`#J+ z{PKkLV0N!gj&s1O?5r2P%y%Vvap(HeRrr^9bMcxYY?3nX>Bqo^TI5~tu(M0o?>`uX zPkNM+^=Rc8Zb%}M2QtG@iBUVr!7)T*$MttOmiBX(C!Ydej!pjUKIm%*x@|G1P((8=44Kl4*Pu% zRS;pMNz5gkG4@RKW5ia8fZB@g%<~<7LbNbbGUnoOYu> z5k5>w4XX7{_yi!ww*{nH4y3TN%X<6ug9Muk*Lt%KfxNkC7=EB{ z>{2SZjuqYB@8T|`4$8KKCk^>&bV3DV0un{sGKUJ_OYP9!CzTd+Kdm!VrayH(5Jh+B zb38C3es^$FS%)Ku!1%~*WN}(liz5;G)Qzquo&QIP0>FNRla8Qsf4&pLktSK<-f&oZ zU~saD+X4|1I!#o>e$z;PX_JfJ+y^O4)p}r(S%XcA<{5iEV@wtgr8cQ4cD?BumI@<_ zVeh8N5>61{@6Oz!FAh%W5BCRmn`c`P!)tJj`EPFuWKj`=cUV#~!f)`JkR-?D0zAHB zi6nWA)E&LgdJhd!_T*6kpu-xC8=jcd!AxtlA78~8Jp|O!@T7IJj_;m!^QXM!*h<_f z4Am(On@SZ3S@CNS5y$lb^eHFwLql^JN(M@0QUvOaHET3)7>BVG8a6fh+e$jyaaIiH z89clJ>oxpQlgwE=LsmhExgx$Fts?EjVXcU7n%k7lO!M%l0}C=~${f!Uk3kXlwRZ;8 z3gG=rOZL~#d$7O=)VdsuN&jT!C@(lS9Ne%i0v4Ln*J|YhvKr26TbSzp=Kpc_)nQSt zTl<25gb0Fwh?FQumvl>52qN7jUD7eY5K;nybc3LDH_XtTgLHSt5CaT3{9ex4d!PNC z?LOc6eb+UAz|4EiyzlcoYdveN`(F2RD*F0OSfX{*DIRHO469~A@7jaF!mEI>{G9}} zX*OUjMUNI}PGsQd02C}MpXy-Ep^h)Env>;LYr{Xq4@`)E+D@wv-0n>}Epga5m~*x~ z10OfhBTf|M3G7u%L@7eiY82#Aw{z-xAv|6pt#gbU9z@+B4sJ$ht|V0^Qt4`iZGsS!`|&_Y>@z zdc#{=AZ!u&RJQ{hL~A!nKgIx{mHxBl9?l7L(ZTL_e69PVvh_Q6p21bE;Uv_uh=Zc&J7A#U+7oxZWs0i(gspip0t682qG6&w;45 zD2fgQbwu_Obwm!s$N(wXvH{uZ!Y!8f~y0g7eQ)<^-Ndc(5eRs&w(9S))$ zmJzt)rw4L?X%4$NreNKhGeLKLlR&+&lP;!Z@v#tv$@D;2Yq1&cW}jVVosetk^d4omucgJ`xVS9| z@)J94%yDBMv~x5jk~cCR>3Mnc7W=w~%j|yJfgf2+xPZNJ7f{CR zGx1^>O!K^naODdFe+_Ksp@FKGWy-0Xf1&r%5XuJ&Tf{u%m@`u1#JTx^cla3Qo-*2d z?sPhc;WVXwycGv?ko3PD17rhljE2;!G^+~J)lU?2mAE{q`{L+>V_A5TL+r@|&g8-y zJZ0R@4~IxbbQ)rR!j#S?jG9kMxICMsm}_L1hZs+D^9pa*264;2K;!wDPKjTh(XvL* z*xp7j(9WaEXX~?e#J%G*r+9J^I_v&M{&agtV3c>$q{?=w{Uu_Rwcra0sus0hHS4BX z>i}PNzm?e!6s)3GdQ>}iSIhF8l&YH@N}WIrM9V=zsLCB%9*Uz?(=18v+I6J%nYMY_ z!MLI1O6LNdx3M~9=I(umEX49BujshI-*c4K@J4mca#qVflS2M!bl>gK@KO0j=#xB4 zR*zRYztRn+yCMQTpAAww9KNV&HD=bSvQBj@nHBE)Tny*xn9&Mxs;{*Rhe1LSJuF0aKsbJ6d9XwAjR;fhtsT*1Y&7-uAdhTFF{$Z zY(!e)8OMAkg-tnE^o!ctN9cH_q(=|vLA5#v03d()?p1+mp%x=g5tM5Y!7M>1LBBqv za z8$Rm>su`>!Ky5^D=SgNAClIlQ_FnzZ;@P9Lrb(yfTbK3vK-?ukHk38ALA+gV`p!Mz z_{u1_VGDj0nJnZi*b~jJE9Z7tt*{x-P-P}w0ZLKaIBY!J;Qlb0KheMZ91~Atr_y?) z8#kqjJ6VW?h;yJ0L~z=3RQK8V6}3ah&Os*~!J9Zd|8AL{^|zZc<9*g*|`&TBQf{Y+@Z zmmpbRTPF2J8u=*COD(aCbxwSxXB1b9ZEup)V|8^}x(ACohDE6l5sNJZ1dc$eKCpdw zc}7rNskybzc`?U5YkAcaGm?J=@CLsEFp8k^GtPh%u>^8m7%fmO)TRP2zFK2M>qozP z8+tT4m13_yUYzB__G9c57W~$kqACdF!`pcK_t1>S|5_~Rn{QL*ABgL3`v74c`f-@S z@i8VYQ~8>ilSZHC_jvcqo(adpTe)44^sl558L&H%IbGDBoVUk0A-QYHfNgCLG~sSf zK~H-L3{qZaz3@C;A!GJBtFn+;Y}# z$U(g%&0Z%kaKbs3OcfCu$eY{@tA(eFt+MJs$3+;|i$RxgeGuA}6E$8bwUfvB2sO*Y zZrLqSZp%2Or@A_?x9Aw~vCYOBr**TOHtb!1qvb2$`9s^3DugkUy zBds*6utc&(3$>Y#dLxORVINoT3Loz(zSg|%J?MX3RG`ADp|%E2`*NoiO4V^Cf(UVh zZqwX^%z)j;;zc}wlB1n;=!5HK*EBJQEgpgH4`cOEH^Fx--}q zUDnN87glE-mt*B5F);k(a$eE~DMe}MWnwg0V)&9jE{6iBjm+K8c4+(*-GV0g`1 zO~A}pFlfARsUctz*b0uQO|Ezr8`#YuC`Xy|`hu;2elm}@PM3qLjJPXr{Uto+Hh$JY zv;a2qs7O{Qj>=CY8|#nP(WN>&U>{0FkZ1K61P)a^3}OZ$;rJTLb90AvZ@F8~L(wTU z`>J(j9B>EhSJGaE8|7sH4jK*!NRc$eVSS}GW;j$!>cM?F?9d08Lv?CzhP+gDtNUC&iUbFs^E&UI%r zCr|?AESuF-WeL_1_w(4o84>RpCrXb8dPTEU6B(;Vz0RV?t+WIpEcR=j@$*;vLQWUP zDF>r7?(~6B!@QZydh^x8%sve@@5Lt3j)%PQ?E$x4$ItB9^R7CqjZ3p_xG5KBQrR6` zj<*F4`oDL{9f9Ss?!0$qN}~E$Wq*(w*}olGxKdHpB!Zk?!#N)Pd{(m*`Za?HBdp#P7 z0Tp{L`5}uBVgBwTR#vm=Kl1r-o?N6}IY>AT!NQQ!pj6ppK~_D@!XhH#?XbE=ycXEw z(Wjc3A*N|i?dhJWA)h)dp;(_06T#ni=kOTx_=9Ek@ICOnS&ei)#UH`$??56~l$Wtg zt^v9POlVh_nb08z$MX2rM+V0L#2Sn}y4SFzC%zH7EnwH_NenG&0*hVjNe+nDelKLM z=^=UgPMj%j{tdn!%(B#egV)^4UL)!UJ)JE;#7k1PxUsD5izTo`ZZ@BpXv0fho$}G? z6<8_XfQpeS^!;d(^I7&@{zR#IhoW!FrT6?#HTm+%mq2_q&AZAmW?~qL35jyOT}|Z+ za2vRrZYDOflG>prOj22oD4rElu@cIp?cZ(R!{q1HLDz&cNJ$OqZ$CqI|kPxc$VoI z$hF3ftVfJ~-6Q$*$|Ji!8&zSy7lZ*+Ev)NRr}P}Z9F4u&tTx6k(uTxDae5C4 z^zH#Y+D0X(D7JUEw66q#CU^r(&8;;Y`~$hoHC!-cp&gHug@#O9Nd|SYMDX)5#R7U2 z9tqRqA8&81r}A2t3(osn%%v2iInipnVw})-26ltX-@f@iRInQKLN;pbddh`SrDDGgXL6&uS(W+dpD?dK#ymU%eRjHYmdA|7 z6~b!;B{p>5z6R60Z(?=sFLe-C{0O*183Cu?OPN2FDp4T!t|m5pSCkUsdTs?!yMh?c z9*5*n@Bv~boTkHn;NbtVhTjuje86JlCEZm*|M=ZM*2DM8#_I@mS2pP>Ya(AP7d{(_~t6R#b|yyrTw#yo&czwP8soMD4Qny3|%=_n=PKp zh%5D~>IbS@oemxQdyY7;y%cZScu9zjK zPM%}G(j9HSWh4!}eTME9YH{pZw|X?0^~dEuuXSr5d@lcmhyCN4KaWf}6MBNT8z2Z( z;JDHgtBaj3PvWHFBc6-5UQsYsO8dhhUyb>s=vh_Hv3=YbCa0g;IYFuONGlnxML z`N!PQ)Lw5DW09l(?eG2Dbp}fF`S)koc=7&nWB+#H-~0=x*#I$$vfP8;EcgHSYXX%4 zdo(=iEdD(t`<1Eur}q@D%`P|T*({#50uUXcq%0U zv)ljMg}?rO8Wmta4I80rar$!r@L#%+>!*@Z1}Gufc7yl-OGo){UoD=0J%4#G{C9p4 z0ss1z|EEs~%mp?8g_ZA|zgxin{P<6i?Jqy@R=b`*m9X1W|F!hq|9k?%>jjk2{mSsa zn(n`@gOcm{%cml*{6AU%P42Y;Mn|^)H-q(y(J;84KQ$39OS1pt1S(xGASQ;;|Ks{; zy`H}kw-4iNf0;l4nk<9$UxzQR5j%P}2?PBbG0E;-dwr=4#>qfhZ@}x@X&J7&6f=^m zieHJn%YL^I0`cAW0CQmvF1Yz)R|3#6^t80P_sb~EOB@6J!hjTwNcrDKF3`k#d&2&) zD>95)jQ$FBUR2?J{)O*lbZ)GA3p+ko2L<@U$5n|Dc%%8+FU&^@nNJT^%6!(YMP3N- z>)Dy|^0j{CI#kz3j*K#tnRG?8;Uzms_SrLGlJlQ$m-SVq80E`%10k{R@PXW@S5|NQ zQQkL2yTf$_ST8q1I5PPwF~gUhu1JRDeZ8A-r!Q2OLTWsjFJ7go?Jo{OoBBZ%2R$pw` zn2ax0lfGoX;yVE!_umxGHSk!X4ksj{!F>60y$(4WWiF|pfFUg{B_-A7wzH#CG}b@@ zYMI3wC!rVwy>P=P)S&TxhJ7iv`$<3m0&t_CvR z7itM~b#;BsxX#W`rd)-xi%8RJ-XrQELb*` zS2;E;BqVC^2ZFbSIY*}$2A_D-FVfJ^bA&Z?(_^CaF6qs{z3o-zz7!ba#X!c@=n<8G zofPVFT~bb6c+r{?l(oWnm~(~F#6y3ZNn!nvmC*3KG{0ANqS7jlMYC2)rSN2mGp{Zs zR@YtUz4NY9Z%5}mAvOUXELC^YliNS}9!*NX0@e0l1;qVoM=G*+$xMcZiRra<1A?mQ zr?pz~b2{&#(8i5Ds~eepn&rcbuAh2h+1c?Q@J2XVjLk=>$YP+ncDZzsL9e)jb3U8# zJ8)}5j*6Yk%_s9~Q0*LeCc$OYmcjo%4u6acI;}XG2hFgW|1YjUF=D(X*?I2ED9WxO zkE>eiJZGODVg^EXFG}M@WnI*%XuZP6Xa&w@`na?3T<1gEx+&1|;)i;hC@76Ov5J62 zpdI}*34K&G?F4CMP#UR0A;wz{v9|rjzDd?ZBu76XVNw|un16EYP_7r^+#(aYvT0E? z6e|XveR#T(MJ+FMZ)eiEycIEyW6-y$?8EtXqOz}+lqJe#d7q)Y*j9ei+I1&7Hvbvc z%d~22jHMLT!g|u-et-O}0+#W3<2MJ!TS?xFwC^J3j7$c#_%hVvkl3?gteO?0(u0G8 zCzQtX`!CTSi~s8NQ3F^)sPg;tP7%Kt7CC%07joV5kM)L2R+E*nK<2()4hR%7{_N!p zbEn|5J`7~exx2S&Da=nT>aNxJt86qBqi#{`Ro{lh1OA)w0dS{`yvmBLrOii73q zcu~`F>wg;> z@9Al+Q>R6Yj&@)q%w5Y-@I)MR`Od7eC-ll?wGFO-%FacVAZ2>vvKTma2IAy8e24b3 zv8O1U_jMHh*7Og}61;U0!8Yt744UI4G3PI14)jT)7`aM8Re}&p9L!+S+gLAYT7l4Z z3h$EDc0EKebKvb zK0!n-Y3u;qNmR`3Fz(=4VqOdVZV)lUa-;W66;I?1sFtLj=i&NK?$I}_q_VOXXK!+J z8@!c5zQhdvc=IMS!Te#Bm1D=B?HfvSsaH6u7v6gA&WZpYyL`(69>YwQvua@$d;0l2Pa&f{fg8%2Xu*9%a`fP1 z*gUF0spj+cR4kij)nib({v=bkOQK-!(Nb;5LOmby6kv}Zs>MA!=MSZ?5NUo}?jytlavOp8V1IQJ|ia(BB{jgXhpc2jwmX?vpJ?Ffd zZS*iWcqrtgWoM5#sHs}mjawuSu>JIH2S}E-PTyx3zkMYu8$l^ld8>R1tvx%_Ekw|-XhhS#YFwF?QbN4W5DZMHzXve{vH+;;`p1W!rCf*_vZc=VW zH(+xUysMhE-%&PWMzz*3r5z9Kd1^wMaVU_`*q3u~|@m5EyS#GvpjM1iAeX;M^6hF{Zo%A@5z( zOEtW^gLGSAQvR^kpKMOMAa@yJziXdnKa*u@ui&QQOj4emXheXL%y?>ejss=;rs$wOz$6HnIS6=U3 zF9zGgk0lP>_Rn84J=*PXi}*fXIEH?(&=U}tb(Icq;Kjp zly4>2UEE(+p<1|b@c;H z@)u#C19JO2Xj8S07C$@!zMLf_@LEvWp^3D9Mb2J@-)cFhav%SEzMMhu0dW1J0_fVc zj`%3_ z!o-97U(9)MEAZy)uB9ktBi7gN*BFmGQo*S1wQDsNQZcJuSdAzbXgHGFPwkA>;KZSp zE*N;guXC>UEGsBlLyz4F#6A{@2+VVe?E0Vv3(nPR3t^(CFCXxkF#-Ius?}q9M=>ZL ziZ!;!;v#CGvF%*)*6%XnpZGOQ911 zA%EKHf=_FJ@TK($<>I=9KfY@7vfG(x3Bw}!RaXafwjV)1UI4m>ZfN}qFKfDtri*__ z?I|g%Fprh|*(pOjkA1Dck?SYIlffRWjhW{(FDocg6!2F2qIHKo)~u1Dd*SnwGpUBh z?jsh%;fXfnc^N33dReg-!EP|DGb_UN%T1VYy9Y)}^^4RC`Ps6YWZ<EA+Wx$2Gax zdpZ)n+t!9h))}p;YrzUAA%8G20-mF87x^f$xxPmSyz+!Rr+&AXu*G`*^sT<)7C@wE?2Bw?%b&{&-V1M&C<6Wis}M)hioX$L_Qw2 z@5+#n3BQ5!%h$ycb`+{Zo0C267jekT`6yy9wGxXeDz-&e2i!%iK#ih0xLb#4GiWtV zvqSLnn!=6eIf+pNgz1^h36Qjbx+IaAC;6XpF%uHiN*XV+^!*JP>IyTqjC%Y7E^uFy z`Q&&c0eF!%q)YlHo9#Uq9c2olW7;WTye^WiUcBt+2`A$#ET$43;TNDX<^UZ!N^$Z1z1&Mow?hHao&B#GGC4oW$KYc0cCW zY_=x3dXMKcP!D=ASTe8-V5%g6sWSyncbP$&aVC3{4+EQojxPyBa>;ndx1KqE3!8CE z`ay=x|AQ{I>I7PTvCnI$8wKJWu<=cwE^12Z@XssCAch@N3U+zD!Ey^+Qy{=NcOliY zjfs?44*`v93x`2X@q#r_j&r_LbDDCF6HDmz3|2@Dqly;nl#F)CnmQCN3G-$f+1?&J zbw$kiK(dhMQ#8&H-k0e%L?>oSEdB$Q zQ7|>9&U&10AO&57$VqYM6SQZIW*Y^S^cuhqBaV{l9k(fcFki~~+t9NZ2tZ8OVawsL zCop<)$zN>{K=`)@dn8V9c$L4uIuh~MH7g!Ob7L32#{_-pO0NyXB5=hHx#WslhDp!N zr=@5|=tIXcAov-zt*NP*EMpQDAInx(1Odk=!-|VJYF0+4R%%RAn4+o{ zadg3qoSY>Z!ozvay4uJX)-EoqZe2n5mlcu-xiqKbS``Cx^IVcU$~4^EiXboPOUWn( z`=tUh2x(&(%WbNm&?e@3?eOGMtHk5&I_F&~R+SE6NlHT2Fa^Zw53-c#j7n*=%oLw5 zGV{2w<*l*8Xn;5d*-jroCfWZ`N08P&==E?R)2*=cYvi^FRw?+dQXouwJTj)kP*g80 z=d?R%#1kZd|CQ|%n8U@AXJz5CLOG8&;$1~9>1z!?bnN?I={7q&;`5=Nl7Vr_$v-TZ zyLrU5gxq?qMlbP-MyoxwZk<^dqT%Z|wE)c4a)yuKj;Sf5tHTx~k!nuFq(u5x9jLE+ z93J>BN|Fr7l@U)vhy#~O2s^NS7UHjVS9*+w+VS7N=tGijo+`f@@iQSJ<$+!-BG_g@ zj((!3MvCe>xF6o?n}f`^MBktfgSqKFb+O96X7k?rs89e~_v#N#>hbB>w#x_p5m z>vCV|qNHljZ*tf5#^0Q&)~`FW0_0MT%-6!2#|753(^9QEgV!c6THS_dB#GRFjkw2ayEotVknxMLU!iUaOhGah3*#}Oy*%rJvQ~2iCdZwMon-)X7 zV+l$RmITV4i;xlIos;geL-{yTYqQr3%r~v$fy^SB43EF~{?GePPt^Fq^$A|-Jqw9g z!H)-cQ&<6w5N>r3DqlzW2MWASChCPwPsbr9VR~6!Iv!^lu*N1y|89z+y6rMC6nz4v z(%x;2?t6G<^FjQkjklvWb|)NXo?~C zEqA~_Z`5V@HP{2eW&>Q-3tXIy4wE$;54vfO2jgI|ZbVQc2?{q3BqR^}Uw1;ZcAC8@ zV}Nai^9VwH1k&Bf)NgM=?Yz%YayyJtTsE0r*B16wxKFBSeX#bRZwl*zR40QY**E5b?=3_!iigDi)P>KFn zSTU3*BTP-n+q01aMw1KOIfj()QQKRd1X8THR_JAMV1=#5nG|p5vxvkHR#UW;S+;g6 zpv$+#;Sr8K@5K3<6_2dBMWBK1Mr_i(6v%(rb01Ee z9C+Pn0WHL)dPWJ9nP?c5#F_0(j!a5&J@V!3DCow!>lJ?AzdjTMC$~@_U1jmikeN%z zOe178%%}16$3%Gem4LTG$F7fusI>;8;*gB1MIg%ct=aNAjh7*UwCM!?K+)`Bz;$)d_L9~s(e^O~PR_}Wp_l2JYOOqd*awNQ| zH|6-jTceS4V=YxyAwK3T7S-O2z}P7_o2nl`Khv9y3?}W5wP9FoaHjPF!r)MycYggU zfPQe_%%)2?x{DJqO#)jGJ;dr;^Pek^Tu(}_*4KncGxd?=f!+H1I5?yBBt~;!XXr>I z=4Sy?g&B|COE(Ez(gCj=F?*2#lZFxC5D6e6sU*dir_|H^SOKUys@GfQ2=DC~x_y23 zqdU65qPwe$@etIiTGg*Qw_r?m!#!0W;1JH)kTm%auzYA_yU(#L?rZbFeMx8{C*h5p zhyKG~hh^c7@e*F>XWWJlT}ggXDfy^z*K1&$Erl=n>T>K=j90yJpK#bTeSt^E7y9fr zq>Ql5BU&!^r4iNT`diea3V;Ya=PO}S?;BFigbyf~3#97yv~X?OWC%l_xe&p+yPr+G zZoTW{5IC*3v9WOgM5iKW(aFiI)JziR_!%-=&s@F}NQsA?u02k9@k6_IHK_TnzxZIF zrLFaL9=qt!qMl20K$Zh!Bu8^h@bY3PjCCJMl7mhSKB=Du>aa0YW}pNy{o;>gunc#F zqHo%eV->!7)PemQVH@e(Ms~5Q?6yudjGM3;nKV-v@g@h9nBlR~NT2va0aV`@OG&O7 z#iO}>n+95>*hwI1t|TEfB{5xmH^^GTKbe5abx$;Pf+oSwi)u96){r#~sZP__n*JrH zPJLU2Fwlj{aojKWSnw^sBhuPCjacZh__Df||LLu-thWu}A8hhY7d`-+#O2Z2E?Usq z&msmYaBB`o1(4d8Y{bpWBE6AhjzCV)j3X@+R!fM5T*?DXtnN!SEzP;LJfR?EjT7+4 zBy!q^c2&Fld|pRKKx(h2@U~);XBbYd>Bt2QplA{5oT0e`KKyn*lYu8pFe(xxI?;y6 z)Mw#uG+-4LvVA)q^kjUFAT?JTZJKQ4o0vVZ!`cU*oMgI^$U1gbH&3&qNTj?mPD_UaJC@RF8wN!7j6p=j-Ou z6zDEz+q6vc>Pc27oYXl^#TAq82oU*7yaXJ?9M?vKEP;q`7^NL#j&TnO8QmQ_bhb1!= zZ(%|E&P(+gid3@OUVY;_Z}uuiFJxBoC?4C|t&%9-9nflLA18N~hSL1%0&gOD zy?}%A%|03`zrA*ACtDH>u`AbutL-i}eL8HP#ylUQVprnE+Ix$y#4%`aKdCC%q{F?K z@D0ALubbvoT4^GLk2UUEdjmWoX4skQY{5d%u@}+Hb3<}bXxIyxRlEa0gHfeuB%vnw zHqdB2X5fT9*&V~0*8?QcuB^crEFX$N?nm(xwEOcCyJK2W7R7T7)mRYIv2PSv&zMH( zm#1sEb!m2o8C^mO6@d1V&p~};27)V&VZIEGE|XUI7zwt~Ocn~fDWEn+LiX;sT3uMZ z#|B)%GkK}D#87I;xDOK&5CzmLMeL_`aT=Izzh8YNcJ)~GPMypc7QspEZK&22O@2VO z>uB!=)pPB0cY^kF^VCU^jHmu4FClj*zrTvijEGZuD<;n|CdZ?hWpVJE(^xC1p)aO% z9J=2FxqyjXrlrE@XC4|_;$ec0;LIk-Z7ZN4a$Mr0dcHA~x#_@?(EL1=Y2OvEP@}>+ z!+GDk3Qjpy)dL)n@*(IzFU%gydLQ{+J0Ct+FF&U^(oo*NW%k}K3;u=@>g9v$2jj$4&(YczqACD_>ZOi{ZO z=XL4>RXvrFLQGx>mykZWeI+35puSK4tJ*byhw&q@--&})Lm7(#f8j`83wslH3uTL8 z(L!go4Y)v1P_^9()74Y7Ix&On=G99S#O8yIc|F-g_3P;6QVCyxKlara@o206N-1>; zv)K%UsGAWy!t+rBf;An*O{Luw@}G|BA=gvm z(PA^Q}O4x&ntmKr7qnWcK_Y6EsCP%&%BlRSXFcWm5IPuHhX4w&D&T*KR zKYpy__*(Rb?KtZ~WSD3;icFg&dbkXB-$}}B?pp>*e=W*+&ht&kN$umhqT^2A@R-TMOItDo6$7ml=^K%Gi~^nmTBpQ~8hjLSPhygRxcu1Q*+ zZG>h3`McsNI?}0Nvf{|5u`RZ{cVlQ7IY(bpzOwaL4Y{17!Q%K_?xa?@$ZQTQq_8Xa zb16T?{H}ZopObLbzGX8(@IydHo#wha*ds@)!|d?pDcnSCbqK&S27)W5Yl#jN&z+Sd z=GfFQ3|OACrr4DNcAj+B%>OGh24>WoJ3t)OFqUfB7a5xdX4z<}MCoS))^`&pf^7%;aVo!#PmR3D~C5=rEO6NZGs(FcdJ7Bkg z#OBe@LG#8#bfxZIcJY+XRLY-L-gKPCHZjo!mxuFNLW zxna(;m=c3kUa1KA8eGiZwEzgS7vp`~NCgBY61srod#!{!h*5XgknsuEkr9xe5M9s& z0%c>Z3g)LEC`OASMa(6X zDi_UHr}pmBd1%+e$^j(iRF=TeAbWRA{A{k!hx0UH!VvQPLmxm!V+h=Ln!$7k|@TAWsVx;E!S;U4ym06um z72Hjp6^1Y6`q3`kcV@DRjw@{rFt*~N#8$dBd z3C&r4Sd5G;tEdgMrL#oN-3icDse7dz4o zJ1;b7Gu4gFAL@lPGtxP^3Ph7`o{!8~ypfe1q-s#OGrKV7w!}lQdMvmjWT)2=obEm~ zAOG1o$rYwtq#y~PD?!7#%9?x=CHAq;an>bW}7)#Y#YI={N*YTM;FBw4~+Q%z1u=lU!a}!<&My$cXp1sLHfOAk;xoO30t58 zsiag%`MCgt#d!8tMTeJ5+dkXYGa$9}S2m$3Gu(3!M;ZfL>{qGuut9*c&n zWx5TM(U6Z5i;vl6`8wU0_Sn5S z8pm(s^uQ*|y?&8q)wv2-gX#*(xvh{uNC5_kR~i>5qpo;^_09uO>DWh+m67rBqJ|3~ z;Cj(JqNgEMWA|l*#7LHs`8G}ItD#JloDYtvCxErgeelC>j ziinX@cX&u@8s~fy1Kz&Z-}o@}y%4N=>Nx72D{_agBAnVRyM-|oRP$~&5^fd!-JZo0 zlXb2w7*V%bbApgq*fHIoV%G{3?L=A4=XHDv2)DZnMtTAbVyI^_-l*B5BZiYPr zN2$(Ew_UV7Co}{&3LFwO7oTa-^{XKG4GS_mKW0Tl)z+lzfRf3on)U{G;fA;K2WJYG zQxZWc1WxdM8fcZK#F7+4iRS+V>7OeN*pqq z(S43%*b()L;mYyU-WnAaTga1&G40(0?UffKy{~_@{I1z4Sj5;uzD1$2GQYauBi7v$ zMA#h0>`APMX0~_ zO37#~8&L)}Z~mUF`(07^$F@B&ANrbIZu;LK(}D6?O=e5G6ZZ3%j=yt#V5Nr>JrHns z=%CJFV=X?@!~;te>LBU|gb4jgO`F`W<%|qHZnD)Y+1c4W9FqM|N|e?gAI;9ow?F%3 z!wmGJ^gs?@^4xKAm}I!ba)U^Op3u-^Z&rwFaoNXb_4S8qB(&RnCI0$Y;z4oOa7^wc z4^L#FHrGaMDwK!p;|0LDFq#}@94u2!Sp#FALL9c(EJmjN8mpXk1PAL48S%Lfwru((>2Zr5*7fUv!>)eDo`tp$0%s;RO62OUa z+l+jz5-o!f18@3nO#$vyb zr^SDZSGDj&Gd+sWUAP5Ek+t5D_`MErd5Hd6>*jV$i8C%~z;~vSE2u!3qn1L4lIr_b zF(DFXVeUQI4sMbqVB8EQY77H(UJhhxgMvbOk<~jk_KZ`NugX?kXV;oQ@NIRUHGWbv zJ=)-+He4XGd5@QlWxgN`XAg`e%Qcy9$KN`Fu8-%GJ+m5}-W+_Ms8;?MS`-7se|6`_ zLzi0vC1pA;2;_m0n@%H$SNM6NNvh-B%Eru43Kj*YTSx9bWM?E`_A!CYT<6=Qpn08R zqo!&TkCCwQce6#96;^|=UGUdo0P{*+tbZf_X2@N(_R?iN@+1q6t;>tVbMjqHVIj^r#rKu3MskA&casqLelI7~)qRp(wp9kS*b7Y> z>g3mj>e)Z0&ix==zbr_>*%~cShGae7u=)JyQ||FL)j~7$g)r{KBh(p!z-+v@q@Hi! zmOEtrG$@&F@3u8?1Z0o3!gvMR?y%lu#aL)DJhij)sq1;)n2);1)}vn~G1qBo9}bYF zCJ@j-S7_P8s zOKxjN&l78^HQHwX^}bk+l1@t7>>JG)0IR?vD171P!$%w!Nw>$ifMTTx)Lm%hh!nZ? zJ@tn#(N{o6T!#Ijm)b56KYr}JqpvH0#Xf<;UN^~>CX)Ghd$up3YM{ZxT;J=iq>V~2 zHog0ipB8{;&j<^1BKfy0!wNqb8FwcZHN1aJMHM~y=$i3Jift%NBUqrARfw7>U8gzQ z2NG(Clp$@SrVW${IeqT6dV5xl#Xy(C2ffT#j?AT+Aev<5!2kn`@ilyVR^Q~JuW-u~ zj#VN;+EJ~k-#%3raxOs1@|~$@ZSVLtfX4-fl%zHHl220R zG41KOxm&1qxP^6bbV@WO9UMYDW%Ph=bMj4_73ojW8Q*KhMC6~|fQ=i+V$-F)5Rs-F zYCdjLtp}9xq}ibB2FaL9KeKiP*d}OIL_8O(jaMVy1xDJ?yFaNI0d_-z>fKtW-EZLI zbTtRx^Pe*`*6ltI4)Kllp<)eJe(;IIQy{Qnxn(t52W&vNLUj4sWs`1l^W@v8hwTue zT?GbTGLOJ*+R6ZdIvZMlo((xifU)VAJ4Qv;eLgb#rKtFF;>H3G)Eva!o7X|*+4veu zvR6?NE8UnupF4#QDCy1^eVq(3Qyjiuad-Q>j{q*3s3+XN&933%FauORh5&*g9SV^) z9KgzRF||)&vohuq#K2H`BLU*=Ditec-_dm`uKzMOMVIcyOn$@9y*umUHNmKOhu)k5 zbF|EJ`=;+pYQRn;(jbzAeCV$2Q8kxGMm_Jb8M=j>lZyh_w&THM0wKG%%a}2kf@^o< zM}K6Q+l>GD%UiS$T9;7?b#=s*7WPFZ$Gzm}yUlx#wyX(tCFYH{KkX#kbq31Nk;}Bh z$I-?l2Y0_#(e-GQW8?v@0iNT7lGF~&qhe&)$PW3LHF1$R=0|9 zoo;^Q3b_e)WQp7Fpedz7PIFJ<6$#n66t)`>OsBSgq3!`&YuJjW$kP*i*;@?rlZq3n zXBptEn45!-E#`?JpRpt~RSStI+S=3~9PkU+@pBZlx{%hN4f2b~!9AovrewjEAvJ5> z9cQY_=Wzsb_N4nR41GxpHA}A)W>pz3+({Eq5Na{ho=20l`}wwyZ>nct`Y|t?VlFSn%?5NEL-Dq{cP7TIpvT$Rqma!;VY2v z4C!1K>x5!HdfMx39TpkP}dOxV5cd)#t$s>LqZ z#VS#t(&Aldp#Y!isdFnBMJJ?JRDQ=pnj#f^RxhrYteb>= zT{g@!cFPHL>we6t>Dec3867HQ(yUcyYy8rz278+;huD6d@!+9u_o!#zYWz64Zk(l@$7GwI~q|j@lz7Y*!j5z z*~vHDvcK@^08o|{c;nOL9{nBp{(w6x=HAOdUvY2+-=3v&t-Rt!;EytK1*_7NXAe_LsXYHZQU264kmUo{A*9KKeIrvo9kN088>TD(Lo`4bXm z84GV-=zKtT`fw7^?I^5u3aW;Hvad315Z}jbLl=siMotMlC}5UAYLcMi7NKG0p-QX$XsQ` z*Wj<$wAmFD&XI`vdNA{9$evD0T-@W8;X99ANKX+dtiAu(`kVZ>nvmwzlXYgXXRF1# zary`M99Vh*fRu8zE^POB>9tyzHrJlj19LnAg0Z(4=N?3xo@JhYvjn^ch=Fp`VaNpf zuRPvgnFjyi9dR6*ceNOY-rB$J@c5gc;@1~@hhN{;a^S>&_`Uz~Bk@->K(oZF`mMM`J^ z0)!AC|73rA?|s^kq4PhIbpQ9ibl=Y+ zX+B+^Up658r8niS1DHSPy11w7uUFu&EEhf>P#f|*DEitj%Mt(5o8h=PH~OPK%Inbn z->3d*5&qYIK6?$M+rQ8oT=+${{V%PRC=P??IlMiFw>QQv{TDg@-!IqSqV>ODtMk|Y z7OlT08#TI<;6@<)l*m#Wo%SvNhlx8E}<Gr7X97ea7PkV~CM#vMSbojP(RHC)hn00|`uo?~apudxsGJHtbOX>A>PL?Uv! z7>w-d*rvlY{m#zi5^mS)F#(KxP`ZX5GHN;-dXiQg3p?nx?H&DB_H z-qB-+dnSI22vnqrla^L}ffvPG*Wx3gID~GJE;3vzDv_@VCN90y6uSq}$f<-X66`Xb zRC@O@>*bb*7mNav9lKB7NBeJAE%xtRr_h)-Me9irN-Y-*m%RIyVEs_fM*?cW>yo`V zA`5=SX74yaFEmCn=Tm*&CMmel!hfHSwBc5>Vpp6Eg@E!Z-)cOpe(b~AE0YfbJG*MYP+z0FnpNrPyF)&>{J*pOtFo&Xst+k<3>l&1ey$^)o1 z&qrr2h~c*fySIPg8O_}w_4V@$jm%e<)_oINS5Q|4^c#P_f%5ICq&)V!$1O06bKVl^ z!{s3T!khWJ{hK1~a!C=mkbOzFGs+J~C{p7lC(xt$fRu)5`)CF^0@7ceyubkNYlWrG zZoFH?Zyq*c)B5C|Lm7=}91hL2Pr?6mQxVaswwNIWu`o&LwHg;hH0eC12<87rE**JR z01QOB%0S2Cvq3TzHmdV3(yW>fK|uPIg_sx0mF5ztB-*!nUvSXYfDuVe7Xl4G3>^IzbtY1r;+^qA|*%T%b?d~ zV~*Pp%BHPeaE1#UQ6F=Z%Cp9vdKHEPwLD{;O`yqpj${SqO@||O8MVZ zxah;VHlAmzmKPuB&Y)va`bU)HYVfN-lj)o!6^>I^c;(!ch;^wZZM_V2e*(N`M+HqH zVIql}X8LbEaQ(tWN4Cm$S8S&JN;^Cza9$fL% zJyhvSwGGz)Ww+()OE|<->>3p>YEVx!?$Xnje|^Zv*tW(mI1F+gr!yX|31m1DaNJHd zn<d?!FOxKj)FB3YD3=GuA;TMJ4#18K8+vjBq(Cmf&+A zEl5y~ulEG1@g*y_gmAU}0&hK}*Q+<1sFFWD+*Il4?tY(LqPN1%HMbzWG*+y)i;$qT zmTbEGA_yh2_caK+>Vcu9Y}d`_pQHj~xw$KWF1PRdDxeYL znNvX9$Vx?ZkfJO#xSoFg%IMU^+y$)%IR_`?!6^4@wCE}-H4=K8(&xu3t9)aKXvYe@ z$64Imx)aOW-{SjBY97=z51Sbd+wI8(<;5Jwo5f&1-!vpr%o%>FPUIr)A1xixi6ph! z+dkhh2Gt~U;}Z{BUS?Y>ih5e5T^TYsmp5>oCWb?&r$;J++8z5K*BvW@+R*OPGc5~Y zA9YQ4jEb1**4iDFhKPlGK+;ur>w+1wo!qArasn}(6)hm2GE>#&{)1ie^f#M9$^y5V z>=d-aWtP0Bq9O_vHE!=iwU~$DtV_)ISMwwY4PG9Nh?N+RINE8hs#4iNmRe+)EivS3 zNSa!9sGb^!+1$5+>|u#U1{u5ph^LJw z9#)B{o%d(f-pQY1sP6g9W*0PUNksUb{DGuUCj8=Vl3CDG2T6^9~NkVdk zn3u+mBe$fFU5{7qj2AAy-#redM$8h>sAa6To)Cn%P4|wfp&lHC)*NuC9c>EX927;H zuw`Igavw-_o8=+xXxFQqkH_Ak_dAsDtJ4yIXUQvO#@6!FC$E9vHCfO>S;7rzE91V| z;=(tDake$fLRxL#$(>*N6JXht)=))cEFQC;Vk|q3vJ0!q7B|zeVi(e-N4G|5FXMd2 z3dW$Q#-bA07ZcrEnbp22?VUa`?7*66rl;LF0($n>T;-tr#XdduEtjpT|j|Hr)B-?P_H#1ZPi+sZF79Qhi%YhSG0Ix2w1l176 ziJZETju)Q9WSz2*gPdb%NT&!MvbM(y+xZ=HqlsX+|Fu!)%o8JigX4td6-s|qWc@3= z!qXkcGfg5$Jqo^+K)sNsUT&fR#}_r41Yj&dS1!>&^LreUsqQ*!@Txj5b%7Q z=Et)lA0R-2-iG1(Nq3T zoqXjgHkwKy^)NhRwyI3Na(y31zO=T{-(jgnYv`LteR$N#sr3WXVChJ4NGo8ZE32F5 zaZ@*)r!Bs8+VOY9qkKAx>Ct-d5H+#p5hJ!~ahE&WgV$0}c@BjS#b55+<5glKLKX&<$<||S*l`QmT3kR0DxZS%XZFL_7PgA|`E2G-}7^`sU9cGtyqerqSv2xA(!oka;=DWDZ zWL>I6BoH+^g~E0GVQmGlJcAz_n^N3f7)=^9EW0p14JPFiG3;7tIJDrFk;S1fv7d-s zfpVBZ=5XvEvhoyb(CG!Qe9SHcyk-+mQ37xTj$2h9eJXQ@ALw*5blLVgP>All9BYfb z%APf&&^kBl+HLNjO7K-ia7O1R%CA#2n?0s$etSFC;VX?KvIZ>>fD zK-h`Ei=*|z{zT9FO}CNp&~U|`#PpW=S8?1bW)_uXqH~yrfZUD%?`wyR-6Zoiy+R=8 zgDtOQ{g<);_XRdbrH~y_FEAtZobH)Zy~GKC(T9fsv;*XlRqx~&Q*O(;L!-V8^-|0{ z8Cz^>+N~GsPQ7X)Zq!`Y@ki2auzVw16_}`fu+D3V!R2=27C};!4-gRkq$jpOjZ23>eP2 zY{9V|K$63b&le}q(d~>mVF!c2of#z=t+f<6XrH>l7X5$z?bz=bPUmgx@5nQXnVk^Bf*Bx3eb*RzdBPO z=DE#G#p;DpckD?LviX#rZU&=KC&;ONwp7DUQ1_m;drV%=zGJL;nC4E?C`#(4@ZqlM~w_+|}Dx`WUR9?bt z5U|a++T(b8+i!x`y_V7~L%8cj*x)89PwRFwgS_d9H!GD!eZAQYw${5Dv7&-RG)63J zP6ag_lve~dBwFtolep``Z1hLhX7?AoXOp&)@zAR*X7l8{(npbaA67ncx+B1>eh*|I znQkaO`PP{sZ!nMDiQ=ZYFpFJ+y4irn#8nsNV0pIke#1@B;&LA?}Q~(j7?k4e?(`y4*G8AF2ns`Ihuu9>DmJm8fL<6Tm-u) z$_E$}){H!(90Hg(lo2KuLNNWNpDyEKB61Z62=(Fr_eJV(lxy=)7`It4G z>hYlz1dK!W@-!uSWtnDArxpKK*7si+CH{TSI!L~k8vU;eUJfNlJWw-tRJ8KNHmkM) z4@P~Ih=dx~rs&%GC@`|xl}@ALo@wzUzzoeQPg~bnX%vGHt8qbJ!PyxfWbj|=8Pz87 zowu>Ev7`E^-5Sf&L%O+G2f#*W4%q7tbn8Ioe8k*9U%xY6?a|Woj-|=lbS8~4y(H+0 z>WsR`(VS2W(3AEq2k#tE8^OFY^@7dlg%)vb6N~A?YyKCsfz+>Bol#2q)(jim7|*|~ zDT3EQ)nd88qxQNyv}D)$#Geem@3wo4D6#8fUTOQhLp1`+S1sGN)U48zf-0j4k%F@O zu9ar7Cqb;otg_$nEyu-;0uJtmR~}BAGOi2vIw6=hQz*6PV4*8r3xyV8X`OmPS3kJd za>G#^uFjfH21)3Hj1u#X7Yr`4QD<&`=?ulY&vWaxGzJ{Y*FUvaVcHAJzf#_HaYVBl zFF4`%uG`Tv+0|%fVS<5pGYLAu0BLHy)7|Zl-WFSM@|vxZ(SPw z3hq;jjv3n!lyEkdyTr?VF5qOcO1&-KC*T041?y(Pq|@bdS|au` z9zLgh6Sl3L>T3eo&0)>FPU9uvb z0JrUaFB2^DnBlCOp@47!UfR2*pJUILdTP}tlu!O*bE^6|fsYo~jrTZ>JC&r2t0+dY z$hVis_NK>JIH1X59Y&X&fRYVx0&X9iScsBfseDezqHY6wyhx<(l33wTXt3Y&v9K(e z>crz5M6=ojahhrANyRB%2z~q-gghgRB0P66ZM>G`!ZF!4T;?Tq>6T%wYHgCb*`?=N zh4s6kr-XdTyE^CR1S}ybxI1uu$n&<>BbA;(MJJvQkAYIJVg2o`-j0sqjAcA8?!;3! z4hllm%a}DUY2&+0L!~BBJ4QGzQ+|nz$%I~ zgKDJ9-v0xb_8>@Z$$;iq=hMR>Hj3nr_i2=}D>jSscyeDCf^A2^~Vns+awIWp2 zZE^)koCw*h*sBE(<0TeJ;BjkaE6?1eP&C0s99*Q^Xx+lu_T93GShpRKR~;&{-$ib9 zOn5mTBwll>r5Q3a&4{!1RXrZgry0FexJjHMA2qIg-v)f<+jerWCBfJYh7S(392*b4ywA}~1dce(NmA>+cW8PofTvc} z`sfQHKeIuN^N75X%nr&^2_g3+~(8Sz&`s;d{|AFeC-UF%ARi^dDx`kpr|<@R3+Z39CdhPc==<&Qfls%I=7}K*YVwm zNKTWW}CUey*xv~9-i6J$q%A`2k%L)}|< zSqY+6@1~(m(rFpLFiG`sB-2^4bcLQmGLmY ztfnc$A^t7Py{$x}O)-1KK_3g)%q;JKHJJa6gMj~T2r$1zm@T>RP4$)6vf0$i3*+1E zx4I^s=@OWfY68ltH~6wg7E(q1Fk1I{y96flgq#+P@W<%W!dN}Q(*>i_rAQi9Ta9fR zOI8-U{L4pnWdxy=D2TN3$x%9JNsB9YovB?a8Fd zKcHn8Bl^^$Y-+6Jg~tRX%h1`9Q2e@3Z2DmokLvsukK7c>6|m!;3g-*2Zp3^b4hjr} zm8a)wDc6lB4%MyPve&;%M1;B_f9VPP%ml$>;qcMxDopNHN>33k?t)F2nh|=5c!#Tv zy8P~J+0J&k?FG}dc|}6!tOV`vHauaxzl5;X-NhX&V4`g21ayh$#M2lZS5j&|&21bn zQB1q_FVcJeu9}fk1i6`;W*#1M;cSH6t{ zaKTEQTy$EP0B9nH7<%GGKVAezCwif0>Np@~Uw~+p&h4b8949z~Z+zTZ)G2}*pkE;y zkK=#;LSx&}QgC7tCQ~JKbE##DsH?rb-ydhruH5=2V&O1)OmGJa^niO8Kx};l^9;5$ zvxSPD+iKi_x{2bfDU)OSuJ=7pt}|S`Dmhsq3IvNCfE~y{mLoJ0#|T^-g}KDTQN0x| zOD=_{)oM-zbl2k&3_q{TU!$T~Qs9+Qz*$rrZnHJE?uA@W7#qqEt7Y8vyBv6rjnAE? z_T8RUXgN6lI#-)%vCTAlQ^ck179gK-kCs6&EQm%pnf^|zkJ0UueFM&6bu~!|A}8l) zab1gLi}8v>QeEGH9Z12+Vcd9o>LGPs{{Z% zEg7<4jbKqBdl-}58j#jD2}kRbf%0S2!0$KCcWzW)kY=l%R4b|?&M#e~CI8}?LZw%CSzlauDI1S2Q7M;!{8 zs~rU&A6j*EcHVGoE3`n$tS1%%K@hb!-o;iry2oTBBzJ(}FFjyQvg*nNF0al{1KsTm zd~O>>RGl-X0P7rurPkdLPRYUb3Xy%B4;4|tq`qsVD2tNa8#kVOfwpvp_7_E^v!1j9 zjj_$VPrCd%C1oqV318@3-|dvd$_wBN7PgfSx5##W>yyB+z8PxX%O^-z_F=ID%Uf}O zZ-CwiX4W%(g1BESqMseEf^*bf6-%Qp^HJ?;NLZv<>d;|NM2(5(xn*|2IRU3CA`Wu4 zwYPY5j$Z+BKwZLI8=`(#d%}v7oUlrDE@60Vxd;7i zfqF5HSQ79a`TJAS$OU3MfRQk%Fyk0K`X1}0&eB_%lCM;$Q2RD%$bo3 zNt{pDZ)rdx6mzEKlMJ`i&0C@h-^ls|({%0-_eHUR)KbHC$#hil6wl3c1y-Ui8U`vq zL#u*I9uQlPtkP!mCBVu=XSn5us6-0zj){FZj_=BT(ay1@fZI2zTvz7l6sjFXCgi%6 z55^{9Ja&x`8?GYIx3Wubg)DcT73>aL;La((rS;tGa{uCmsa&Vp76%oZ=+RdDC%yv( z^dG(Hv&u_uWywb41zpQ9k11SiECLd2G){BlGx)2hEY{*dAUaoj%S!g1_x&cSu-aL0 z613wN5uajj@gzaq3{t>P_b!cpuj8WnkaPja&)!p2VSF=fXF&DL|aIrX4{}&fP58ZJaJ8#j9>(S-b z$!T`ThBXVb{v;2JOAd~w3r9*JTJ{17Ce`CZ0YKlI`eBXj0VGzvYHn{+MUF4?ms$0H zmb7~C;v`}xHrN;!e}Vb}WvUIH=b8;{4EqL|h~xG*9SR}{XubztQt^df)OPc3X8i7? z9UK@KHcxLc^bKv$qw$hyKZ$d(vGQrtrw@;PcjbBO#-E!Z-o;Q*l-R5gCMaeBEU>!m zN;PcZX9EbQo;U{#zFeuCSM*Vs+A~(z!#N)gnQt8!%(0^c{DP>}=v!w5duRNNTC4&r z(mWQbmP*BX;6x7!lBzAB?!oSM!3F<|@3ro5GK6Yz%@gLXeS%no8LWt;3t7>ZD8@X@ zP8TdfK~Ffc-_+OkMnMd{-fd~>NAP`#WIQM44B(J<6!`I`4phvWpXyAO2n^`5$I*kS zSiS2?*^#^Apw~I&RWJELsN&(~))-5*c?hN9+C#xnUbsW>$B5joVkg8JC>nur^&2`j zpHQfZoN!ZrsKjjXy3z0KgIBGIjVfu6a}GWRUF|?3Cxz68mcGc#;>tQ!z zFjuNPCL{;7Hg9}JU|HWDEht|E=EFEyEVFYGP!-LkY%X!U^gcXNzmW(aKXCp9>2>vu zCE`|~@9If1yc#75*`nW1#R)J6oIc5{+_v?*W3D;?U}SsCUCyBI$oPnAadbY1m!Zal zR4DP*XaPO6=mp#~E1*jw9CY-_^^_ zML*%REcSKojdr>QG!@oApat6V;ESHFXn*H5dkXeqZuMH$PnY+g9AC99U9Z}1K!(XX z4gE6a#u> zR(0?GefXXdi;AynR*c+U#zVV{yO590#a>@HS#>_PoqWR|x^Qxz%N)JqI}ot*2{^lOp7sbM)>A;HJ2XmJ((lC73*4A%{79%{QWCHC#xw{)NDWWDj6J-Z7> zTZg<$LA8j8v-tCj;H6QoSgV_mqrhh6`{(U}O0`E>T?`kHb#>1kTJ{ln-hE+e)HOZh zwEn7k1$qhh8!!IBw9wqvL^|gpHh6pDi!85lX^~@Lg#FL;!wS5|_=_qpL~agetPy zC}h4rR8IFaxBRfuEjSKW1WYTR6h_SNG$Zi_`o=sP<`hlF@LY7$;?g7g&epI6N7Q2s zdZL44)f=BUph>~46iFMYRDU{}*kXE%WKKZa}nJ+ zky`yN?KHftgC`&Fd`#LIX>q=DepwM_vjr1DxgbR-?xVyTR6oHiC1d%*g#auIpy~v4Ew|2T=s(!`lAHXlekYlK=TlqMc(?j`|0c zKojc5SBE|)a?P*qTbr(jr?sIqU=+60fqc&XhT#Pd#%H)MpW)-O5hqvG*4|_x%n+59 zwqohm%{Z!*^VZF%Qt+!4Xq=W}x+Zo3_inTI_gTv(i(WnzYfI}es!)f-m6=Di0s;b< zt;Fe`9^TUO(sdJO^{uY2^7OFT-cwWl-L|$R>e-5EH=i3Kl7 zh=c@dX=Gkz#XsJuPRU+=4SyuBu>Z=!Es9+WCW!2fBlqXM#ah+>4eo_vw7VEPbreZT zC+czTJPs~C@qfHXX7c=uMUD@>L0$%5@;k0tz^>2EISHBUSc z&~0vZHko_`oRU41P2cMa7hTj9BizNS@%?HSM|H(?eyWx2+!_2qiMwoJVCS`#%2juV>pOkqqEv?)3)0*$!kX;KA=GooBeK@08 zkN3d~-}bsAM7q7a{rQ=_R@#Co6N1Z5x5qUy2A*HKA-3CxFXs+#T^x+klURm{ZM)z` ziC7KLFntK17i)0PXU_ER(^cctavABR6*@)^p+0EkPTbbNt19v#Ko7*Mfcr+oeumI^ zs9&;;Z{pUb>(WTrphqQbf@)o+D<^Wl)-7zbh4Ra%A zF*yg^b&0joUeqqhW*oByw}=33Qtk5Gjq@i!^(hni&EEOP*4sXC@AV)VM7`tl>N+k3 zRkEarF2Cb0UTj%==FJL>evGA3CP`E42raL(>Kb@{%XrN2B!^4_bBZ}c!vnh^FU!qo zI9I)fcm)cD*HJH=dd0?9w>b}+R0eIZPws(~^FS`G#h;P)gB;8gNaCsKQT5w>^nMHI zm5&^48Esgof-pdz^?Lrav5PmOl36^rP`mg@vrt``Q+`N|lf_g6w$k6ld-8aH9sKq- z=jutP((VcRFcADkZ?-R0M`8cT%DbfQLSz!9Qv3K60!6p3BMpJUpp4qH{^G511`CO9r%o#dvjZl` z3Ak=TXJ02*#O8ypa69Eu>MoWpm61ol;ger!8Mk@46PX;%o+y78R1N8LVT}tlOzq?u z9U-?9XYLH36*0!9DYRl|VjMxhvwQ*C*cIJ=b>{jn;%oxlyF&275OcW{<{ysZ*}3bv z+|AiWl|3qmO!rj#qNVqArF^}YZzX=*s0gC22~`!TAYB*xg7J_QVY^W3x1?}Haozyg z!|U#sT+ryncrmmxy+B({qvjp`fIH7zY2K?e^%AMLh|lt)wH!s7YZH1YkJtQzVJisX zX*wflcA#CNO`=)Zfmq48S=8X_+azwKyq@L0kqoeK>S5KubEM8j>jw`O-jTNz1=*7> z(uPk@F2H;}*=Qpwv@nF|2UA+h8wq$@Sj(CX4gFdcB(;Fy?B|w|4v7}p$27Dy8qOF48KJigtAAf?P z{Vk@o=t0EE_cgXP%QYLRAXf#uSL#oh{$R{#gt}(U<$}h9Q8iR?>%&?T_ zK4lFb2$uRtV3?U{bsr{IZ9im{4NnbbY{Q&?M?7I9oyqmSNe@q|*-EcgCZ<%ubn>g< z&pPyM(?A^O&+mZ>7cfzkA4H(umZE8&|kjtQ2jD~GFF|MJ&@s-clE2~`RAf|GTmH#lEI=L{6{u{AaqRAH&r!sshj@wPg^d_p{BK|TFbyw2R3t6fWAj&s?YDQ> zU`t{&3Nb`nhUrW5Jp1!C`+0*5l08UP4e6k-{`xQPkrIoFoaC8*{=-WA*=+zndhUqA z*An*E1?>bEw_jGoRO9Y%SLGLX>&cp5E!sO%swhRCD8)ZZQIfM00ME*g~{n`EN zT)cvxoaA}P^Xku*Y~MD=1;D?CqKEWOGn09op-Fnua8n`sAzrVY;1)6DD?XOJR3~30e=s6PATHgPU#=M zP|p2-+?$ls*bK41d^J%03aInhibNCo|Ef}c4pjd6BcA*>iA6zKm&8l|xE+7;4)CM6 z{gwGy6Myo#KRm2x@@wGAQMl&->+jFZFYeh$1JI1->)AYi`O2>fz?F8+I*Abi4_+9%K z>og#h{94F)??KijLaON2KuVR@ypgO}6n{LYIFZ|Lc6ZT(&+_iuy=VVMlrY zC*KHKfwP`hYcZkYb!~7#nl%KNGZ7(--6-Ab6+on$7F6GN-9E*@Z0lz*b6!IQTD2~e z^b$cb(rnf5sv$PmgUYg|Ac07j`*9QPV2t~TDc|%|jeZJ$pNs`x4Iz7So;ZiSCb=N#EGo8cD`J z%FVJ-289S?j{&a#u;2R}VK*P*oV@#dG5O}0HGkx;}_Q(+g`{hBs-NzDU8 zQ;SHPaYsNp#mpl)KCDpYZ|61~>8jy=RLL|L&1Y5ZLw9T}4n1}qowk>D=R4Ue@pC&l z$_V70DvGyYwb`^A%}`R&D%afenZ*hx*e%B_+2S5sLV9?XZ1rM*`RG}FC9iK`ofiXb zwUlSscxR_ni}%L#f-{_!6Dl<;Mrpw5P*+SOjO+IfSp)Ca^u7al>Rt&^o2(J9-2XdUK`HzswH+?Vv)|ZUE`IY8F{&*_cKb`!4-+F0DgWV`- z_TBa|uyeQjZM$*e3hUN#Y#V~zhIC>maPKn~VTs(n^a>&BI&PN6|9&6yuLIs5GrRYX zQAk4`)AnY9y_9J_#D2Ipn39)0!RBDxI3^=f%KsgGFQRNQ2wt;ZkjqR;ACk0-Ov*Z2 zXA|gWHI2EQHdB_KJa-T8Y$G2E9zb4B+w~R*7%7sle_dp)eXG_^Ch7lB#3FE4;Bp72Ja6) zb~`>aSjSJ&a+qYxubpu=p3kHIwkn@C7$z$mvsH_L?j=>unAlG*ld;!slvJC_-)AlC zoxztQf~R%!23hIXEG@^us#oH}Xga6-Y#1YHomW%fU+IJMSea#iwuL_&Hcuup0F`R7 zRlfJ5ekuJVitFtF2%d={NBu@g&K$ba8#QAiTZ8NsfE`R)f_j7Ib|=cv%W+vYeF7Xk z!k7&u|B)`74x%3Md%?iGIa*iSnw?LSIgyq7&Ag=~dxg;D*vEiQP*H;P31iZqdR@%O zubkrAN6glnsBv0#7q?}mmGCHEbZIMLs~Ed`vUj)$D|*{B7&QK1?G@fP#FxMc?C7ID znbIB}4SD_3>W<8~Oj22XCZg8hkO`18JR@f*EY8=p<`KbZFyR$3XKsS!!l-jcsjteD zPLB4aWrg+?{cMt7`tQRP-nssK82)`K{_#R52k$;19`Eq**PoXzTJ0Z-DMyPE(24wf z1X~vDCkx>UgGDLN6~Y6PCgjK5UAj5pgIye!#DX9-L);9B_fELkvbjS5>}FNOhfB1~qJ@o!4sNUK>an@)t5XQHXI7#OS zEzz-MuUe{@9NbbPc9m8*QwTgN7yIf@4knE;=9T8gHy@R0VuOWqCfv*~`R91w|Gl~I zmja^6d|ZW}j&-*QP8Vyf*)V%OY6h$X3w-5r1kW-a*N>F!dPkqq)|bOlsHwD3)I?Mm zOY_J;#u+1mm88{ggpuBt`KoTeeaA=fRprtPz$gsHPuD~!i3^y(>eNJ!l*aM*BbdY; zK{h?yEQU+e7q#6__8$Wr#W`q_cDLitjLJP4OvozMby+kVmOekS9$RH9vq%)5RJOE98PGOZZj9F4qP010Xbvt}JT=si~ zh%XZefT`I7rR+aOAJKTY%ZcEv9Eb}Ngw2Vy*nAO?Ia6)3VqK0O3o_|ofMv#+g^u)o z7*x@8L+9uq@GpYQid#B&VRvm7ukohejMQLf8_1HKFoV5PFz>eyprfU)C5Jc1k{nug zi5CYGUYIm1SDHEXA`~oo5bMq!HLMk*`yJg$vd|Vp9XFz8nqRi-$C4RQa&FgdRE_Z( zB~P9vL#LY|0@4L<<>Hib3$Uk6TP8Oa9SM0`+HE&gWz~{bb2{ZP>k8wF(bIR{7?5CL zT>4S}{;VP&D&bIPnV7Tu3|&8hG{oEVs+9+G)NMZ-wl!t6s9uWP`>r4xk?VTY!3gi- zsAtXcxk?e5=yU`x>#bRjL{>~&)Y@+Gt%SqOW1P?#QG@alG-}FdKuJkWx~^-$V^$KS zIiI_Ka&)L#i1FeBFl^LDok(8~NWPbdIfsiLhiRcbrsXWZTY{Dcr z!{6_7_TiLku+ZSC$l+6UlkAK)0sX@CgCFy38dwVJ23IrB3~0`|qnpZ_#W|W7)}oW< zu-8%=mZh(bT6v)%{Pt$!Nor*4u&kWKTM^Lg8=l8(k`awa`O|{htxkzr%Z{3T)n#`q z1~lP1ss(GKb=M5;f!+VnZvSYTaG|X@Y?!3!!W}{r{vS^<-9tMZfEGxKfW1mbtz%G{ zLu)zf9%)(+$ZaXY_+)=HDRg+!HsRJ%T{cNCy>Bho{@QSE{Bi4D|Ma*Lk_Ekc`y-iK z)3qx3T<_-^a^MxwW9F69gWM{hghbcnnCyZAJ%X7h4=2q^%S{A8E>iM=y#Gkli6Ht`J4U3WVenQ#s&(Ib^_f@y?ycVW9K zxNZ^}0Kw0+&Ld!xtcU9Wg`T1>xalI@eVUi#=$}; zR)-=W=zs^*pK?>X4#_XoO>}pNVARwNr|r7Nn?7A*L28&o>|%nu)eIA3PPZ|$Dm`(4 zFv42n%-(QYs=sQs--4_pUK}ojw%%4kY6DJ!ON}e$z&JZ2GDp3_oNODr#!{%*GwFue zglXFJC~Y6Me7{g|$Q#smr4pUcL6J#rz7>jcxo%fiSQC$i>C zKd1-95KH{_8_}k9ic5;F{v^adiM#rpe&|j8n?I*s4W4>p>-Lp}Q=OLz5H*t) z#*_DPN=Jd`C_}hml*nW`>W{7YAlu&vqR{Q}Kya!Aqvp4LX?NOPPo@Kx3fgBd?!1y?owID3*<}u zneX?H_SaR0p%2`fUh!tEK9P@GP@T3~Nl+?fl!^YL?Ktn9;{^C{bH{)ZsLKJmn>Ip$ zs8)%)5BK-$lc@|OE)-adTz?WI0(`1Cytg11c!m=AsM74+(ODc}Ye4pW8k-h8$Pc*l zy3Kpjs4;q4PRIkQ^TQ%t9~%81JN73(?yEzRg~0b~d^#U7TjqjbqX_)@C@EZoo+e6hE=p8ID!dr zM>WCbr9JM;F@`xfd#G{4q{rLHJ|s^-&xdtXr+Api;g{z*Ylk*uFJ=|5EWWHiME4;> zFj1|A|9D9y9*eYh@ChRSAd01nTyc^Xhb%f!zVZwG{82!u=4_;7tG zYQ{Lf!?vpGo+)Z2rtrm&CgEpS^88-!&-ab5xC8J21^7 zFqsh+2p6Kn5}g6x0dQBNU?g8plCY<|fk4>Q_;Oo6#W?=6{Ej<17sOp1F?%|T%>WvF zm%A2`Fj6xmrKL1U-rm()6#oCj-s6r&+M z$S$xMp6Ggt9?Dk8s&m9m2gTv-6_)IFI?aKl*A6?Z+A;!pW~xkv(5rjfu*Kj$_t+eI z@ez?-U;0?}sg2{)6HFGS6lvC#U%}jEUNsiuz&)In{K{9B={wjR8;?{g()i?04!8`JH6)p zJr2iE_|BHht~@%T{EsQ$3U|I@Kf`Fu>!f@44)}6N#$&fR!JS_Lf^#3Sz(AU}%-;XP)1r>pnwh(hwyhoAo-_CMMChO#qkA>VuW_YlOdmdOqBH+K|KelNJ40js3jn=RA*yfn+jm+f$Z5{pioP{P&Ok`9}S{ zynjpYe?X7_zdACu@vZy0KSS2hl6W)87XcoJzAwIi!^NJxT1bXxcK3}2n z%QF>y9|wrBJL(#FPm7`y#93>0({v!RBO^{pLcJ z*6AZWB@OTYq5{HkNMuBe`Wpn3p+L}%p3Q6vpfJC8^ycNK|G6Mq-Sa>}!*l;%yZg_l z@Ql$&wmImW62q{DAl{J((s}~5*u9Yu>U_AbaX{pbo&Ac1k27`ct0MJfThNmHzb)i0Y_c zenEV)J>P^}^RHKu%{9-C`scIQ0VSz@{B0A7{}QMF*-%eq0$cb5ch9tGq6Y9;3^_v$0}L?a%(;2q*XKRY z_r2eBo%5Hd7c;-O_r2F%Ywdln(LeCPuQ}wGMg8-dJIqawc^l;e;09{Uf^kadxb^E{PS{rSJ?XOD#o|10NoTj=rzeJ z{m+&BC&&Oy-KTQe;v*vP0!P@6>ANe12#ItH~Ae|8$IShV(iuY7P)BL&Ne?F$6 zJn=2Q)p?td-3dkXzinj=G{ArhrD>O8`RDp>yh{Flv~c?BbVKMr-{t@QXx|Ee-4GN( ztA8HdpC|kGef(cP_|{MY)Q9tzKKIWr|L0}@*N;nO1<$tfbDH4)_1XXXI{*DIsT-#j z!jp#s;{SE|{nu~%_xpK&<&-u1k$wID_ituB|2o9#OgYaOsojbOjbej8xB7>P5nN! znz+pJG^NHFtp&X{#PwhAMV`?&Y|vbY_kYzG@6}Sx;K?gFS;-x+y1fYt^HE(Fn~J*6 zk$)*TJByKC*t_fv`)?;KiZJq8`>Jd)Qq`pNk{LkzuW#BW5uI@YL~|EQQQWC#0;uok zoeuhN)Aq%c3no+vTMM+bNqbWc;ht3JiE_EqydcL~E^j1(b(^knl1s2Gk^2#z*(GZ(abL^asl~qU?V4 zmE-?biQ!^|r+_%BkH;ySAMbA|6b_DDQPVR2S+>d%aqa}V5CRh*OQXeE`$jgH~q>(p{4;}mPq4WXR|t4X>&?erLU>nV)KvJcypif!cf5&LiU^V63l*XX`PeTbX3p73^zlmt*Rg*oJG!N<-|H^mV(JtRy@$$upQAf%PNJ7W~nmhkN%Dx ztxj^8;i(7rtX$4QE#xepU|l0KVHn(_3}nQ?k2gf4HlPH&Y04Ti-`F?Q7|`3e5L0dq zn1-W_l#}&EPb^Sco*!aU2yc0RR+|6^OAmJ?+-btN=U;nE0mbsy6OTfNBWHy|K4x%E z-Toy7Hf!wpN%$lyHNqd0VD@JgfZ0sl47?o@@9e%c&5QVQ`S0C;fgSWgY)i`i&!8N9 z{=m;B=nbsa=~B;G99ZJU|u$}%30gT_L(BNs|ivlN$1>8nnB z&Rv%V*KRGiKl>8vb7*g%fXs+glt01{PI9YBEhjXB#E+OJH8?zpU*hL(c+0EndntTW zEvnlNDjSex;f+H~g=E`At1^VW6)s<+bsqb%5VCP%%~QChgqT4=_(>XxYg%&5`% zT!3IwaXU?IEH0eCsB+qQl0j&BXoXF_LNl_~OsT?8@^VXp0iCPpTb(PAo%C}9Km2J% zq&qXshMOIeLOfBG6MWzAgamr_~7e&4q zKV=_Bffh(mtVLHG8K*EZ;O+~xUQ6^NPY{AHxMl8F%HlSL32Nrn<7C`MHH8CHqDrG* z#_s&JRmXiH^5{j-Q*Vb>CrtnDU~kV-Dt)(iBt{!!eY6uy=8GO=cFNyR&}?rbc=8tT z7U=!i$$T&S?vcA`{`u>lOwc&0^?*ox#&w~5r^vfLITYgN9eFe`V6UL|+UyE1!n3qQ z0xTq{cy=y{2g>qdCp*tt*N>n1Eh>o~WSn|1h=SQ_-q#!;sRqH#>kHH})6!Q_m^b>I zT`7UF!6h9}+&EbXA*q8bg;l~=#)LAiLh_lvD!h89L!5_SV)xF~jXGbTIGs{#I&_Gh zP_6VxavJIV*kibJ(Ds&ib)#akFn;cFC~NYn8!)`6;im%@w205EtKDlik5*Odl=SuH zrgHO`1MaKu2oDS<197rZdCdo?;e&AX~ZQc<307FXinO|Lv z8A6!4Qp*$Y{u08(@Qh22A-sgrl%#KTH{DQ4F0$=39`YM^)7A97Ps9c5)NNLU803$1_sa*Zkm zg2(D32e;Nz2z6{g^=a`Lu{WiUzoRNbR6!@<5yV}-Cbl=W09bFRrpoA|889Xcm?l^O z{urc`_;8;c7+Y=G{d#U9N4OB?*b(7{`*~+qaEAEi*^LOW3)Js`%o%?eu^q9mEyzPUz^W4}w*8nll@A z3(y0V(0U_?ezsS$lrHAo6{^u8k=oCBe43WPXry$sQEL+vF=Fwtb>Vcm@iUrzCZiq? zy8i6s2$y2+?B=ekyituRJl1?TJFkhFa)85<*EXa{HJ~syp{)A7iD!HuySWWKj@5~B zo-mJP2xY|GpIi*0_>)UAU%zwZo$!n>h2bv@bqD4Mt0@iLf*45B z+gM9)W?atPj91d0r1qb@G^hwlhO$!CXMeVqKcMd2_bZNTBdp}<@i+{@F6hDGMA`4l zEQ_UvnurFas9+=FO*)CqV+w6cRryS?oA8V5jTx;}Oj`GxD?}yOG?ane82KDy^5bbK z*kz+5ZR)lp7;5CjN>;we7Xk{F5JJ^;=%In^^K z!|M8x^Jexd8?}s1H>-9AV6b`RTD${XB&8gCP|}dem6d33U%d?CKoM9{pJo|l5J+x@ z?%WR5-DTGIqA9BV zysA~`c^E67-QsKqSji$=4@u*geOW7~(saZG_sM{DkG5A*3sM!gBk=M3yxFj*3L<)pPg89X9l z9@|Q(FJA=3yC3%0K$76v?kj=RRM^1p`mAnY1)8mo{{8;mWB>sp6CBBfOwX&x(8<5;+sj$wo&lh9 z+SN~b?|*zA00=tCeJ_zkqH!NUw%DKt%XPNTpbcB0HW>=Mn@JdRaNb-b}`Kkfe$U%1zB+2%7 zpxakSROlPbLKaDW;nPtSQAt*IV6tl51v_I=PFiSh%EWGZJ-C?&MgF-Ax&-gSy6vu| z9l{9$b5F!ZQS>0n^3{Gj*52!IrxV^h9~aHy9UX{~4AFoNy+z2g*YDVi=GrnwOkuOAw1 zYr3@p;-Xt>mzMkeYd!9m*5V)|EPz4Ld3;WxfeUw&nC1^{u|1VhOTqGqW_bk_ADpLR zyP)bo@k1PssXLD_byXmr?FodLXSlM6%N1EfPrgSBjE`{!Tz_s+RIj)?XjVK_qz@&d zZ=!6^ve%BV>9UnA8kCsb{$%Oc)J}`hwl3taWX7B?<_MD@eRZ$BVjs`ius=VZz{J}l z*yZ`P63S26b-7eNpK{G*g=_2RCd^Q;xS$Hc>wFUI6=oshiJ3nJwhKg8xVMoBOQrfE zrH*Y=-NN9DE39#d=43bIxV=y)b+|@R@kxktK8PgqR&w=jD2p9BTft7Wpros7oQhYi zM{>(s?3q_xKgLuJGbeG<%9FY+s{AzXIK)1$s6i`efwY}1pYB&>&d|^S*{p+`fFAhJK=?7THGvSiYFH|OVPSMb7Q=Gt(D3c)MKs36WhmFc4Hd{H&&<`Px*~v zh#ex#0^@V`+&1%q5Y=e*yl_~&ogxLwKu3R7~^y4PY6M3+%id zF0ZTbMDKi)V~dCSGWL%8(?T-FE6Cf^x9<#(P!6`bq;BJRevU?U9WGSc0w~vcP2X)P zx=TX!psQE1-?xAyx#;OmxVKJ%qVU$IU^k_%(DZ%BXj?_XtT{5fI#KuUXP&t^*k3Ye9V~|OP zSxAA0g{ZB>o96Z?Gb?TRzW|YM(Z|NBb%amR4KNee^E;l;-tutnw+PG>!{Z(9IO_8w z2hky8Bk+_G60KPUvoy~c7y5Z1=px_T7OF%WMiZ+?BbcioS(w6dbcEb?a8|rxI@w`J zP$u*n4dyjV{`@iS{9$ma)JfXGM65r#tL)WC1*d*!8bPnZyBJ#jL~>sL36-7L2>N^I zJHl3+-Ad0~`e6HbgY+NvDqa<&&2D#NH03|@=Kl99PfNQ84y4DTpX)*iCpns%2b+#l zc49I(1VOyoU+TV{hTu-$OQ4~@vc)Zgi)r;9A^BnzSy?GrBsLcicxUSde0sQOOt`a0 zuYlRl&y;#q`OmmWjoshyY8|EEcTl+p(YL)1U@0ZDwKhvlM$uTKX^>4BlRP$B&?;=f zp2U}TS4uTbagR|+e;N2A28*e~7INtu(=8WCN7H9xsur%dt_w@^_^naN73)i!IiU;o zOn(X_bv`70RP3{oZeVHA{VtU{c9|tVik*hfdVmDka~{(oNXkL!s}?~QP|lNM|LO#K zg07>u$V5IFH?a%qik6bwQpDzMOr6o@Q&q)oXH3@@fGhoNb#}K@pMD~x!A;+;1=F47H%o~m zf>uvkap+&o*E`RRv&4D>{a7>gs5rVbcblbS3J0qCQrCmE35#xEtdAb2 zR{bv7p3-&ZaBKv;LB$Ezg;1(>Z{kvkGuUv5<2y(gxz+m>vyfYLfYCsm;Yb0}C2s&FZ=LO2o8;*^3vWoLjfGn(st=f{l{&o#vDc zvk;ZUCQgiS5bhaCT2_rpjucEwbYHa@ye=eP7bBS!C90Vf3+yqKb=S$zo@)gJV>H1) zH7ln|OhVkmL~u2mUitVHF!lQn_+F&ZsphZsr%t{uxZHSQt<~)w0s~B?g}I(fuN;}H z7QY2=^Q!gUKv3D#aY~?)=3TD>mj8;hUfxr++7y8BG>6^xkqI`Y*AZ+mDYN1+HR8IF z%&Lp8F2<7-vc9$0=qc`vRNCti@_41oQcx!QM&aP@(IF0+5*wrEo@1{U5!lPCu488+ zh%Q4=mUh7>uq)p!3OgGJ-rXsTT`x2l3WNQron7%sd5QXqxS1oNl~1?B*oCf;W19t& z8Lx}(e`OHL=5~U!tp=oGl$B0&-3lqNMo>kO-Lmxpnv+s5g0|=pAP3;^+O+OaK0SRJ z0^sY!ZV-Vi%K}@oe8VQVOa@o#KQJmNA9+Hd>Q#XhU{w^h#nkobY!7j8-j%5)`KldVopKYrxX~J=* zU&;h>#K#}@hK*OR04I8>cKHNcA?=`5_TSP^Pr0?$z?t<*m2UT zQk5;Yt6kfajzsvaqix8Mj@5UtD?7djM3tr~TNFd?R|3zSFoBJCnA21iqtMEmiF_7z zLQB~9uls0YB4RiFS9NW%_%pf`b{v%~Byql9hPm)8>}jbyC&+r&>Z$cw z$S@>}fxSO$`;e5{V!ozt>Y0w*s_MTA)}g${pS0Ixv5u=>8>T%55IWB5)2vBb8>nmF z>%=KI2(ZUUIhe`WjdJtF*o8p>%nkWU&xw76>Ic}UqLlbiU@$zPBL5C4w4}R0v)&tz zFw5DNL3c=a{Omy`bNfNw;Qf{;nM+o_@`=h8nVj8^HpiSt%8KbQQRP3ll31kBPdXb_ zDJJu=4We1w@n_h`tOa`?-U52j`JX&A$<4SGFf_(!@9Dd(i3?{9i_=N(c!TYBlvtDZ z_(pQu8!at1)$_u;t2{0=#M)HCw37kiD3bTWvp%%EW5yvthkY+^ES`;#ct^$~r5hk0eA+r-%aKq3-a$m*I%EWibn>0fy3gfGRc_(UD@|_Zp2pAO5 zhj#hEt3NM&QanA;k20E(q_X;Up1CmYqNik|h0zl~*DD{#2on)QAVcUIpPlr!;dT{W z4d#0~Z9|+Q88lmVN40?$U5%nq^__`^dEhpZ z0Mgw)W%g8h*?!+Ps-X^?TnvjSu%} zMl$0-oUNJq_VEp|eP0KR)(MQuRn+g1_kQy^EplNo9+Yu^l{0$6%to-P09hkyXU<;$ ze&dv@VhxH-iT929Mm{ z&s`OiPAZTQw(z6w2q~KW2d<(cfmm*$0}#AMPYPKor|cc>9&2baRFtk2)|#G;j#cR` z>{8!Afy!}m(d`b4Rr#=*=EX`6s%y#NOIspg*Qrja6?sVXhj+o_%A0pbgZ4%FD1>Q; zTeTVH`I8(607LIyr1*hv+%G1|O88EO@h+^h6g_HXN#dosS<8%TnK|{||&t?E^5=>|nya+=L~z zeeyFX@F#QEl%IxIyfO>2EmXKj?I?{Gz76N*%!Pn8zg%BjsnX)!BhoH;F?0EyER06Lcgum9mf+PDUL7z%EM@mUTcm;FPRr=p`bJ6U{K>2(Ut~ zjJ$KHaj{InH%z?O8Z5fn2RSfDwma<uo^0Hjg%YPU;)32vPn{L+i{8IxxOQdk+ z)lKV+8)C;yS0<|HTRXl1&dQLtX8Ww0ts(JlqSJ`xI7zhya;dQ4@Vh73F3AHHNz(8) zqyROU9c9 zFfPzq7Xd>rVzX2JWL!F_GRp>nP0;+cus5DPI=Qr4Slo7R{5=|mqBo;Vml2er&5*a#peUrU zEH{X_qgf>l_QF~TUP6cwwW0(-3y3ZvRgBVULlHz#!pABq@LkrRq7cs&!I@O1i8MG# zV)%neIuiCUC3JSFT{8Y~G&0|4XOF)q83Js=G9zc{h;R!!fwNm}Z$rX#GC&fm>EJ!A z2DE{CPxx#BALx3xVk!oREFWTZJLdX6T0 z?NzU9ZEC5Cqd+CC`Mu5MAX;5d25jLrYNk3B1y%#hdHIPKh1lwM-X3%ywkZ5!GExY~ zQI?K#fhZN7bi)>8m&MrP>iawg`!r?Tv1c$wDI`-AE?mF;ZryNazI;@V#p9@>SfK%J z1R!FosCE5rMx|TJa$kXh9d)=7c7MUE)T8C(AbXrtMc>ghaLq}FQBh!t(ruX2&&`oZ z5Om>n^@`cyTRX53pq(!C_!&gvwbQysgrOta15?kAnIfbAR#c7ret_eZWDoD90o04) z8*V~~`24(12*&XaAibs!4yey!z@D!&E|B}7Rgz);elTbsC%^>n38z41=BHg4!7l55fMQtqp7-;?1#^i^q4)3k{soZys&?9BXlQZW7lbOC+lK5XUZ}TKnF3tlC~?;I-{u z28pi@jv8b3u!62=B0JIzlri(8HN{ zM9-mT_@~tpR{B0vfp40dwp?VdnCD4yq@lji30*2*7+L@&FYJFxQc31npdGZ*qvcz> ztKhA>Vhs*<`b;y8w{4Ctg;#~QilFPTy;hqH{$rLp>A^c7_$bGZ9e_T?D%BN!cWw); zB4m1xP5E$)n}711$HEPR{hCID3Vb#I6`DlMA7D>gnh?Sq_KVr;<2JR&H5BOJ+0Fgl zHkS+ltP7t+PX>oY*y*|g3KHv~K@pRZl;>fJiw?AL32@*_7Mb^$_)dmW)>)wY{1UD0 zW(aYB7lV}rM6@(v6uqsG-|o>KIw7S9e2&2Vg*4rAwwm<17KdsBg!7IY;-O>b>M;i8>b_>rct zO>6l>$t=)fO#qx~EE}|LYfZlx{>F@Wk#e-TDiho=?~`QJM}LV~9Hm#}JDfK|4blf| z9D0&5tM@fIjuXe>zbsV_q&WqTHDOQV+z9PK?c&`-0uiuL>w4mBeq-PcN$nxy5LZM?0 z!)Z=i+oWA?+=-c?72su!U`24SsAsT<-b-xgPEMlt;&!*>6k>O1p{ws&ftNaqa@%Sg zKFV|Gu{^Tajoa6$wT&GgNQu#VKz)FeGCywl(Bpt5aM^3vOz_Y6QB>jh__K- zAhNBT-qT)U7CY!v0u7wkg*SZ$o)BfbOgp7{JoVV=Z!d{J6m?0}hx(N9E4Je3WB6j| zm}=FF+)6M#mgDdHgQLOOLwh+-LHk8>xaF@2P*W*iD3xeD0A#R6viepMNpOP~Ez3E$ z1614uoh(c3f)XiLeyL16uZ;3b6olOHQl=}@BV+aehqo(wYY)PR$ zp2{;n9wHUkJ|6&_IGU=VbFpH^{p~L^OB9$)zz);3@BHaDYZ2l}{lw3cUIPc}<|i=j z7=fjzNZ1>X1&>o=APb02)x~KFy%uW@+o>O~_nvzcd=2C={n7^ug9D&nKM@|3y0#Ai z4WMOAZ+8VAkFKQok=zO;8%>?(r-W%80?3cgW$xGk7!4++jj$*Z!7|gimPof|_Y~WB z9X^eLLx9+FFR|TjLpAIvZ95)V26|!bMf~`!3sJ7hFEU8F!>&u)$9JYGs$)z zl8wag9uAsrF@X*y4F^b=nS}pWuu(j`0b%Pp-U|1YB`v#`?kyD*5tpu@kfdZs(;_`7 zak&z7mhoMwfj&wpUrq}q3*Lrz@%6vrz}U5)Wa!|5r@&;ijqzD!;AkJoPT{pwn~h}Z zq&!2n41PEt!V|{*uF=O+aBq$edSF$vKOel!XSn!Gdw&h&M*vrx)l(LC`W9H1|AyBy2 zEj<)Wd=;b^58C{nADE``qv%_)lKt`YGgB(UQkA>)PY@a`-mT>}px3VGgM+94(VmyE z_e{|2&hjkj*%gWJ-yIkQZ&D^1Elf=U#}w$?U>*P!RYLyYz}+PW{GtkY#n>I&}Z$1$Teb_AYV zrl$`!vG7cyDYbohG`3U06P$?YjlLOF64?A{a>!-s2K6l#0MVlUvc+lzA_)4vRl$f0ADFr;?xEq7pGl&6-2t7 zt}Eg0Jv6rSaa2?~y&>o;p}qa(fZ{k4uH7_!87!aW${xvisE9@QpFXoVP2vgoQz1h! zlAHV9d%forgXqxBpC8aMy&>g1OZPw~D%FpK;q@h?kB_0~4z~M%%t6pWvh}`r>zUOj z46nr>$8|h^E}=sFC?GokvWxlYZsG1>YG!IS-iV#CSzcYuU0uz}%R3q&98nNIICGXn z{0z}epEG~`7{yN1PBY0!2CrpNF4K^hamsujwgv+@Ye<9i2<+Z>FOyr0P(x-YM=;^xU z_M(z5*I3PR_C$maTeR1a72bQ%f#^_WDUuq@^thOxjf>v=)grL!|0$~X%hkJvk1F6T zh1JO1U;DrWL76$IKvv#B_eGZEaip|T|A%Kh0%wGQv)F*=QWd%CXk~&8-iAYsThDW= zj)mUrllkEG#?Lre>7*`Td4Y;+FwOnC|29$PYT*`*nPMWd-3Ta~se@3uiTR(OVyA979xWt%vb0j)$kP=>d?$*1oJDdaPFTeLW z=)awklIQx%O2~hzEj&@)s#`_c%QM#$-}cG1GNaV@l=*cpaMFe7WhKU@G(JmJKTVRa zQs&We3kov%`Dgj+E1geBfO$mobE98z@dy~oykd`x{KlT_VkNTO@pTiwQaxc5E;98) ze1FxM+Zj9!m^ztZXn~`A+KREEMvvx3(ny8X(WWMDa<@GPnW{4Zw))$=S!V3kY+y>! z6+cxvmDl+fu6B4g{O;oY!8sd@n&vEUe297&zbb@cMV|)j1TjN|$Izn=n+ZqMI~vRc z545OIC)dRpixjFgbmmDOe7WTrXMX!0;U07iCVMEPpeSYkAn<$gMSTu-Qm>)15B~D= zc7*ulLDX2EjQmqL|3dfs;l`D<{8BtM(q+BMEKV)W1UAwnGE%?SiY@H>`Y^mELsv7y zDUL0tMT*wT5;fC*UeSAZc=U^#b$KiYy~GQ|OQ4>UG+ZRlP51M6*gthJVx=;5-_NL;_ah=B6P<6uQP1ek{}o46 z7tTtg;tIkjt?=S3k6aj@SF)@W+~BHFTMhKZ7zg%Z2^NIG)L*`G+!NTe77)ysOAL?ZvRNqQGOOST@GMqQv)h!?~(R z5NMs*9ufuYb8hftk>3uPEOFOa#y-)NgYiu;gA7#(^1W6!$hgW%_RTKJ*7jlLSL%UT zyI2L5%kqi)fuY>rF+M*QLhtch{`~otGONa~#v+Q$rLS|Zwhc04zd8g^N!_wFC-(<| zGb7p8&?kJn`HqD@@qKzd>XJ`Vhy1X5K2tK2*{U4Z)_$UZ!|&wLq7?S9X%CF&S+B(9 zN!4!}W6%q+w9~ywN2=T`Q@GE;L6#}qpyD0h>{Ap%lVzq~vO6u7{49H()qBu>=TMh` zQJRQFa^`gOcdmnh2lSao^R`gW3T)YgZJrlX!LV2fXF&(4nc;d1-~sJ*s*T+m8o9?k zq@7NT8X|p>dS=aEL@?jZSJ)@Yw2SV)lNW3?gh@xO!1?g9OvU6}9Z|PGsWpCGiI*!U zYCgh*U+-E;=}lUo4uu?Z>aX9T(2MOmM&*NvL2U64UW|A=C#{>Tm}V8$)1Vs`nv~d6 zH}(qLUyyeg-`}EbrS5XmGv8OF0)B^qwQcH9=Si#4Pxe{`9a}net}?$}Iz*2guff8o z_(VO`KgX}#vbP_s|Jq6V+7IK1#z3*FIdz9`2VyLRJD+rD0{^d0NgulJ2mH&ti`N3R ziw+{g>6=%(GbWjEQvAL@O~dRCkD$wj&Kk*Blc*Wmi26!o5`UzNatZI-C75|53KgrG z63ePhVZ4&`I#2D;GBT7p^tm@a*a10kiN_R&fND3&O{F1b3scyk!ooUpQV923aEs53 zSO1lue*GXFW75~A(WyDI(6D03C|U|!F)KWzzu6)82t$Y|>?CX`pA*V@l8Pue%zU^i z06j6_4KK@cP$}Bqudo8C@+&=&*hv|axg0F!SEJsc8={sP~Qf$OE?+ z>j|!-GR=s1J+uUjwSpmz zIZR8012{Rd9yh~h`0xh~C}Qsc?Hwd8&+w+4P9L~We~PPYF0Wj;RzufagPZA2hf|j0 zfrvyI)J1O28(;cztW)|0ZmWk6!7-eNlJJQY&oP6~$Ve#U&XilIQ=OdHrXR61MNRbW zzvW((w+t5%{L-oled)g^*}wBRD)!FWj0dIyw>0~j7#VDj>Pes+36*=Qv6)m~#5#XH z9++w-I(i9QH$=GkmrFlcp4y@|u`JS_YCnEUW*RhKc<#*n+~V~En73MCx4x;!#HV2H z0?!m13#xL&xD@SU%6!>A<{vr+L;?Z|k4ke@v4r%B1nv1Q2>yW5prWP4j=}7%Kn_0@ z*J8i8&+=aBG=-CVP^8)&8B<_Zzf6w=1NoRMG(dFT8$4cE2RCWo8B(DS5qNCw)&qA} zJmHKgvt9II?~ZnWfsKmvNkruu^oCcHZN2-hAJMI7MhCJtzIF?3OFSwa(1zREC20!Z z*NxSmFVph>9xBl0bG`Us-NfOfvzN5TX6)DVIMuk)o|eGK{On4l*P`ROXL6ACP%rO^ z=;m&KjI11cO2VjxE{FxH49^6R7J$J;%><&>OdO@(?Q%Cpd(e=bK|N*)3V+ zn2n*c!RVx89Z~w{ig;Yx_C*6Vdv=fn*n_Z#I)xXNsHOt{@d-S3cYOU!VJnI3`Q%4eO1UEY!LP z+Nc>`**eJQ@tEjAf~kYmfm5#LbG$_@diMI`Y3mQL6?P>xi}2@vaH%f{MglBPN9Q`_ z*}wDN-^f+m?ZH>Y7UZs5lGyR)%dWu#!+9`S(%;0aH_?Q?ke2lF*Xgr?k&iiQPWH5W z%FLC&U8d7Ls6vAQZMQEs0$UD@NaB&~jA3vc!H1IZmwK7A8Ay9}onvS}XH;q}ep9(oo!RqjbR6hb<_ji%s15{bKgVVhCllJj0U|Iu3luG0;t>}4Jy<)0R$ylWkalc#e;ilQG;%j%erEmV! zeUtMze^{gIGl!~SUbq;(MGyYmv@PUr)5>G#;X6*qqW!P3I=R~jugXT%;AwC+P@Cj) zvDT+LRlgeT0z+v%ZEgEv3o5#9r{%uZ87GP^?dmudJ2`ZSg1&e;wGzyH&pE>Wv9Ub) zS+#auM~tJycf#T5N~Q_SRm#80A`rRsLB0khI?*thBI;Em_XRE&SIicH7A{zAm=#{N zBm>uel14%iS)Sur@Omy`!)gl7UfN1=(Esap`-g49{jVEwTkzYlq6;Cu&U#dL`GZew z4o&xea_S7B9&G49l5ZEVu#ewg?Sdx?3_eyE&fPMMf)aW?_4@8N5b)D})kCy5Y9IpR zfLtF(0^chS-?ZaPS4iyZcw>yE*s7z!eZH^&H=U#EnZpIs&7R)Jopy%nV>j0My2a^H7X?@ZrMiB-cp`g@ zRoXMOAaDVk_kkWo96y%gvEhbnzR`Xtacdx_!N_7b_ijw|n6NTzxc12)wr2bD?tu`7 zDo3-_v`}l-HnL~TE{x>Ea;!ecs?A@5zq$f1hXPkt9UZrv>c4V^c>IGtL+q>eos?0D zsG^NaQ_rfu=8|8z;huVn+>3phTPZbQCtk~ms#BC|lK{HNbAPXI*-O5%KQm|@ z&;4DT{lDupEh1q1ROo8pu}-A)()&!NIl~vY{8%<->=1AvWp9RYTtetF1tezc zKr;!^+*)2y*k)d)JgwtvNXugO8F_LbWFcPvx!jj@YBwznDzCvsU;pHI~J{{Q$X&KYu?dynWp}$ zM8gA@0xcJQG4hfcH(s|U>w1?6;rKO`t_V9<;U~C1jeC{muLsqe$Dr)sfsnZdj)Cr_ z+a$21M?aP;Z@rQ$(;}+{)Csza#LcJ}pd15bH#%h9@+jE-E@KyN0rNKW!}BS-B^eFI ztV;#reQ6SMEL{2b@@F3SUydiP*9sM95Y1`%_WZ~0et7Z|l z>^B+7Pu$B}Vs8=4%GcX3b&c&kYE%`7Z`tXTH{30Ec5}8&dC&fluNqsh*y0-JCBb)=gJzYtWFcog`SUTrn#YN`|b9DESfhaUKCBY&8Y301-#$0h9HNC(1UORK%eM zJnllvQ|jl}XBCX4my|R|VU5%3(51DO$DnTuUbW5@ofR#0`B`zFiz=7dB?%6f-V3l8 zR;BlaR+H1ePr!&eog}j**?RBQi|q+~HW52+Z_e`BFr6%fyDca=>;P}qy=3j{2Kp1j zPZru`)%=oWpGWuUuI8g1uN*UJ1ofd> zA8z%b|NR&VIThc3GZVT*z~Wr3)!+jOB!?GO5X7`9j*D6d(36(m`rSAvN+RpVWmkgq z7=E(Gz0{lKm|)Qr>Qdk&=}32YHxJLjPKd(s-6|S?uu@rXtZ;mg?sR;z>@>CM7)K|%)$xn5JdVK9aVR##qS3g&*`zZel4wQX-R;=W`&cy`o&hS}LXG_mA zg}^$XTvg0w@rDT%hLgjSD1%l3ePSFL=ra=@cMJt*RHtfRq#0xF_BcYj{4SGYQX+EF zOyI4pS|`%J)RGvWnKsoKDaQIb^Vd~MRrRGuXB13QAcyhfeW>Wo^OF67Qq)eyOpl_@ zYy(G7IE75L{?Ork+Hy`WTlM1GSb2-1&E}5dRUkhRWS^K}@dhGHB?6JT|q;>EvP(C3*m;^(A1!z9t+ymR4M z#zgDyljLzcMW8V~vPsElcU=$Qp3FDtKvxR%_d4rkfUy*aGY^sL%Vk2?VSN&x?@i<> zXX@(OES+Q@--0rhe&-o<5L_L~iFDe#cXv`gOOd+yxTxWfSw1)=fn{;_q5nlh%XoYu z!SP09yjqtXawY*dCSCbcmM1fGYp9?Gx#3gZ1h40}wPfaiBTe?OAQJ7CeeqvQo2iGG&8qBY z&YZ-1Z;P$2U$tU{YF>F3PMh6(*o|*>!(_Lw8&{VO1?^VmCo(R5$4#any=SUREx9Tt zl)M+c*^iG=`mN5%W08@U{u3*gd_!er#Fj7oPg?Obb9FrNRp2Z5rslB{HEA5FK=e>X z=i{vx)d2{?7}J|uK0+X$p+g`+Gk3~?lGB?AIc(&ZEGIS1kd{89R-{*-`YFv`>ij#w z(`g95KJ(4&>&H0^Qpy|g@!X6?L z`jGOccK_Hy3znHZLOD_95wmYO1oCOQs>J{PfKWFc0O;m2y7fFL*QKNH+~ZG#k&Iwm z^-aMq`vl>izYNaRPBf!s zGp!`3Bl~Xyn=?V8)Xyt$t=0+VLUNCfZRQf=q}w47UM|ChJ`7D7)I7T7E}FIn=AeJk z#9t;eK-PRpjt9w_Xa8V+k<)0q{R1Fnx&gaOQ}Cgs!KmG{$gav@I+;Sd5UnGOlkA_*xlan+HiNJ zomD4ke*X{UBv2g#%)0qt=4Y>3&_47V6UH&f@a4J}uVcj)_L+iQs_y+v>BHV{mqJ=w z1klwbofV9UePZJe2eaVCbHz$xJub&<1CJ2~k`Z(1ydQ>y3}VzwzTOn*Et~Lb`zEib z*h^{zW`|t~25QpNI)p){LPs%k`~l1OK0Hz%Kl>4jdMYNyh7K>TT9D{j>tC4tgq!N& zBk=tk^cB)KKor|wb;2+f)XWy$o1N%WLp;3A2r*0&V*C!|M_&G@HJ3>52FJlwhms>k zlngFpsYlz5)Fhb8`BBU$Gi~p;dL^D@1jIw7acv>I{o-|j!m!ES1U@n8E}3>0Mf6}+ z_{w-`7E2q&zcAeE!b^!2R#pzP6bXzv3mqxg^E*LPY)#dr8&13qokWwC~mIof^74i@-{5T)-%;Rsh*@>K z)Xr8l>*>%!Dn;yekLBc$+6EMG!JoM7glhB^>)7Tr6Pc_#zDoH8%-iig-bfH5B+P#O z)E30N+Tsmy6L_oRtO?;h$!^>PjRPb>a;eP4-zT;eNZo*>N-Dda0PTFYcj_>Pt?NOc1ELqWDXW`GEDVRKK3QCKR`z$RsEdlD? z&)~w;qFDw_PjB526MmHclW7EE3~>?v%`5TSWe+s=R2vTzq~TBdtLE$i^M)0N9!)@i zUA_AX`&GF()Rr3{I+sg@1o+ zjoRNGRW*Petq=0Z*S28c(3_%1-#x%!#Ir6;Qy&yvm!f04vG5z$AX&-ovaajk`Efln z?Iyu3HKrfA4Xb`!&m~h&z#+UxkB<;$pWB1KY1HxSH;$)CJU62Woi^?H{#ZnU7h?+L zB;Z#BLL8WY*Se{#ASg{>AJ7e32~2Mf3o7xHby$E2EG}H-{~@k@>r1Vhdf4mlH%wOQ zN7b0nispK-g?P znq?0BsAeYPGJO3~gqIY{Xjo#4R@wVG=TJ3WJEXVL!NJD<74}6j8+R#@tyfLeDtRPR zt_#-+gX&Qj|CIwQ>hnrf$I30g6tH*xlIPy)WW4=5zrpK@;C)$Fw9uI^pX*;4I0UJe zNy`XK?}w?orwDILZ{wieCBGYtcCGl#dZ$u@+M0oK@*#~y?)}W5ke+<5dXY8M4ta6O z;lz6TC<%xKBYZv%o{qa^7;hV);+il@r}YpZ>m;>Zy}w`dZaA33NY`+4_F`zFdW#%_ zbEB3^s}~LWfI}}KvQOQB#XUDR5-lJ8OLTiI@eV6X74NLJ4snQd&-6ZduLxodc=EQVGS6e?_@llbRp_fDxwBB4qxgVmx zUjaj^c7LUq{A7jE7JAb{Set;J%p-kRZ-uYTR+;2=PdF*=PC%h) zOdV_gKH%oMLH;)a4XBLZ^wT3^gP)&7Zf&%TAD~hwO%ZnOx(0&NuimVgQF-a5RfD0M ztm~PHRJ|g6VqNa8jdDzfS;68WHZyhNRgWU(K%iQEZZTpV#aTrS#yo#zGTp4gYus^@ zC9a-<$sRCulXk+Q?>z=GI@RJT;>Ur`P@&3K z$~OmewahL3QnV((2-DnXAVuVINiYeVu07C8nLcIRg$8u8*+iucZMO-t>+bN!ZZLq# z?`VY?aJ?d?04`l~UfQ$;&aK*)&V@`9aaXCdV*5k}>*ynnO%qg0Eo+G#B3WEOt=c9? zT)hzAJLn#>Itur&-Vv59t8TD5rNMvW&o-HZeqhu)ML>kfb0AiA(@9!E=1unUU+QrJ zY)bh{%RUAuWA{wx0g0>0)d1Ya&Y_4Iju zoUsKM1jc#o-hEmX=u%9=N4s2?B+n1W>=avt+=O(9RD)A6N z7@Dc~jCJi96uoODQAeGcA_bClsvRq}&`V$#3P=`>P{805!_)3B?$oCqAnFr%FoJTZ zq=I47FyU>cwM6U(4#J20HLCxIz4wfYYFpYy6+r;3X8qQ!WEdq9tr@V?^yyK4c!YDmCjU@T@hXxG* zLBw|_-uaJ>L2-r8ihvnu+*|H%FG@93&mmt2D&RZE=h&P@A=?S#4BsdB?AMnk zB~JHA`ytNrey!KwkIpV`aNRXow-e^! zorf4`RG)^Q(~U5_c+@_3ke zU5Vkj*5))9f+#sA$nL@>mZawg}lI`BMeF9;PA z@;{pX5disH^iM#`i-x=?As~h^w8Qg;!yR|&(uLVHRp~_#hwBvhMA84b>CLgQIgoKL z8~1a3rCXROSrW_XP`aJU0KUygd8$L8mq&Ufu!FLp6qXVKv|(dY;{dq7`FZXDKsqr8 z0V9h>R4@(n{Ma2JNg?;i2WT=P5_8_1#`3ADNER5h0Bp1}z-|XsSy5l&mY{?c0>Rie_ zue@#GRfLqIhYmM6r zO&dHahPW8Z`u@4V9jx#U&0s5E%*C-E>m#%L3TD64VU_nSgr9_|H@n9`gUUc#*`wW{KNo^g&KQOKGQoUlG{ zz@=9*in-taJ(3x>i^HgoU!}^id+M}GWq77rI&e&9~EkwL6dvv3;5sRk*ByHNh70L7zfkne~ z-;A4BtpXe7;{NmGZJ3zG1(+s;=y`{1J=Ttt-{r&SbBIy5jtxx(7&d@j^}!O<3!3VwVtd< zVLvHG=z_#VEH{yM%+dVO`%~k=dX5}Q9C+kK*+}5oB1ef*p4-*h<57cM|MZa-{A*Y1 zCO#Ej@Y}jS8{H@kHyvQjD;M9o$udH15r-@Ztt9jMR~Qv&kww36B8w|JmG^!V(Ch#n zU2@#nnWOu}V%0_rn@3fe++IuOCF)c0%CT8;sQ2KLj05V9mHyO>Xf9jDJv&cXxzJ3I zIjKTvz1y!OIJ7dDL5rTN_ClB^f^KI__vF4`i(3rEAZ z1{YFzUrDB!Is;;ty!)>80-TGZj>f_n4i4~mXPoG1ckaoQ5i-{0jxARID|sJFS7L-T zqGR|OsoFrXa${gqq?~H0Q7G4(_th6dR*qc-Ydd%Qp)!dJX7vOu!Q#TNA}b4Q;fycd zXesr=B)W3MdU3}^rQV;+)ZKZCdzJfSt>ArcmiMI%ms@Aaby@XIN!74v*UyheQT6C~ zTf@G6Bsce__Y>@G_Q^cUY3KQkWzI0II_KSp@5I(UTyT}ElQ<)D=|1=$5^#AdEQAA% zrke~iv@TK?sqG?{pIFSu^HYBSITdKX$#-Z1Q}pC@p0#rvQNK;K8XJEn;5WZdH9-O> z=*@v_(8cb~k%E^3wm&zGy4MY|DawyS#2cxbAuVzB4Zb-Gm%uUCy|$2agrdvV=zL7ajmF>4tzBKb*jJ=jz+G(pgEU#z4MbFh= z2f%y$7pJ!5@6E=G%YtrsPkd(YA`pAL;eWMHlWO-=^E^JO~YHBrp2k9@sbO>)&W|wks62| zEemkl`p1U7nW@*DKz45j^Yvye@zg^T4`9i_X{vUynUF`d6aEqsbDU-w{Su37sP<4N zB~?WZ8tInaZ@pRK|76!y$x}}VVnHmXjdZjSWZ>{Lc}4_eC_bj%`VH(`pBcRqVA>%b=YGpivCx( z$k^f$3Pkqjg}wD`nr8=wdsc-W8>0bTw)~GdR(&n|p}|M`;Z;Na%kaElOT*%zY<{g( zl-&F@9v`F`w8=qtG2Kug_B|NH7M(gyh7r zyv{c7wVIjW1FNp#^s!VQf8Yx0hzRXr^`BLZidL~}#Y-QC^* zuW;g08^Je)N^g0rTNe_ND{Z2e{OXskj%O>>Ah01w0Zfs!HW}>Ac|;x78;O6eekiIdewB45dleE1NrOlapR1Z z@BWxEUU#o@^!Rhj)bIAtl>l3aD)s6UG3{y)kEQjZaV@<~^?fnPxb*}Hw~5-L9tSlA z%*~6bD%&uJEKsbfE#$#f-qudtGf`%0Nb)@a1MAWIa_=}{wmL-lcsjISf{-vZT4kz+ zD~x?FK@N4xe1o0<*G49hkMiNXEseRpydpzusduIl~V=kC?E{+bz;gDY;WE&DHe#x)~tkgVem_q_OFpBa4V zMH$-70oMzC+u(uMhPpK<3UyNSX#LaFvKKuf@tWI8DOS%Xp(fp>Ps~}5^UP07^QzZC z&zNWYlbSRJ*T!PA4|p^i&R}7W4$QsS%)hwA8{(;I7unMt&V|(L#9w>H#9ZV>M+qsGbgUL22V3UJrk zY?%0D^n_k*4YUP&EA<|pX%Bch0}BDgbLsM2+6nG3T}O%gS|ioRa9u$))Si9o^I~@_ z;RnN*H-yUOzFL!s@$=5&MsJPI2GJ63N+=3CXG5)?4f<^9ratx4;H?1(9C*l6q_{+qd)i` zDTKk7n@k8 z&x#~2A#HSS{%7$?cV#5WEL=Y}B2`Ko%fn{EmR(0^b=X;r%bexRVRwxl#aZpHO}%7x zX&h#$$qO*#xX)cWn19BbTyrM-;0R3{j&@s$mA_qheIYmE{rRM#y9BKUYud<->RH++S7= zs?q)?47d3H8|a8hsv#P8CD*Xmt8u{x1KIGNiu{UaAi7u-$eBzofn?CF)k_+XB@oQG zB?Plw>cU9542X2o?c|n#_phd!d@YcqUQ?c2(hn@?s}~{u88-p1dWBq-2fP0gV`~UJ zk<5fLsuz>Ook^p%Nu=2FUhb7-y6$Iw8NPQsvYfbI=Afaco%BGrTVlI#M2ShK8bK>D z)rZ?oEanreEZPlC(q3C zU~Irf6YH%%kHUZ2h0A&KLEd7qR8cb<^(mx-A{xNrw|e6?hf$$dKaU2*t^z8JeA8iy`ClTx~!` zKMLTMn6TT|G|GV%J`{F625`f-MG%eBjjcVE@&+e5#)56)&Mz;WW6+r{gr!C3l2v+ivaRMa~Yg6 z>9A#Wzo>roiaX4)d?{vg`VOltyoU``iilUDLI{k$dIFZ**fS);0I}lly+Cv<4G#7V zaP=HtE$Wx#@rbd{D-R5P{yd=kDfX923mfB2rbdp%yvO)B_9LtAzkm0~+%(}D4VJ(B z#1FiMu?4;V5exx7Pmv(PXkf5nfi8&RKR=|rxbg`73k3>3gCgq_)pAzT(Q|#YT^1B= z>qo1k>f&Jn0H*F0jvDb;*$k|3qQMjYKhcLk!nDq?jmm9jvXyS$bE|NdZc}Ez5Aav9 z72I%m7_AxeXqV4Vd6eZvrN@^kDaHJoT>kq zc}2Aa%2cAo!)T}tivP&c|91I}0SY?r_1*Wsov`0t@taxuVvT~n+4rE34A?NbB zL3}Nh=+DjaPGAo8umI-6l7jlnD7Cz(w?<>wzLzOwzcKdG|K{`ZH+tod^%H2v&3s#= z({~lgvG#f6w&5RoTp%eIPe4F(1VMiG^FM#x<1VEq|M@AUQJq9MeY4ZOm=AxB^*6Ia zMJronvp74Oxc2J{VD}O9e8m0bBG20q-#QjM-`HEb|?MhnW{Kx^qpQ5Y0|oV9)gu_Z!+xeTWsp`2fa@Hgr9e2+@6kgb=k zn0Jr(Z4m|2@~iK!fBY#+o_iSNNivD})W7;BM8uvjr2_U>k&m(RYoz0!uvf0Z-~alv zKcAhXhhYYF-cP!AtXg(%5cKC(^-RG9FZ1U8(61};#TFp;E14@B2-!>th4vOt4Q!qN zyx(67_H(LmuKK}q6gmU=5a){O{?(#NKc$H-6&1TLvY$w_;@9!51$-l`zp#KtBNeQw zpRA1t3)Mrv*^>Tr&VJtFukA#{3?5@Tl!=4g2g}^AF!}40^y9t2S2b2aqTdYhizQ0^ zV|5*RrI{wPy6$ojisO!OhFEHcswr?*FLBf4RQhkqV=Y_}>HoX>p`1ozK^2>%KU zRZ+Zq$EQSPeB&1xlI_7Ta=yHM<9eT!sC=qH_iTmR(X*1(QO#}y`%W)##`VtuU#X3> zXXjt{`(^B&YPgxQ$?vnkF2b$^qo7YW88*@0_2&(7;%j<=^2cL6iE%Pz>lCLwY=-W2 z|0z9xiCN)Q?6Icv8-aPN!yIL6W<^)ko#&`cxs!+6>bP5M9!QEU+VgweGs7e-)F|60TU z_-OM&fFbt0%s{FTWz~PNv)doPvkQ>}GD^l1e_c}q9^I;QX_^1}-~Zc>9Yj|f8p11h zI`)4vN54$MKiys6F;L(|Z`-{8n_~KZc!1}Q$d#)Q=bBWtJHIH{Uv}27o8afrn!w&A z3-FQr=k4YUot5xc)3HdouvONwfp%(ZO?%<#OZ@4Fg*F` zPX9)a39L|mgSCKOmC1(x(g&Uc;z_Sp*6-E*#vvw`M|rVzbpOoFtDQd<^T6Ye+|2K_ z63Eybwq6g7hBRHu2S?xLR|$ze!Wf^?_*fIZ$BKPK8#I?{=dx!a7(d~H>@VV zk{`RZI|P;dbYW#%(8-gSbU6Yyf4%w{jh4?YzTh^m>6k%R2fT2<%Lh@k|Dw_9&`|e~=1sd_ zXGQw{_?@Ds2i=E^+Ix&ez}G;cJM1#+I|t-d99VALYLu zE-+46C^x?L?D=mza3IP;3B7>?U;oQZlk9M35z}9Hp?wTLZwS04sM$1=%ddj`+tvTu z`2O}$85q4pYR>GR685(_{9k_*82`UR`AbB8PTT(5*^r{*mv}eugCrtSA0+7`rj*zj+4#ET~|kq3-$M%ya&t__eOl zkZ+$lS3u2tb`@+SUI?B>kQ`K`oYr-15D2%eWW!}>^s9dgdm@8$Y7+C7NWS*cM zK+|P)@To%fo2*0Wh}4J*nDz~pbsvJRFUEsiQXH_jRK-zCmU%b0x?^8;~dp$^AsJ^ zmDFT3pClLwj_E(@OZAq#NV^ zDjlBt;r{INI~tqE((%=>)i@q*BM*&u&ipHGWVJO zIxYe|uQnc}@z|_7ObO^J>E)G=sZmR^geN#Aa3M~28&CTY^_IuTHG<8^<|YLtO>=3! z#V>_x@Hj~MgY)@-Id@jMA{}Adwq)O!drwrN0LgKTRE{FsP3TEaS3J*XExS$H5jdiz zDqv14#e&%6t&ZV*`PRqk#Z8Y@%e!(x=)13aEk{5uv8t}d4kM0H%|p|Dg?blJ(qmK8 zTpaFnn3a);HJQL|pUsu&inQ{8&~`NL%9Ab?sZAjp5_~NQ9;4U0g4QbLF{~DG0fPop zEoMAS=G80dFP=kE5!IcH27d9H%>QNz$z4&Jw>h@fU0?p0!0CAADWPAryZ48;^i!E# zIvkz@GFk(fw7A?^VtdvU$KHZZc|Z&C$)^4YS3xLqF(4RqWunbiwXEs3t3X-TV<0_+`!jS+aoKi-JLEWufG%~Qh4%T`3GH1EP|gS% z$*6~aQcB?wc3a{rlq&><*TykyruWoZl6^@GKA8z^B zzmff-gvO(#%{wa!OKwFKEKYW3ex z`&u-&vvvAq$ypNV1__3LCe~f4Whf(TNf8ccus8>yK*zX zb!XzAp5b3o)$znrJe8D*JfWaomuN75^4-2oH?BUG`|?BE73#<+!vuGix;WdHJb=Q_ z4EH1Rw7pVcS5dK45>P=HNC4{Ocrr=wWBYyM&NU+IanQiUVYFr;JrO7nE?%q|1m^UgayBdne#hD{{T%;59aV&+bXsT>v^V$Qa zmIoNq?sG?Qyo2c;*;vi2*Yk-*_`^rpFTA>l*ikM(KI2;QNw|`_J|MK>S9&s*V7(M= zaJV&R(6c^{adh6JY?!!#ph>$h4~Y+(cM_a?R!o@@kW)}av%b-u5m)>jec8TW|Lo`y z)9zc&E1k|D6uh|Pe{q@-r%4_84?#oEVsY~AdfqSHrb(l}5igKZ!R-xknw>&~`AIeS+Sr6=*y! zv1`X=G3+5``4K7_h#KP)O+mTl#xrgN^-#uv8z#D&P@$ZGUNV3A#aoZL5bU9ZaE`qB5&>tjQ> z8S5H=X7tovoS(diuiSA@plI0yV5;=6vqyxx17BZxod*)}j7Y|^cQcvXwTJdvx1u>q zoH*3#Z-cxHnsTG2TYs)v)d0U5dAuoBw3?`A&sg9_Ic(F$y(6E zQ`_CK)Q}huFlEX22ZpW!v~HHRGTUDrHW=$m7Reza?#olP;=e2I_7UGKgouN&++A%6 zP$`lI#vhPyqat5Q@|P{>29ms#&yakID=Q)uT02>0NoG*LzZCo8qA}3k&kKuh%nT5C zf1gny!Wb21=HDx9lmum@QfKDn;+ZK=*D01(314G`Diq}hO+beFMPq?gdkRWs>*V-n zAn^FYAn%qslII!MqsBGW}?Q4*Omy&{#4?3OdU zETC0}z_OGkFz++$){`4{ zy$%(+(?PFDGN*6E*f=A;Xl6QOod8I}W{T3vKs$zT zpY`07^)#1Dtd8`HBF?YiSf+eN-+mgFokk|vIqijV!{ z^3**ArZJ+EI36kH;%C>ytw0k!SDG zmdtA?JWC{(-o5FSu?~a;!2t8Z^s?#;-8Zm@$M-%x+NoDH7DU+B!3K-o>_)vkmZl;b zS70~jj(d<>Xf-wma;F>FcR<~YXyJg@QUTfl&%tP$K|LvXS=1R0tt`xd+}^Y{itsih7%EIW0m5j)qP=x@Ao6jZ;m=) z)Eaiz8LD1!)m>5WxXY_TYAj^(s0%YX9$mckL$7>b*UXigSVH1C`w&eE**39G^F>rh+sCIk{`Ea{YJR}Gp%)9Nh_J_<3K@|Lmbhl zn%Z+QRM$##29w6zZ&HG4h6EZ`FFeJ*P@+wf~iW%UR)KI<=%ozTYbryae$$;-3 z`IRZ(>?=`lUyvCzpW}vgQV|XxVV2v@lzj3so1 zW;Y3cUSxxTf$oc}ayq=A2A>Y9ExaK8F6R{3)(JJ6?PiI4Ch&L8Nhzk=onhu!g$33q7Jq?$v&&At;T*NQgYU!)N3&?#@}W zF`{~{=)&^`$&ccOJZ}$C<%cWYGJF`jr%gczN4!0Jz3mCYTxoG`1L7jR;zQ5oE{gH@ zC6ZRwFU;(0Xz7OBwhBD2O(zRhRHu{V_KkD+k@~9K!1UV=8@KJ{Gi9vaYS=1FNlyee zd(K@=aKYrne0Qmh=NMnZMz#e;g zmI>~aI3u{YX4mFw`h>&kP&-|5ZAml#g_%Pc)=N3pMvX+oUed1JxU1!E9!Wv_IvY{A zJ3+ydZBvu@xF55)Y+Nq9x(GiOjNrxlrLp$zRt}Yb;K}wb-6{(*7+;>F3=l}tT-``e zL}%z+WZ~%Hjyqb|Tlct_tkr{mla%UT+dtoe^NfC&N$!1{QQn$IHxo@A( z&qarEl~r=PM4Hanq#q@fLGEyM>S2lPpZ>5}?>v%1AhJi2$xU!s$ZUt?42qG`BV%Sd zBozZ-pND&hfDfy zrr5t#;7dHXdUoM$wa(INo7<*zCl?_&0Q{HcAfF>T4+l186Mn@G_xDC?d4(0`lO~$+iZ z9any>qGcb1QM!{_Ubw}h0W&GA8^=F^Y0fZxDP^t31u8JH_=vt*@y7PX`N`(1M+r*f zlM z;;DN{ov#Ut$l)TNEGobkAG)E*y1~-7%32Uiykdy2sv_5RhX3Fc&$uVNQIUX1o6iJq z!=E+_5DpZ$*r159If_p1BiStYDsm8MxV<^GGemeaQqNS1Xp|H`!-F*%nP#Q`jpH0b_tB<9|PZ?M6Xj$ql0HDh8Qcq z@etk%XLATn-9UfauK(*q`W?3k+Mc8&p-5HpG6lh)@e)JdlR6h9Bl)UonTY~+vbx+S zh`cgJ7bMK;s3CxHr{sNUO4YGk6w&0z)@I}Co(hKd%AQg0t`m8`W*w)>3t{hzQ@rdo zuGeV>us0W=K`N^Y4FqqJXT5Hxwa`OtC1q=rcrKsCVr}y)kKtZ|nknV^iQwyLTj4uO zr7O#4qmYPCa_o*IjzL^7JHF8n%hy7x$Thln)AZpSr8{T?E~F_)VL0z`lrFB~sjP-wjM4y)3HKr6nPR4*P%?KB9xO$yYFd8b8MFNd2@7gEv3d(Q}i*OOgu6W)?;>59T{cs?uJ)G~KR9t=syA*mQlqlIfD~_3<5Q==yY`_xA+eEXt_wZ( zIqFYaE4*Cy#H>2x)$nNO)oz^AIxLvbZoztIs0d2OJ-lQ z+2IC9^HhcLUlAPt<57IOE`H_e*>&g1Dx-f3rCgqU1sqU8AZplw!UY4K+WID4yQUlm zPFfWf2CfXBr?hJ}x;#K1ymU3XQROn9A$3sA8IueE%z)VVRsTdN7zj&6S6XAq2f(hdb1AI^CZrwRW3wdetiFK(#bQr z`8R3KN;rosPlb^O=A|5>HK!staurJxOy*6ic4p_NM;OiEpwFSL$)h4Hq}wrmm%(VX z4$vCrf%2pDPWEsHC3akV_(Ts6JZ_d0W__}OAte*V{IC|85$9$DUQ;@~H!kM_;A5-x z3iC`_t!Nyg;|G7#{+MKu;V0=*b|EmC*@5x9SM7)P7+`%|Q%cv>Txi0GQg_u|9~)8I zOi08jfUaWYMdqQd1QD@4i-|15CxWG5`JRRF&+wb&*BzS-j=D3cX~!>PtFmzTmYj>{ElpvLy-{}@;=^t@~g_REgAf;vFm z=Q>M*<}bm?4`S3ef8^v+^btg=Tg~|_&54p?coe+-zRgPXkca-(XSxADC46i3{;~K+ z9hPsR9^)jTTJ})I@NGBY@sqk2|KtLg&If!@<_)E|6_d+(*_8cX*8vWjq0hjIy!C>3 z6T@kEufCVN^D-zir%V;KY9JiwUOLvJsD;Q4#aBAIhhHl3t~w0AP~u}jVw1<$et#R1 z3&ZH6gKGQq`v$4>Ck_MeKxvkJWJPm?Dh(%NrCUXKl7h}l;owN|Pis6Bl{WnwryeVwhFJqpC7a=ONUo9!+wpCrRP_@6`#o!`2WcQfi_23Xg z6f#QG^Arx`w|(jes56v!B2I2|3ST&Nw{~Yz?DP>8~elFE#lfxvP1HXpx(KYJcsn5_hDnK)Nn}wTh==^73efWt*^V zbM%O{5d`p5k#1V|y;uTK_FGnKM_m2T!PAozOJdDEO{U`aA^es(I9z99aU0OvRN1{P z2NkweuJCqe>%#yh8dl0VsAZK}cM?_aM!tB?T~Xp8e1_s3`GGR{ZoIKzwdob>d?Ni`kIAU&MtW zDB-DYa{M|CB(DEyX^a1@o4RzQBs>nRjnFgpd)?Ea_*gnOoAo4!a}zBIEeT)RZ&6wLF>HmScF)bTfC-i z0t-e!A{l$v#&u~qB^QP}mlgGMQxERZ&k3dXs+HDM8wANmllk$hFk0}hPFaDP$$NA( z88`DDf9hdhqYxeg*CRE6&X>007J!-(q{He*zx^JM?0iwlnbf zs@W~dLbnEsNOG4IaHRRqms3$FF1p!aQ+s?rKFwy7-(ys}FT@Dh^1Olhv1X8K^q5Zm z%UY&Js)!)Lo#*S!shZj}AFOFY^C_MhnpS5-YB)sqOJIN=m+CDkBWAs^0WR_z5_hc2 zf$t+LfFKLu3n4&gL<}8y^ofldTwgaIHyz4Qa4rofq8vVEhNVvp7sq>Jl$R% zuXXLjTOG7UXuES8L4m|KSU$wH{-a!}6_;6?-HiL$Nh~d?2k#iu?F+r*F5#10c!#5& ztez=tN^rzJvRM#;Y3Q=~`FVY!bV98L+Fn)MHQ+GzJ2u|XZQ+!}Q1u9p^}fb6;}=V7 z?;l=&9z&jllsV~}{l2uU8!R4WTej09PMb)4x_8=Lx?7fjmNz!9NU}XC#-X00_{8=s zh$9BX!=78=?k2X|O}3S*i6^K+EPxX%IO=hJ1owt`h+?Un^XQ+ntrF+wws=fEAFUw% z$E@&Os!s$u=~{eTzll~0kUs+Wk&t_`=f}9cOoy91EY1E7povthWs3S!(6&eEy^{tS zJ5tC4&;_<-zWyp<#Y*p_LWrY(EcH0hFMWfINkT;~uY^q#d#Xx4<84v6sVdg>3%(Px z-EjiVsPyibs`b|u-3Q$CO8IfaWqLfpuj9>l7(T`_8-G3;{pRUe$Qar0ARo`6)H;B} zb^`Z*7ARtc>^uk2{PX@Wq`<%uq{v#KkquW=~a#if&(rrolx!aev^>q2- zZS`K$OuMdDJi1Y%@!TZ}6qFo|YpXy2^G#LNQG{yOnDv5WIYaU~=$mOUkdYXpQRjk| zW1lOt?IxZu>G`G<0(%XS5sBwA8OdEy`WvI>f0zY5agd!-exFMCE7IU4?X1uqB`GI| zQ1bHbS|=m)P-h{fMxu{RcjU2rnaS|h9&*aHU}d1nwz8lJu#(~);D_(VSHPs(Yd8&k3|~s(QnFsnGY?fGXN=G;*lr8Lg~b6WW{w@ z!@JEM1+}Ne%0)UprtDJ|+1C0#P4rBz#)n&5Z}V|O_zvEB;@=#K1iTLqFxK3U76}GH zr@&GfxTqPD!CWuZBl3CxUjQKOk($WMWInC2td~+@C%ECVziECw&PiwNi%?PP{tDid z7xUmNF(dxv?3`L+JR$K&?0urOsgkZ49${a^Sdp$^v>M`zLHc=_3F$y@H#n9?%Bjqo z3TGgN+or1>Il?G+tx6MGUJd!pflM1#fOsXL{RhlD>0+!i#u?;0)r!I&O9sxt<|p1j zfZSq=unrRc>rB0e3;!}{a~@S;fO_~tyj?_D4xD&w%H4Pd5Zy7o^=#O;Mlh;(!4o|; z9U3>Fio6;zQiym(kbysNQ24;Ikxf(`Vx#8oKUGo2@b#AKoX?jY;r9I9xrZ-tQ>JpJ zKnrBZ1@YJn*~i{6D8YUVv2D zR%`oB{Sf(W6zE4N@*7X!!K((UrJA$y$u1DZrQn66iUf6Cy+N!sbAYDO z9hBc@6bikm%%V$b_x9rUcqZ=wd38^YCtAP*STr>6ucK;^GPy77W|IB&Oq>^|h1n@3 z8dm+nfIvG!JHdO&Uy$E)sf(E@CKJ1xPOmnHF?RyJZ%vp(e3jmIARY0gTZcZs>%?3A18xB@^)W} zpd4dHhcV?z;?3qx9)UwA9&rN5+$wx~@#3_!;Uk&71_NuY5oL34^mCs4adJy<`-5#C zs0;gL2BYxwfnmafbajg3(@M8`lCLs=PkL58b)lb|%XO)^5}98gZFUBymp)C%e!>-b znT^m64R%;WgZJGtm}s&vpFFPdNiVYz0G#;&fYdqp_7^M9-rN$P@$(uqE}b)wQr~2l zRkQl;L-0Xg!d7R#$;pTGBN2cdL0$zk^vB_ot-`D`k zFB<0x3K9Ax!0^#_Z6ojD_X|S=XX4~h3DfQ3jEu&*wOQXHWu?=01WDU@Z)^S( z()P3cB*Ys)v9c5Gj?ng!Z2X=JuIa|-g%vC0@LpSY4`4N0)`!txODSpCD+p>?+qoBS zGnU_&ZxFMD9vKLhW2z}N1{t|5Rl#v-vV7+oB&u)lpB^rFllFqDKNC{Ok5FEYDnQ9yMHgkx(@mvF0;=hdiq3y6YWwaDtjy0(=5Lv!?E93a! zHZz&Wv9Xm@xyAHEtvS)V}&+jCBz8%}I>>Fu(nmw|s2*o;7cbthX zjB*iIcvmK)+Zrgoy!iHo_%-P10NvZ^49LOssGFXbkqqy)5R&WM8!ynMd4Hv1d*LkU zL=pR($g)l!tKzvdvb1iCPy5;tNb5Fu>!(n%q|5Z;bM8CCpo|~iyr^v@cFjF%x<0)a zo)Ca~kD*WM`wm~>no)>>7bQT zBa{!*UovBK!6?=5nk&))DSO*h8ec6sFU?i%Hd=%D_Z`|q8~>XvZ@jKnITqL9`VR6~ z){~HSuWr>K>LUBZwEG);miFXjx*du76TI#Dk4R(e$@ugUjhBvUuUpDJlepc}n@sno zeKFHzXv2jD-<;IhjTd_>pKMlWHdK-wjYYib7qFiuqcoF&(ND7Ft`)B(xW*vOwCeH` ztzN(U5Fof%v>9;yHqi%yr%ZK+It@-vRD|COzU=}gx*FkP`(9yJwbAn|Ir*0-d21QW z16M;^=;spZ2gheV0n2$${sGI6oPw@#c$}_7+4B~d_S!t)gp1WA1dN9b6d;HhBd4Ce zFjD2x4&@TK9atWb)?(Q2^7?t{onnna!yZ=6$?IIeCt&LLO|9TPG`z-E9l+i*SR!4i zuH|q+4%J7k8%-9h5Dj{PIUj(&1vlm+qG@%;ZrPL_O4(Tf@4|YY$d)3;@Ij zI`I6+LqKga(c;?R5j-K5!Aab67gJG* z9Fi#3o9$k=jI4Fu#ie=V87p3HsJXvHG~?@yRuNcxTz?VWOY!0WlXLKRfmWIo zk5;R=OOD0Yp;OS#H(a)VO` z^QSN+ji(D{mdjZvI(UkOlxX%qjnefYF3t}sywzV{^Y7Pfjll?`sd^`hcISf^+OTOI zN=`{Mps_YjdEtvZThrWhTaKe+=ByV`**74vxRrD!-{|+Wyx)s&6~Z^w3CTVqGYxqj zS2_)heCw%6@5%7%KuQLBb7l;AeQ z3b8`y``L`{C~bqDg!sMGE23YK=Ccq^HuH(0z+%tu)gSEmNwu#@@4i}{Rvvx9xk7rZ z^X&=?SBZ=-C6(Fo$Klqwt zKFxv2E_0yhzqLbceR%(*<+Gl>P~|BJhlN`HPBj&AKu59>VhMA8WEUJqePfHtiy}Lg ztq6&YYr}i?PyNi(?&lZSoK>?qKb9+0?ogd< zGpJr%ip49IM|966RM1LCX-OBp*uxaU%)rE_zYl3J4&Tr|)0({I$oc5gDJxOm1FUn* z-qFIPGcB*~9SP7B-9V7s!%le-XJeeZx~rK$UGD=Rb8pZ?i+^;;N9cC2<8fiCQS^O- z4{|Hpwot+MI~Ub*3A^y=9Eb<$})CqOx#?R?OSkK*dLWDPBN>D zCnw&@)EznEY(1FLye}TnZ~FR$4a%h2+3ujm$31CiV=&LLaupQ637UBOaAZH$;&qkXWM0KmH57|y zz0mtH-`S5a?`=Iw$jSbzD7POGBCp4*;dh(JHp+O%lAiS5q_i)*o!+qGQT{?PeWk7O zj*PP6VeQ^^&)U!Vqvz~a+y!4W)ni7ho1a<&CZMIlmv`9OH=WfZ&&(G}QwPnAl!#9} zO3dvtO`pZ>nWa@QWzI=(uG~gZ0`$;MpH(^P*OWyH#wud!7G-w8r z$L+jM(?v`0xoc+RXA`+3sXMO|faHkL3SY~*iyHp;k(Omo92Z6j04X+jTkjLQwHRl7 zy(RRTc@O~7%(?B?qjG%h^wW~|844;Xj0H+S*W=wlme1FRJ~#?`o~|l$Da-BwT$}p; zVedV|np)GgVTBz~5KvK(j-pf%rT3y6*eJb9M`^s%cB2< zI7IPa3mTw_z+P=QmKs-?c-n|<@t!44x`|g^hxnY~wkxN^rlCWU)H$Uz*x2@AGv`+> zz+vB^+dX*)qm#EjDQ*hiF;zS&ctFQCBDp=93R!|u|K`VOR%9u++R598M=P>qH~=a@ zF2xXkmlv7ub#h)gWk9<{H(P2D+9?w5?c?>hxPjk^GeIj~So#3guT{%Y=Jr0L4I+h` zlwsJ;2)a+sbq&1Wd}9{3NI*_)mOw2s?XlJ8wS~kHO+<5iBP{2kjM|oJpW&&GY@V;8 zM-Vwc+l8PRfA}y=BU(N%=*F!i`x}js+XODI(PB^o@iJw4GU051*Cu%Qn>Hb0buQg^ zqASg}UsfG0s-!pNDy-@M&Ym=#Tljdd@imvta5s*%kJl0qS|@MiPi6!(dOSp*>WX2L zn0CRQ8t7=Tx{s4f8EnWPXnA1Lefi1|Ewzw^6mdi>aJ=?lYrWB$OJj(k@R+M`h1m2)7``X}{?x+LaX@S9i`;051*W$; zxR=*eFEy$_AQn0YBo0c7Y*7ntHW&h&ytPFo8P34&ctynW>e~5gQJ~=G+ZHnS0{19+ zvC6>8Wphgn8AFD6GSvKI9a+?s`j^0 z0YP+crG&Tz$r4bTIKhlg%aRD12|fc3o{Pq&$;VAc2RuD@YgvBqy7G9b8UQ#)Eq?Y} z)&tgvRhZ@J@9qYGhMBKJCRD}re$A)bp7ZN=)@x6XqtBQXQw*rHp303$89daEamx=tkhP87LS94jUm3wW0!0&0_bW(BweBZeFF?fe##{pwbNE{eLv zmWC;g>Wt5fJwDG!NK<~?2SqlIuBGj zyd$X*8ALLJh-P>CRRV)`(&dt)T@m|pUNx>2vjL2zybZBBO5;=Z>_g6D1udCDZnv9f zsg%2=|G2OLUx32x$0gHy@9!o*`0X#{nJ}fnWI0iVzc)ZeEMGnn}0j9u0Q{{aTo|_*R>ge*kkE* zX8}o7MlsV_qCYN;`K|an&fp%=rry#=EehAFDjj-K%xj({i#c@P(6VXtDw5sH3hfO6 z(O=9L5BcY}{_!WhJ>XDeX}N3h)0wDpD%e1v!f|8bWe(6jPB*FR?Uv^LOfx9{bTg}!?Cg~}A=glbYx264r3Bcr$y`k)q1-5C<}ac zM%struV(mc5!U&J^GU%yMq<{%H&RX|epPPY8~= zrE&_UsU*M7{$I}E=r3oo&}=tZ|H}mwXMdV%`Qgs^W9&A(ZjX^V#!~SZH{q;xIb-CZYgV6Wm4w)s`*zg4d({k?l?g^AwY2LI{LKyt3R#tn}%6|T~i`Nx<759 z2Qex=CS~B~rVW-&)&4_#;*c53DnMt}5}#B-06O~MUGo8HD97zY>b};~Hef~h413+R z;Ubr#gSxfpw1UjQsooS>-Yx?*@s(ASwG%+=e7e+|;gI3C{yuyB=>>3JK(zJJHZM8p z9ykIFjYm-?2z;4&o*`E=<n$5=;)AUfXIPnE)NVH>dRYmV4M#ydcD zMvOG&AMhA_-82IjtCCa4D6C&q(@fYoF8c!#Spnk?E@SSO!zm2G$(+4fWR8QkFfM}N zh+qqXw=3`2%k&Vt%xkUq{vAa2a zd}ND^pHBuA=aVx}A`=$H`O|m@OMq@Se&10@G*bEYU6Z*_9)f%<~_` zht{k*e(AovL{f{OOV2gKFXaa|>@1P6EXjaY;`a&bFK;eewQ2%vbdNsaw`W1JM>~r> zsesUK({zd}_0Z+doH{9pS=Kx{pZfY3Xsgk7vw>j~YJwm1j>TK(wRbVB?9s;%c`mbX zLm{%2&&KkVSk-XGrt>P?>UJ`FQ) zTd2j?hBeluGX#zj@~eApH(jwf1$!K)7Qb%c>&2~xZHZlF725RHe@DKtDfMs=8p$Rt zh06%~P(>uy1Y@%^u471=1!<1MvnrZxc)D!qu~-)z!Vwg4MWk<^#cE#a2Sr>r832ZSuWNXcj0mv(%+%iJmM)iip&ccfFze6h zr&?MCA`whO`+O#Aq*J9JVpup?ySDOXronB!!R{IZxZD#?xO<%L%`!&TZ8c@jmm9C( zb0MJeYfo-!-jg-`FErltPrB+D}bPACKDye#)3IGtuZ!sZJ>h-!Y1|X zJ9J8EF4wSk4bgJ(Ry&Y3FrE!1&D=eRBT4|EOV6!o-#8zdC~jc!ci!Ay=)9nw2`(7a zJHC`)Rf|@0U#ycHMnYXi?3k2|EPu^=(lmJh8_afi=*xvEHM3)nJSTV=C$XvOv(jk# zZA`^q0y6Na<=TfgK()$y>XsSP&s(a@I&0k|=ogMZ8ND-?Qdr$IC!MR=<=h>dq$$_vU%RZCZ$gSSWaHs zBTa|O8KoGZFG!_@Df%K}n=YnCzd&dD?WQQot#V7IBVWwekrg9IqcO(i<9Yh_)xHsO8QYO##qB+A&!HP6t-q%;Yi z*5dbr+uf(Bb?wsUTbp0;0Y?wwx2&fdn*bZt$1wA@#*~!iTr{dFW#xc^^M27RZpTA? z-p2B;{p?NYoe!QrE-_FgW_Vxt*@4aa^$d8Tx(jHu*}c176J2DG_hx{5)U@1^bv-pi zB}#Vlmm&8$9o0LZfoxOXuwZOomMAR{a5~cVgwX=s$y}lo=WZARjYw>FxPvH`?%WdYhN>w<7%Jl1wV@Btk7au5Z(2 zYyon*p(~!dAKRpArb71deQ4!q$xs@`GYRxe0$CezL;ZIc*rd)yK@JZHj)R}iE|p1J zi?f+D&SpQ<0?yM=hZEa!)C!#(0;oqr9FCmfyxr5R}%#^l!5fN zo(^gO@jSZL)hbelT?u(}c%TT~bZzwBT1f~zN-nTm2nVtxUgJZ%O3Su@)T0hB?FP9w zS-clW9%h@>xmkI+*9FND0k9kBbnmME?#W3}hxMBVL^k*z@y9MOnM{a%EA{vE{E=sR zv(u9Fw}x^LCEBxGfu!P2kGAzv*b!ST}`w)fZ?F8GMDQ*!hKP+|bXkDNw$rI1F>hJnkzg<}jW!hEO^=}jE>4H^PS4m`6i zL5D7W{Hr{bWigZplkQ{RKJ0()M%3We|A+WVs9eb1E3#$$8f9FLXu zm+yNn^wl-+^y(@deLHvTmeg}SFavmWCC~Y;f(Gk{m&fuwh`)Dmot4V-bf^4YP*20q zGNs>e*JV@-pMuOc4tr&|mo$iE5fj8P)^<$ft!1cIBy@X95)ZaRNxhH-IK$S1miA<> zRCEPqhTQ0)@13LDlPFTa*&G?hGP5Ez@ z+G@;?Rwc9LSR^s-cbL_ID?(1C*n#J_g_qT>Wy3&o#^L?{ZXO zk7(IOv`?I*isNwZfex>=fuTYz0DPO+*HxQge3&cY_pS9M?v-ucHN(Ch#Jb!WTDxTl&$Z~^3bKV%9iK*q!iHo?=m&F7P4+(f@k~MyZY>*(iKI^M zu%=2L=sO{PNaLc9uWlsAkI?TS$B@cOQY1lq{LP zX6I5E0GdaS1Ma1L3pdf#){C4@swW>JeP_gK%A84D$f+%Qk*rEfhrJUIYP8&ny>x+g zuq;+wFk*i6G(2-~e-vogV6uUNv=-SJ%VtTxc!f1N@iCf3p_{7%Rf#1KiWFh01o!sn z@SxE(Jdw#J0IfiHDT^=l)XMn^^qBFEhv|&U_EblWNEs~w{oBVSoF{q}BbLWlZa=aG zdLX8W;1Ag14VCtBv^HUq&Vv#H{NLj+>{;I}-+AyDR+R^Mi^JBd;Kf*BI)P)dc3u7b zfc-p{sV$Ajmpy1o2CDgCF$C0%fqZN2<2oRiIx>;LxmdY?2^hQBa!+o_t2)Gv1x^Dk zQA``R)5z40=~{?ZTF-FaB~K}{7jt3YyLGtuKlz>RboQgK%-uHyCjkx6KOW`57ey)_ zABNc;XCqmJzR7YF=7BD2)q93p0i0p0IVcUI$&6SQ57JY#Uf|5mF8;C>!ggw7qRzLC zO=+whZQ4SYUubaCAKiJ`HF_R!F@Jw*@VwUymzG$eefR;TzwmXbb%r+8&Q--uLa=bF z*rnXNN5BTeEYM}k&z@WS;tVQ!f}eYN4nI(@6n`H%%I&rNVQF{>Edihhe1d6|bP3Hx zFIYie^J1%+ifT>W9&X>4;Re0r2%wx*-ELkIjINauSl=lrKTE|&k)!K3&~pcj?8T)n zlSt~@$ax`VIIn7B#}=L`C{fgOhBJbx`I`d6+Fmv$)kc@$eB)+=DS-T0X;dPv&a{IX z_7^F2P#e^GH>&={MP+TQ9FtY!ro(L{r8pO(?Ki&t{JF?PV0)J?WS}x$7QgPvTrMrb z-vkJE^b=^ftr2(1YqZdh{elKL%k`9Sa>ETfs?z2do6MAQvd&^KRE?zBBcx)Wsxgpj z3ov9+-{Ps~@QAOcaFaXgCf%l_06ERc!5ug54av+~MRmS?7+;w$4K@pLl1GjD?b&uw z@=9kin6@6m+dVc1T((}i=yc?UiL+P-IzQJDa$OlP-hYK2lEvA4-}EhG*6t>KiV*em z58pCOH;lg)bU2CiByg-p3&sYtZRz@vC%9ps7AJrSc4mLHo(PP=p}|6yIJgxHr{%cX ze;qvsxD@BS54ivme)-f{hzj|e%NEQs`C<#a<}F*6Rk=rJ2CgEfd;mCJQiTymCG_Rz za0PQR1aQ83a-8bGA$@d#1O8n)e>nTf4K)fpkwhPnze+a2tl}2zRj6)iL`Piis8jS5OC@}qj%)b zxDQUdp8ZX&U{rh5S%-JE7=M!DdeyPb`tIjC=~oEF5o0j4FoX=2QA zVUNpn0+)n$Z@?rWZg}#D9rljV3&1F)*+dWd&cI6qEy_z9x`;w$5}$~* z6NoJ*H^0b@4XKn%^<`Yy*dUTChWr7#sI(F{^cLzpeAImuK8K|(A;_+d&2kWckc$1O z)F>#t@Z-z=_fd-#yipR-$~)Y3I&vM{_FSwf#`B$sW_1cV9Zmr z*`?JI`dN+jqM;>+lp$S9rm@vNGsQCDWu3Or%0~@PURjJ;g-fZ-(25j=WA&Azs!vbH zgAoOa(>u?aKb&f1$qbTOA&R9Js>p+W6#7oO6KC|k?dW%KtWhP~7tF9@YmnOHxD6NW zeMczcVT(Q4BDig}$OhTB#x?o4Bfa-5fBHO?H*tM*ny5F9woaABoN#51O$>;IKHN-z-Uu&Yup5Y{Fglh$4%dPM~c2cwb*56i{FL~4(j$}HQOv=?6i|c07vls zDRvj1siIKi45N4CZ$>(|YtS5WX#c#j8pa<$*QW1WcG!%a4sH}J!Nj^F^;yQurChSU zCQ_>;+!^^;%^{SHuDC@ve%{h)u6a-dXRLmXm68{Le=)=JA@{(>xjjMpp#J@h<6J|f zbL?`%k}Y~LgzdB$QAB<&H_Z3J>bND^Yd_B(UCJA@*9M-d9+<9!UfIRC!~GrPP+1s_ zM%=GtV@q#Dxuzm*&~6)fv(K2W&}2NT)dm@VkAVwbgI;@(JleGqr{=zPs_s53B}aO- z(9OW$MOAmxVl8gpO5Vpq^=o6l5rlzFrd7o79r;(*LidUgT)dI;s>ma|jwm0<#L8ez ziHl6JI(?#*e~tfM8#(mgYnkowKutk(Mxr+oVb=6jQIrhTWjNeKk=#&z8CU=aq*a#d zSq2*r|1dL=hh;8qGFD&dV{LKT59bbSJZAqL86@Z9xR9WS=^4 z9=Su`j`NSM5pdU;Uxvj$gxt6kSeC1DEA!I&2cCO*0E;f^7)gm?A62G1XXY46clk`= zi}yg*>?xc>_ER6WkH(ffLyh`~@ZBPh^S425##)On3!B!@&f7k@Lc>_Ax*d)w>gCH`S+;aHK^A0{5`a0KA_{(9ONC^U06#s! z)Ff`e^DyJXO7RM{ZqDY2}Gqm5(naXGo zUQobmw~#xu^pe2DC*lKyZG^hii_rqFD6A;^;pp8?A)u4`T%nDhB53X;SXTWO-M?5u zWK%fKemM1HLK)jsTCNQ06owuA&?p}WWB+*EOzOAToEYmPnv~#q1GsxP5`QNj_8Lah zGFr5cQn&CM4v|^}oAH19tvE%;pJ#sVDv(wbfwiEA3o^gaA3`$1EJhXDdw> z_~PB^e(Mz$>|9yl=cb>jo=Ys#&&j7>9<2`i_0AC8)wt zv9JO|mckFQ&?J)-d0(A-?RoEc!zN!GoF%3pXX5*wy-l<^bvSAnUikPu#QuG+c&u{^ ztxI|+KNoCl*< zZqssP@WDHm*`ha% zsNlJ7=SUp=Zpdigek;=IVdHPbI7BYJ248Vo+Od`5`s4?<@^jug1Y&ShlXtiD3+omj zWdCiOT|aVfH}x1oR4R33ul4yD$)j|zeQ1depGabRscg4p=4z-JNllnMC`MVXl~>(o zlutVa(%dd6T;$_wnHe8_nSGxmkbdfuo!k#fY$@j9}rY-)+|a(E`wHOKlH> zGiRjXDyWNvp@k zLm9srg!HqAc4t7iT;}yHOwST2Nk1pVmLYTNq|f|pRDx6|wm`~tvQd>25fYzWwB?jZ z6HBRVdznN{XQ@TJ671~59X~u&uY0now_-dP!-I~~m4|07f~S>=uD#K91-H}QjOPSi zQrQNx0H8n)pMHRM{4MU83w`7mkjp?D7>3JZGeNht478n^Y*kYf4v+2r7_Cgm6ZNxR`z$Lpa)D03&|s^1U}G6>!jr-l-_^?>(zEJPXm2>UrY-uO7V&&olUcCQ-K6h00aoE4@0 zr46rS6HlKB+i}WaP`1LJY)G!;IQ$%;QnA!Y&W5juwDa76_X@WWr4MueQd zD`y^|1;!9{^qTu9kZic{^>_3#7yCa@)n^M%^#u8|zgv%mN*kZ#Ni*ZtEJ&JKW*xTsOOr$ja zz{kQ$OszBX-JG-LIu1$0f`$~^?k(1#f`YUHR%mLcj{MdW>~KZ83pmb@%g9}EY^ml+ zKIxvdzw^x4T|3L@+TtqccJ=Z~l)vbzaJdd}mW>`c=!;^bJfWBPwIq9vA69l@m;N8husUQas96@WEQnKfg&!6%nn~ujxL5EGjof z=BX@JQdPj-81j?7@#Owo#!ets#uKJ6xtfM#%jubAc-b@Ro|3V;A4cUdL)$k;pvgKI z9}2sZku={!p#VavdZesH&3=_?wT;Q5!JcfNu1%u^PQ-+bDU)4U8QABOgT1Wc*;Uhf z>t^DiD;wbHcV*an$#K-iu(>qs=2m0c<~h>;>Ux5b4d zN&zWpeg(meIjyZ%6fu+NHsA;^lwBMi(ncN-tX|Y?y1<5oKT?$evf3c_8)PS4g8yRj z%EwpO(GSuAxv7CFcGliD5(vQE;>h_V5Srbw&~aF$R*iF3w!zM+OK7J`_CQa;ipBWG z6(2qF{;ksW6@wV78wZpxH8K0NX>rz%dW@Ohv6vvPeeLqs3buCzRQoZ(7y1 z!(!#pP*SyHew!UXEZz*a5fDkrY@B<~79;SY1&%yukSdw!jm^_yXO#ZvP^VkeeN&Nl zSvsCAP^y;UTxGnNAZ_L2gtEi_8{CI{#^d?9(qIa{Jb>ARgdhH95WHKI(P5z2Q)>C~ z6KHV_`oPC+S0Q87{H%1wu;Q3UXX+!uQsR&fc9dxw7)qAQJfL5KvSTK`U zk5%-SIcscavIWg5268?1H4qmM$gvv2I;g z>7X@`*rid6TV&ik!DU!(^_attsiCQr4&5n7HoMxL!ie{P&TtYg6E;D7Yd-F^IyFv+ zDW0*3&!htDDC5ESPoC(jl1~N7bF-@GZ#RB+wLWc$cfFGVb+DmyaNq7kX#?S;bo=}S zN~>-SAq(M-D7 zppE_x7kO&NJYC?`QSb_yXnG#EtgpOeE;%LdU7ozJrKgv`lz~yqZG18hl*RxouBHF; z&d1?R*53FozLKhug_ZlqM~N_IRjVOq0Fg>2%8zluENCKQ${Ux=J+afi^*j^JQXIIk zrT%1Q`|(13yVzpPvF!&D>eU9*$h=Q&V*?J^3+`)Xi_9GYsen;_^l5?q%B|&BkPl`S3Q;%8j zo0E`62)C9Tg}gO5V->WChdL4RqXzBem2D)G??UGid2 z&FkhztjyJ|<_aYatC*o@AIyar`Y)z#Hhc91f07V(iAGe!%(OD=w7jL)#kWIqCP;#8 zOe1w@zGr$Dw2jv-cqn-H`lug0D*$=Qu`=v3VeNRow$fe^Lsr=Pxzv$$=LB%6Wp&aA z?GNkSmYqdUv_UzN)6Qq3K2;yx0Mu2*ueHM8Y~;aoC#wo#pkUMUzsWiGubbU|(c*@L z3bH_k>)i+a*`?h)hJ;OvVgPcr%7sJypazCrBhd%|XXMcl=e4N7ClqZ1Kk9;2CsECe z$Tx*3HF`~p=bVC~SV5-+->GtgxV_e9hB)B%I!x%*A1yM}%kt}k16%p@3K2Blr62>> zlTec93g>=R3_up))U1YX$~vr>Pnx4YuvGwt!JM$F&LByd&}8O0=0 zD~vRzuJ=3gHCJHghc-$!m)N=RKO~r#Vt+NF09FCZB*NeG*YNPG$Jf)a?5w^YnjvG(Tcob4me(Q4)&UH zt!320^iq;3(Ec_zI6$PfdHk#7e2TPairV`q2!r=;dyU|MY~#UG2PS0}{N6oZy%QuB zo}|g_rXnm)A-jE$>G#ma51u{B+EJK}8x=2c{Vn#^7k@|X1YLbC;kS)-cS!Q-z>?hP z_}h|few*PGxZRwgniCn7I)O_8^O0^nS#w4nmY5aN?k!6hVFilxEg$DSZ^$LzF>B{i z#O%jyV1byK8g!SQ)LOpd==xn-<(Z7>)uLhsH^@Y3Ll2Z#YPOWagnihU{7@9tt!)~b zZFG7UP{tQy=6{Q>X+eZb+NHp%G%ANXTgr48h}lJIJ!#lCl_M7Jzx`}WFNLf02TZ=P z>jD3(vpzUlIS@;DQWz?mjn=DAXB!8WMdlHSuYH;|+$!@%@(jw_G`78O| zI~@j)no%|qdz;NDUS_W$(VW4)&uX>LyU2lQmc+XUN;thDYS0 zXez6?OW(3>0Thh#z;J2&(8CYkc1rk=A99MwZk$S;WaYc#K~xpLQQm9^#6#6B0HK+pl|NpMpq0Kmw{v4D=pJ z_*pMHNNpL{efXx_)m=l)BsUhH6EJ>i{kef?3-_dS*dAbejuxM$*%?+$0kpVjN8{dm4v{urR#=Nx?{O}RhLMLI9MKb$!Y)m|p5;q~A(&T!kIM+I5gy*3q z+B`XTTYPPXyq@S{EP1;uBl~dzf=LYK2&kD~Ptv;zm|u6rMVB)qWxtkS6rSt}vMbftUn1)DW__oxZN zz7bT3-WCBkT<>fmg<|ro$?K^AF%w0KQdmv0{b2+Nk==aB9O^((aV1km{7Gp}E=c6t zKNqM0GJ}of4w&VSmKgxL{;HzNgoViub4G@6F|Na&Kercljm9gT|5a6lZV>$KPC=p~ zs3^^I=GAQhdmLlaRrVvcQfbHC=yLw&+Ir_dP{kBa@@OIXtdR?xi8qq^5el#gBk95y z!XV564;1u^vWjV2DG6fJK6RY_oWq_;3HE_Yq?qg6H9v&Shf8QR#Odh5*zpf9^E_Y+Za@>VPl z6Z5%ClULxm<}E-WIwY;#h-`Lg=yDdmEnurrd*w)BD;=4|4=iIH*89*lI7`4NBI^7I5DH)?P{o87JP%al*Y z^wQTh0XGq)p6}grhaq0pe4sO{qz*f(Aus=TrKU51qEw z4n#^DwKP#H!?xxq5jtM)aZlaEvW(viL3J*{k1gOGF7+A+Bq3f{Ez@Cm`5vljZM1AH zVWdIdZp&U1ttc0LFzP=IR0%B)bDaG0fM@ifSy5*(p!7 z!b*rhbsAO7?%9IHo`hte4|EuR!yHg^spnE#1GuErdge(%Q_z4<#5i9WfoZ2KmE$^W z;IzP1%eFU4dIM-o9g$2hwQe?4{_7OtS$9f{or5T8>Y_p?rcfLM3?)fJ{e zQRU;d$)ZI)t;Bu2-!8pG%$k5g1fRF1u8e6!a$NYHhuzQi6?`B_B30)8MU;=`|EbpD8gCte&zL81-yk6!eb)>4zpq{u~S%o%{#532q^)R zoTm_|tMUB%dG#InVGhONjilv8s@_XauV_DeEB@IUp;S~FL>V|vasj6oi5Obs-zJ%4vUvGYG2ISVxlEgNhzQP;{Yb*rc z$HT~Rg)kZK%GylR6Oc#e_xfE6Rqq(8A_Dst<;jCJgGH0#jJAatesQPXJCK&6;($$k zo;vvPud%DS9bEpMhqb@=_bk;@6|RkzKmbR72$Wdz*j}O!K$9NQMChQu`ZX@9Sc<1( z-}Azsqk;)!9fJ8DtKbM^D1;-m+c&81Eo;1Qj!S&Wk#7xKB=K-P)-sjo@Tk%$SsBc< z18F7#WArox&a$@9v%P%Jqbrv&x*RR@Gj$7e`8PyUREXOv!oS#(=f822ft;!%<9a6Z zjq+37_nDN%9%-pk>yEYBg9`SnKfqL8A7z!#)&abE1yh7K^hfB9Xpigy{pHkx*`sbl%krxjZE8whJ#pru&6U@RUhkwQcSYf~4(gYz>B(UgvY*$LX)Nvon;HzLXP$LH=9k-D;Bz4 zE`YF*^I}`eP_y_xMRF5$`0>|{!`*6>;jpr~jYA%azkOfuJP82OGHfO1IWbA(nHBj{5;q!6{e^B$CZuL$XOA`K zWlUU35k<6G!e3G_nXMvy4`MtBgBMEJ-Ss<1zn<7Rcp45u0JQ{7}% zBrT7d5Q4GgJHy^3V)L4l%Wkh=M+`t+=w-pHaG*h1`q1_cd=DTtxTDTqe#@!z?4A4s z%?oAxFmszXYX(HkL;XHRb)G`$01|WaNzMS#ndIur(Wo9z**6~lkq!I0E4a?WrQ?k_ zAY@~w8wqFlir)LcS2W1%W||B#Y?5wiE9gbNV+I67a3j_dcnSou``*+()j z^7uaNQ}2_j`q7K4(?+Mc2eRH8H5oSfa88OpR;(JMF}`J;#{B5Rj3TKPIW2r%wJobF zCaOU{=WG63hELyhYnxCgUZrHz zb!rtA$?g;?%*;Oi^y{MONvB8GC8|Ph*k0RP={%2O_#usYuw_r;G3%ua8}+|Cx^VJ) za0~Q!_z-o{-$+h31-O;hbejnUp`O2FOWNpR-0YCt*(j&fm z6Z%>zs>}X(o-393u@>p(GF&)Eg&Ha&d$p`eKed%|8+*DmDR+xwHVFgoC;|dTU>hyg zpjU=L#$a0;K=r1txxrJs*vY`PP6BgHY=BT|{bnRd%e#(>Q(V)%yh>|_Nwg&F_u^>G zm{Xos#@#_d?vtb-M!uQNdCC*FG1vE%&4kk!prn|N-u}4g+E~PcE?sfU;pw@oHf{0l z@L{c6nw%`6QoxP#9T*Vo%ipOtSbX3JaEn+Kv0st8)uKlSL*mAK7+33#3%(gq_tDSg zj(}Y1=RUq1!u(0#cSM1GEbNRD<$Wtczt-^MZB@U!9cda?5WwYwVp-o>cvE}y%~P{_ z;2pOAV@KvPbP7X}hoHV_k0M8MoecxD5p_5zyj%ya?;r9D7st$xn9{2LhlzO82H+oJ z)rjYRiu-_K$Ia6qfmZ=B+PJZVTV~);*((KAPd|wrgmyRkdot(e$!B|yM8Nno6{Y$C zo?)!9rLC5A8Z!rO_5RTwEWb}H>8uyQp)>M1)0)b6Sd0EHAWMbgY9$l5vB2EH#iy7@)0p!$Q% z-%NJDDxs1g${gbCm&NsdB%(Mbm6_Ilhoi*o1_q! zooZTcfXhL(v%87IpMX$wCuIM7IXCTowm5&U=yuk&0$dm?TVwnck?F}>ZihH4)f^7O z>-AW+h!a)>w+I278Fb+Ot(_uRkUj@>w+6IeiW~wSn4CxI-lqv#q1``8%GPQI^B!GWb}*V7$BD-m9rA)z($l>pf` z86ai>HT+fM-4haz4dXH@l2bPPBnrAg=e63b0pO;s-y2I6OFJ9PPz@vf$#;C$E@p9z zHTJUvMEo2pJw6jxWL9wPSoqP^%I`meL{u)&3v6p-3Z}2!05@zDe#zHL7Tb)yV<*fF zXfYmEPM?c9$Xd&2zlb(-S!yjLn)uvub?u+ z$XDGDm(*^k$i9>I%6ky69g!e1eGeeuiamRp>}EjS2PLorT?0q!>(uj_xO)E1w|rNw z;!IZF_Og1!_>Ubd#sa7!c#4nynZiZ4-4S}x-+WB)U#}s6)qLyBcF?Su$_@H|-0_^s z!TsmY`6+k*m%nC7oB>iwZ2e*#uYa0~|L|AaGg-Ln|K+y}Ts{%kcr(jL6 z^D1b`zq36=3p_6}T>kA1e?2H!Mkj+Vq$5uI^9uhD z2VLcqBIZB5^{3Zl`wMII^GlxIwfvcU`yc)%Ro+Rh*1$bQ_P4*_n$uPPxt-u&6DAOS$qsL-G%4q?fQ`jQl_^8QS&=SD#j?|859v}>iM z56I|iQR$?KL9)l9_F_t8U3~kT3?Mi34pcnsR%;v|3`mztF7_mf+F!2J)d1i}9{G-C z<}0_@T#^Bm$|OM6>9e`7g-sD4387A+I{VXf2hU%c4SM>ESOrgTd0*X{_j~8b z!$8B2=2p^>Pg&u8pRYwPn%_=88|fp{>Lp8XuJXt8;SYOoN!S9$hfXyHC@nNS)*CY) zayGQ@HAZx1RiSv)*^SurENgNLlBwJUJVgGl9QWZEIG=oSU$fZw?Vc-^DyQ-Phpcz; zXS)CY$4j9IU6mv`TyGr_MaUe+rRd<8^O@v)7%`{WRuor7Dme}#IkP#=*^+XeInQYh zISj*`XJ+<$_5OXox8Lv6=N~ZJ>-Bs*o{#(Een>ami}UF9g_txwQB0a48H)QP5?EE! zDQ-8Sp9@N%Tt(xQ6fdqi77qLRn%~UuK%jRU8P5BD6~05CzSQuD*~l%&t=-=>-$W_aFKwxfs4r|Ng_D|U5nGG@1ImC{p6=%B8Z@I`&s zfvBonnw{u?)sekn0B4vTxnoMhXj_ zR24FqvC1NxeFDO2?b|eZsJW@=nU|~B@YV4du2V9DO%a;F^4uwdkTpFdg50vN{ zRyehA1<*ySQvg;T@X@XQe;hw=7oc}RT&~5C|6kLq|L+`R-aYGv8;>MbHJ=%OT1ax08`!CIBWJ<4wr{&GO*r&x=#k#}r=(>Z5p1wb zE3j@HR@!UK;C*4sU{=1eGnPEcNtCW_CAmUJ|fp;fL ztXs$Kj4nBHEDpSqaVV%;g;o?77)8L=utR|s%&3UBN=Kk|R`pMfzkf`)Y0z)L73_@k5)()NQX+H5E5@$$Q43QZh# z35h+7j&S0h}evrnUzhBrxKSLyPTTOV9V{^qQ_@%4*mo{rs zZY_fQMo-Sx@78wtK**io@-u;UO;61%T%XOBTsx_HQMkaoI>GqZl`D*$`e1tdnHcm3mcV`eJm+!H1Ab&1Vd?Z>2&oCaOZXu8sYYtzSt^I1;v#j~G%UrAnC{%Dht=<)Y-= zG{f4H2a7DGyhm!9yE7D}Ni(#D#|F-j#y43mMZ>@K>9vVY9DlZ~`@fr+@%0M6Kl=&J z|79VL8*it&=6X@t<7r07wo?THzTcPunZ0w#Uhk!Bo|;FY@<>my<=u``p$Da}Y?Uw$ zKCXv*i5_)c;tI}lHYc06tV>-eXUUt(aCTcYR-X6jDJdhzrMWC(oy6ltf2Uwh*upO#zQb#WiYp;lw+0+*J{O|@s0?U`s{ z_V`_si^qy8R;@oAw6gZ!!Q!n~$DrLW4p}^(%u0RZbM+&q8B?t+Pk??7ukc>#cSLvy zkGSDk`f(Ys@lD5yT1G21Ky>$o+QxgqH-0y) z^V=&JE{$bE_55J| zi~soG8ix?9XXsDQ?_PNh9t@F58{2L87K5PGtzVA%>$)OGg$~|r`^Hj%J&Vg%Xs1<{ z(>MODgJ!I-7;G=Ac&l+@}ccpoTTmr`2XfxRBQIA*1m(ujcEM&%AfE~ z;1E&rzBQ0%s1T>V`N66zyjC>|w~Fi9vMe+!as}#Y3Prvz<#!{7Qil}gI}_gZJW{dG z)e{B+f$U5GkIv6sKhm>USfi|eCWf3#EU*Y5n(eS6vDk13M2HQ;67G&div~SCVP`Rk z8->2RZ{-X`nOP11Nknx2BX?!2^FFl8v{ zrl?!M4N`$^MOkA{VP2ZUB?T$-BGd-srU@>sPvw2QlqtreaL7mSxL#X_qzH8}b+{`1 zVWDM7M&Du5D?qo`Tidgp%qlal;0u*9FIm+++XTfH9mK-$uk@38SSo+hOeJSBnWkNr zQ5hXO7THcPp$ph>Am;s9RHNS`z_T(}I^Uj8`8@H!I2$A8(KKG>8)C!KB^ganuX{eh z>eDmVSkC(bzCrQn0)##5Cn;Z_=h(iM>eHW7#X#k6#{Zf?76jdcHmu1xkn*f$hXT{z z-EFh0b(PGPFUkKT9Z*CvtW!w`4-M=aC<}g7iw6St6d9`)M*Iuaj^`h!VKdgymw z>Q|91-6&OMkn~cB7Q*Y?oO0xDg+V&#A^qW5FA~N_3UDNOjwly?4V4)qh3(R_5ZBJ% z@Asdh*Y^`iO!jtSd&oai}R=wbk3m=4tG zk2~%HH!(XRV{0KtsPatlg^ME?*6yy^c4JJ~`C`)>*Lp*LyKr>Qb>t%PO|F3BMOIEM z;Eba@K*;O-_#PxLYOML3GAn)uY6ImnH`APbrNzG8?hfO3kMgnKEGVEN*MEwDD3f&=mM@OWNZ{N{}N2 z{8-3fd2`)rn4S07Zp}9Wb0fWopaV;@Geq{p#)VVger+5edDKQPA$p2bs14AZ6uJ%4 zq~1z*VD_MTqOv(|SE=Yc@p;S6`0g!O#zusQ*q)czqvZGzL)%r|ks zWf*k)Cv(1C=d*X`Rl(&{e>2 zzJ73h9y7WiE8of1b+z2CL{3m!CNSWj?I2Oq+BdxorWpX zLpAo`m>cc?y0pdK#rU` z&wDLZe5&DlaV7o!ouvloN#s1$1Eb!y zc#!2|x?6=^oV+4xWhElEs!@>l8jABQ*J$~+mgGCXN0fbDIdM_n0ak-!|A+vj6#8gc zM-SW(^l=HkYGh&HgP$@xss4b;+)8Q+PF-qYyLl>-hqi%VM=oo2lIqRO6@g6vuZ{wo zjc#PVi2w3{4Yrq1aZ5ZUB_VO0=ifJ9BUB>7-l|aig2P(tnJjf;T8{#yIP*f!zt>Mh zd{Q`bnUWT;N2+!$s&>Pr2CX$G&nk zg@nJVC$*%1+&(4jhOHtCl2yZcEUM6QOk!!LIo>9A;Bx=a zrGbJ9n}Zo9Efrv+>=jJUorq9fo7%1#xa%i`(`2F%F_(o1{6yY1Bsg2p^qOY{e1w`U5So#{;eef`?n0OQG2oK50e% zagxmKv)A4$gZbOZsJt~c<=F1tqhvWYy_NwTF$zB6MAAKEy-;CwSCDHrM7alF9^}0Q zr;2lJ3-B}MOiJcI>T*-8j!v=Z*yxE(GeALnO&obSzi4&m?#8q1StB>@&>{loE^Kn~ zqa-2!V@qTmVlD~=QLOTEOMY{IwB+p4zFIB?kwKuVb9I_<>YXfNEc-y&QCKGWW3s6PC%Mzd(XNu;}h~ zNzr0s!-EAjL}(^y7oc-^0$w?9832PY=5Y0I+wX0M{k+7KcPmx4s@Vp98i9?7e!Aq= z_~*T;neRTg-v7_WYjo!~lRK4?p8Y44TVj=CyxK=#Os~5K!2sx-0O^ObOYsTL+iIYE zs5zIRbrVn=gFOKqwQ#kq)*O$_0~sDQTJOdKlX?Tut#a0}(31V2 zV&T{_p)wkIWmf8Hijg_%v0NPI)94~ojP1`#^%cK?Vusej8(ncF8=N=)`6OAhF;?Fs z_vz!j^164X+af#H<{!{4P>E(?Hg^B+iO$W{>&eCQZ>)r0vJTdbMxEno z7b+yCJLIHoYTtW=?1jo&22EFx2^di;(#!G$sm#JkLS|U89f^BjA1ZintcPnz07>By zdWB_l2CYPvhO2``d+uRaeFsm179X1`S>rJg!by6f(}kY)v%8Iw#}*YGx&(Wx27^u+ zjbfjrIHKRuk`kaMKKr}l4(sK7n`$FNbas3-NByJm>9rpcUYxJQ{5M3D+^?ROSR)x9 z32%Em<^QtP69yJJlIFSb@(_VO2zzd<`^p)!=7xYX%WGnKLsfK}$Xq@?w_^ED^9hN@ zaqy|yu@goUPcMpLlDr!_J|+osVy~R%{HMr7i-bbn0;?m-N6US!jP8?OzgMvevPH(s z6qDD|u8zQ}*Hv~!JVs~5gkG)WDGn-*3@ZLD&T_}Q@xj!6 z)sZX8urVol4H!kahg^!`I7i7{@^{hh$~UgCibjTst> z$JhZ8=+!9DRRaC!FGN-k8Y9S=#bj-duR}lau{1m{m~9_CLH*P_*r3`k2a=Q4)LxTJ z$d9T7uBF=&X(hxJv&b6ogl9m<+em#Vd^LQ(B=ciL0&`|%S} z*FE7c?PjnD%dwy!B&^iAhg95K4L8spO&IazlwYg^HTtO==TT2GQ{@P8^>N1Y_Ba+wd_eb{tUc|9nxR=vfi^x=jz4I0V>m#YbPJiUK_eG6P;H#;+0cK zl{jm^Oe20ufuOJ3e=+T!oy3N$Ddb023o2%iyksYajV%y!n2L3^^m;BISlzeHKDh5m zxknzh^cavwflTsxE%j8H3rn6UY%{PpTEOpM{1a>;<#Op6xD8BjEht`I4%z97np_j( ztDd0^MB!$2Yi852*|4R2X=bW8df9vMMo&`1Boe{;k;TylMP9LI^W@S(I&3hJ`oBO3 z>+~Uz?KyVw5I|%7!p~oo8ssk;hJ#qqEc~@uJH>TM0Pjpto{o&e1onh`--HkZZ(TWstYY=TID_wRe&4Gd{Y_){k3ypPi16kQzvnJDy% zOcq=emEG6K&0H?AsZRBGZhIw^5}}r;6DxvxC)YS(&$L1ZU&N+=oI!jhG)}dRs$Oqh zb#(tH${MfdN^!r*Q}1a5jFJK+PE%=5@ervawxSLAy#tf#;=rY3mzpnNqRSauY}4+3 zyOIcCqPJ~Qr{|#%*goxNvNn<5coi2}1Ny3)5OEh>zDJ!}>)1ViCuIq?KB`VsOjxx! z8Q%8#lBjoUxWnfHhqhVO946ypMlb8$K&@Bxx=iqU&moM@wh7i=oirn9+bj-y%_B(Q zQzl;|G3<8&8w(@b0ri$=u3=YgOGu4f>mT^~E*t>f>8yb6zy92A8C~bNX)l~u7)j!L~`@p@ft3^T{2#In{22y>XJ~u)`}tkMxTojw+0^o>OBDc0A}k{ zISuCEb+2@e<%Cg;dC8dUH_en$3K1oAY3gT^-CxIv!~=K~qr=y$AKIybmJ zA4qi8vDy;6cN=-AmXz*SEj@3P6-j7XQ%IGfF4MH_<-L*&s;sIEl?dMF{ap}oQk}jf z(_Z3fUnLA(`po>Q_Bfjkqdb%_|AsnX$MYc>2K1vj|G%0l)Z=*REVzio|)MVxM*>U+`n|p4hQ(aSY)nd zxv4L|Z**ev+WM{F2wrw)c{)Lx<-z18&nWrAjoZ}!>jl6ecY&QUo>Zq~v;8t1^NzQY z;88#0!c)4X17H9?jfY5~#cSc?Plk z;#&9jHx47yGp({8OoUqmEz?k6GQUN>XI9wUKU%}{$U!3@pYI&u?s^s{My6d_I!_Q`eN5>GCyEZD^VUI~(O`gtgXgYU zW;zC0QY6#URH;g$;m< zoS3*+*~lh`jJty>>m=kac{^$}T7>sO8jCvq=3PLV`FexAn&H8wxU3}Nb*g@Bd4TkK zWjFvR<%e&4rbQ@y<|A_xi(1}-P82&F)^{lt&zf^BeV5V)*`Gg7G(22z&>==X{rNcg z6pSr>tU5yw#65Frqw^Upl2XOSk8kBFyAOImKfzEhFn!tBWlF^B1T%2iVoFZT1ZYi> z_u2)Q0}JEmlfbcX94})XdM5b<5hsEu`04J?J`6hA;Vt#m=aIut9^hn}n6I0vVr8IK zi#3M-L6J~Qz~~4|Ls9ME0Qe~=kV1G%yF4?zU*YhDGX~n0-_7tbU?&N)8R~CP{^+x{ zwTI!yn&P!hU6Bsg)J%8btQAags`8j6O!ONsvBwzoDW6*FIlJ7SSt=wfz-n6hzuIWOEDLLQXsrchxpMWBf62{b*TDix!W$VWs{7h> z*h^e39)9-4Zr914P9YFH8>%2;jA7Air^8C**)PFDD?fi)<7Ip67MKT)|TM$ONG z_f`Cp<3g|3)9DhE&2O4Hut@O&ZN-4_lTJp8|luJMVC9aYaW4f35@ zj@n0KOxTRffJ_QC5&D?Snx1-=P019!9y=)+s!nf8nK-ncBR#$ZsDzlSRZk`+ zphT9eNnwS{oaA><yJruAzS|1TRl00t!WmxE#+RPaxWJl~$n?0vpHqEELJ%Z<$=x zzatD?9*bGKR_i?)imG<*e>Ofx)8kO89$JLykE@vsb7)7F#dwZmQ5 z3}Ai>1V0`GJ=MHZn{isUK($fhi{lD+|ySBX-RSIcB6IR4{{~2s}%`22Vei$C@ zmG_!YY5nLnVBap!q#<9Rut%av_HQ_aJX%Z9(IYEc6?Q@QIql|h7X{WdBByO24X)>s zvE{=-9LZn^hWFRq20QMg8}`CN(6l8f5DqYd8|Hj8S54>_^s3ABud49vFx~1x332Q9 z?9c00JYRDcxiCiJ^xy<0ljTalKd;^Ec|VCwydFXj;#85&uk@u3*q#q_5sBr|G?%Cs zc-vpc^S#J4FM;p++5!g;9LAG2Oq3NlUHm0WUNG+o&dpUVI3?XjX<1b1o1#BCMcV;- zbekvKv3dHjb9=edqb_&>e_$k8 zi|o3FWIEcOf6i&+YpF8MImI2DbGO`gDG((L%dmQ?dQ#?sP}jc&W`Yy;RS28lL+N49 z#L6mD;>U~b!#fMp*1{WW39`L*Tgq6wU-B2kLq}mBN8g%Vv%29E*~+rvICr+!4VjPC=jb}+tQ;l!uG+DnY) zs$HL>v^q~k?+^Pxv#ayx94d;B>KyxN@(YyEEkbUSVYA!@<`-yWctGz4GWJv^sZQHL zowQi@sA`W2wsoL4a;TXN%L1ZPv0Ho&+*+m0-#IRBP&DbU1We73l=j5;)PtVALYwjQ zo4qK1tBTKJp&47!Yh%7%$7q5_Qk_V#ouy4-%^|_*BYZzZ6Cystg~{~9X^^#I@Ml5< z^5yECfW~_C=UDZFAWpo&t;*G95E*x)C_XhJ^DLIUK=utNTC@VqFpdD3%E?1M#px1lluFc26sTocS{t)8ItFJnW86guhu?3R- zM|B;9GZK7kkCtvE``kAk)X>@`nKBfoKCyz z!M2X&8g7IBPlM5RVO+0O^%pBb2FC8=6n;jorBt$wEv~{1YP_i_qOO$!%OjaYd9v5C zQTF@$VO_5t`O?7EPd>4SyaIH3g>}#~CQY#G`HXRTTxto*d~|x%(l4}BBH&(+#yX;g z6=P1(5`@O|ZJGJ<@l)p~FJ)0u*l9iPeJz}$MHmF7kEYS&j#|F(^$0ZmG2k{Vy7ST@ zjh2NGnL2r&nDX3AWQ;n`MZ#oMpT!@*N@I=1$?jnXK9$sNL4>xZb%xuGL;GxHfu%5d zy7G2-Y@PDZ$>)7vu@f}Ff`e`8cWU#duc~rYspvrCuztyq8)x%2tfCsKg8?^R{I z&}$NJ9Hi&eCyU;SPIG3u>p<%szva>%=HnFY6ndOyBZ*-BT%85{NC?zj*k=%Tk+&s& zvSIr>GSc9?HkUxT)q;Q@WV+C}BDZLkZSkS4pUl-EosE~-IWG^tX4)5wwNgMTSF`5% zvrlbz+Gk*nguzJzbg;u!gA0((5xwR8wIbT*5Q`MtX$+rvRLrsq~?#}+Cu&GUv`|!6HbE)Bg80shdnuCj~LAYDw zEL>PA@Lwh(y#GdCT^0y0mkb8`^@d3q^Ebuj&urjY>feGMsL|1Rgw}4@{q%Lg2go9p z@(a(Q!cqPeQQN%N>8io5UOJ+t;hOmKhwE@;cJ=j3gI{vGQqew~u79u>&Uw7t3%)1h z!NV{12My-v@t|wHwU3np*kJJ!h{FxG*d01+mhFAM&NApbP=%8b;%+XHUV}9cd*=Xu z=}R%pkHAbfQVcI!c^A7Xy#((QZwH67?FQ)C0uh?W@!mf-=UrQ(EU!LqY$YcFQyN>xhV?Aq$(*mzX8&hwlq*gVSCs6kbIYG86 z!Ou>Q4CRwK{l`5gnyOL5{<5eIlZkS&ez!2g9w)`~g`V>d!IHwS&z+$(?T}J<_8rGf z!L;P@FFmKSnGdfSB#7VRpue`Yto`ciuI|PzHd7UcOTXy-pOFG&)(%!7o?2Wp^ z8EU@dKfV!^vm{bw&yH~ta*;zVp)X_vRYp}U^eqqV^3gpiu0{jW2&;W#IQ^2aA9p4& zP3(_NZwaM`Nsbe7-j=te9IG%{GvX5Hs{TeeS zwOlzzOn^L2Ke1iBe%~th>|=Wj{)vk;H=)=;L*W8la=u9U_BFEV?M=!LSS!=hLqzJ9 zbu&SQ_0`AuFFyV9bhB{HGKb=7Q@v`)Q)6QsV%4Vbe!A0VV;h&rk>aVmb0^j!OLlPa zX>WU2fd4VxUsG!bH7xVIXkYotWn6ZTW>bY;$mn8IHCO!dtA%&?M3YALL71^NoB0m- znvoQ^9n=p1+H=q`BIaeyBT~|om{Spy7Qwk0^lX?-v>d{A{1i8lInU$G-YI$Pt()cL z-3$1McgS@SjnI*Y;rl`6-JSa}JLq{tN)$CwKR7bpp0v#vzRp@AGEsbr5)k7%`Rq_*M(1t>LHis;0Wm97~`8 zW|hm*nd-JYo0iK%kZGkH$57xoR+k(JYMj>tP?AmA6J-6lEo6&=s^BY>@##i6MX#aF z?0V5CJQcBLUwq6pALbLMeMdaqr<&+`+RC9pL1TD)K87^jWu2?d)Y|7+VXQ7UrO<*A%mq3N@dENw0T?AUiW?Va_gvwf|LA!NI#I~ zn%AG{)KbGpHCq4nQXiFaRjDHU3bS*+ABQPFWPmZz7Vc@n#ek3vz%71%m92%I+c#}o z1kRt5x*T)8!g0Q{3|uZ}dkgI3;r(RX2Jf3*;7-RH#~1S-`fS2(UT#!D{P;vtEg-ot-QDlZ#Y+cctJzFMEuA7M3rKGQV>#m*7O@ zzPx>J=d-WJG=_d6m_*UWxYHdy@2GTga!5}*SdkNE!VMD=aM_xsqh&r7U2nztU+uh1 zsw17dBW4zeRlJ>4D-oQI`T=`R?k_Mdn)jT{asw}v$9RFGMr9~(UalA1!Ff(5w|jQJ zz-*msfGskWNWrUZ|N!CEu`(I@0@=n3!?&4TsNA)v^j5pcwEKm2>QOns^8BczzSb>1>S`6-7G&|>raeKEG z>&eH@TR69S$ZH;Rp}_XqE(|q!^<(jM$?&S~_mWzoOe?civG~r^`+ZEgxSP}@l>9E= z^+WpQA$s~3rG?&V_eGMFufYsok?CvtzA{ZgHsvMp-WHTIO(GS&N1qIsw&JM%JD_2dC zRw*%j&*i-EaY;8snEW*AeDFvwZndkS)(UU37kW`P8NH+8_hLtHMK7~^XJ%`bWLM!@ zC9ZEnd7G*A{|ov2?__t_3y>MvS%%`O|0@fAhNl|<6NQzPq$OzW*>N~w%G2hDCM!il zf~QZ*LYIFedH_tL(PMKhP-(NyPWvKFRt6;lGIr?TvC>*aA2Vjxcn1(Col#U> zQgg{S>3z}Jf2B{0VT}X$kwTgd*E)w%p9IL}DOpoIPC z4!&evDYK!YS(~9^xq!gl?K2dK< z^-2wuJG`;{_RxTOnTwv=A5^8YsvkXxUAW<{4s>w{uThX&!j4KHhmq0K+TN=8&f9lX zHsuG(+sFl`HwQtg@##~q+%kd+pSUJ2rma<#qU2v(2}igB0H=(mHn%X8Hf zo!rjR%Q>Z7=kKx)lHbP#Tw0i!eCH__?m*cIP26UPS2dqoSRz~qlYTU!@_J~~^a_|V z3AqJa{29C1|tjKey>MIIsXp*r%LpIhtx;b7AQNHr% z^DSYed~n%4=yBupAIjG+W7_Wg&)%rnCkTir7BgV)|CdL$EiVu+G#+zNMa>d2Ts%cs zMb-}J)79u|TZ`HPTwQm{pE8~Ye0y2;&8P8Dy>L-rdS81l*XU}C0&z|FI8nOYalf)a zNBD?xu>;MXf>@fjsOt`&*{!_ka(P>LwWaGI1dxTY+#j|4mKYfv<@rLq;g|V5!E&8l zXeMpqX_4@j@*iiX&e#Pb|CYBZO0)YPA4bkrdcIyBjhs?McI~_5z9M)ReH-y-9Tr-R zzU8AN-rb+GnmhO!LWC6bkztg|ZXcXT^;++i`uJD%{?p|>sb$Ro}brY80J zU+5jMr`4dE3tN4&+|vB1%O#Rh;(^jPuDKpX8)Zx&gv)4w8h9@0=iQ2|&7q6ee9BE3 z%MX+8-)wgul{}F_s={@;!W}@)9|*2ZgTKiXmjb_w_BA)90GNGQkL(*CAvt?_fAg0H zR02nRJ?Xn|M?~6IU3|iF@PLpS~!a$$pjJ2f^C)Z$MIxssqG|6XmvUO(s1a~(x6k$1KZ_~lC*fr8) z*zt%_SZ46P0|YV4Z$g%vt%^K+inqDq`Y(~dN~-j)|HkHjA{$*@{<&*{?Wej)qGYX= ztt%+o>dv}I{RF|HRMp+>$Vs)U#}~#Y2hh5lEVZq+6x7UZ3;3A^D}dN^Gad8|y7^z) z%41_-h25bapfXG#))LERI4mtcOeyj>1_yYTOT@XXjujK_TtwNS?bGe>jVWn2VrPbm z#`D+zq}2v4^^*}6C1T4ljUgLf{+Xy>)VB+sCE%Rz6>mk9*RYjB%li-|)l(fiqO7+? zm^b#f1p-<|cYtk|$Ct^%QZ(zZIH35B<%p03Dsvu@K8Yl7=*qFDE2rc;mA`q^<)Tphsrzv$A273zGOWQlzW#3Ceu zF6^D@d0|l(=uzR)bspc&2mJ4X%67eHr77=k@r|d`I66AbO2ku^EVbf{T?i2yN_*X0 zz2iq7aL%pqy6pZN98+#&0eOlQ7Fo3Fa{Xd)BgS!7FhHl~NEm0bbmraL$I3V|TT;SJ zHZTL5KQhN^5W&fuvtZs_#V0xT+qJPppMSlIcq+J_%d*(r&i~>)rIC#s+{_Q zb>%cqh(U4ExCiOuuYURjPOuxa8}D8*fkQoF%_~G-M84-&+YQ?S;Gx!%+|2#`=nPS1 zxrCEw&YEW_BLPbO>89nv(*I6ye=0isOQ>;%Lj{WM(1Y+=-ew97@1CI33-05?A*Qaec6eP z_H224kvSA{>+ys^WVbTz#=G#lnQCSBPI^gLqrZV_N@xA(S%*?xU1AK|4!il_al;~9 zUpN-2uW$v*v&Mg*_NUvinj1i=-v1M{moTd2Y}zYEclFD@HZf2oUsp(zt8jJUeEQpV z3lTK2{@KJ(S!layK4|QxTas7uL59sqzqArB7`sDlXjw=Xl?$ z&}{Hqm)t6?G;UFPlEetCXMNj6Qy+(X_fPt1knMI@cX!Z1>0gSu*4euY`CVYYqrDx& zaj6bv=39#$S5j zR+b)3BO5kgpnRN&TbC*^gh?dZRylg#%9#3C09Nx*AV8iI?ofkl<|?#!6OKBJvJ-@D zU1omBP51?~O*FIQ66DK4NB2UPE-uWcKAs5Th4C%jZMmQRAa$(gid0w+gL%dFn!hcP z7IU6VUI7kEEx!dYUfy~Gj>m_7gXb1Jy*sTjkue5Z+{3?etM#vIl4pdgCFgWm_fV=tVfB8+?U{HxQhTLolto!A%zY`{rO>vM%QbboU2eb#QhN80sI6aZ!(I2D7hwg`hzqx22%n$Zl37By zOrq*WHt$o%hyY2pZAT|>67N?G-+K{>J>+ldDCa7syOk}vwOm!s4 z^cHNd9%j@R_Y7g%2Ew(;k1+3dL;*|307&Yajvr4Mus77KQ57m%7A!Wd?2Eu%o zL6KyYyo3z>QKlb)#se~L33`f6a~#N9@7~h2KXf|Xom}J4dA?B7FhQG$=)UtC&e8C- zxMe1C$rWTr&oSl-Q3Gf)2ZQFQHS_vTb| z%`%U?*@rxk>-A|9EtDNZ?8El{pvW21PIHX2bs*d3^r-@6sY?MvZ4XHUAXQvz1RQF( zsPW)bh*|o?c}_WOB}CY$PlP{^cwM#pea^zmbld4t4lT1>_O^qvUK{(|#Hy%g>A4Bg?ZY_WhdVH?U>aCb(DFv$i-q}8 zwk&K)<6U9x{0w{Pu*V(IuzL4-B0))f`Rh~Z1nlIGOCc*zOkIW-HR&hE*tR(*`ihO{ z>#?*A2tCI1K4+wqS0e|-nH02^ao=pYDv0@fy#uM-*^SAx6||$)X@sYM*Uo}du`}IS zW!<#pQoql9rhv6G)sUoH4{mgq8q#R5!iRJQx4PL7Nn8pR=54W4O>v@eyr1xeSdTGA z>og;q)mQOlV8>z9abd)58pPy^Qjwf|?6Di z!ga>pkz8I|i8CRW7_R<@W zRTg$JBvA?@hyv7|n4%)(r`=+QL33fLqch)=$TpX^Yl~t3G*bYFCSY=E9yi^5&aTz@ zbO4!oMT~qe%$@ER-RFh_nJtAqnTFPAKX`g}zqsH3C(=Bj%4$hLuR>N?1iEY7cPNKW z5!A&0m=rk-g-(}|>gsM+Z06dd27Gi=-N<38!QKi1x=pm!9sEJK7-#HPr>_!dw~ipl z>@uVIi}^J&4f7WgDOHc}iF`EBqg)HKn3eYl*vCH)SAA%(S{VE63YMZ_1>;l!|E^Kb z(VJsIT4G(l`2e(M%MakJ*yMbgwg)*bAs{Z|`u0GqOR0Q=1CNyWX1`VL0G~s>W)sl6owwsH zT~8q65YzHOGw~__{5WlJsI(aXhIhJ6$5pAzE?W zqB~i=DJADcjk82)_B{zAn&veB!%O!_qGcWh_3{-NIw^;QJ-H`Cb;JOj9qII1)AJ zl=YclfVRx#3m?Cj?qGl%waEmY| zwWPj2OURG&?Is0%F&_@7tK{?5D2)e|2r3imCVwI3XptVQFi>!v{ga!U8}y2vj~xBH zzfyasib5Lvb`?D9;N`ahEfwS%5afmpQtG}ar|DevH?B_<(}kFjHg)!VagXF1Vv>H5 zP_jHO`y)r&PQ0ZKy>_(NA!BDDbNxAig!1H9*>a+vwa=xnh}i9NItk|(WWR=YoPYI~ z-L)2beD5V6)n_%ZcEs9Z#WmYuIh2!X!=(!u^Q{TSNWCc=yK6@|53eE23qDOAzqR*z zAQtpu@7F?ONEBQwoRT5D9GHpz@uizRGuuO?7(X3nq|4@0tjbx|Ab6&6+l_=VLVc~c zopNNx>I`UkQ8=p<1WmR1^FO!V5rmV1yhdPvHd<)jDzSXqw9LqJ!!(7?&#Ng&7k>z3$0%8SwV z@pesz?H(1~m_O={W(MacPRYdt>al$!Wy~z7_N<|X;z-ot-r+=rA?kPX9bd}m5tjI* zpdUu!Ws?0K*4VK@PBMz^xsTX>XHsbAjt82w}Gv)<>}k<{@+7{O3U15B5GI@7X22CoxoV^xyAWf28}UoZ0O zRS5lK)F$rs3&ABg7@p5s4+mpj*dt}e-pjA*CfH?pDNMMApj)8deU9&F`|QmFWvC~d z?x(ud5}$6Tvp++#b!vhw`Y8~&cFxOLjafYQamQ|mqn8#UU@RrUOJWeyLF&M0gz;fgLQb!wnJxVRxG6U`$ zZq*aYg~2};uB~jfCIpbHQfe}K3f_;q2?|`~i;ZE;$*na+$2D^^qUfrl48GJyCkCIG zL!h8O#rcX0MVPVAaS?8LW0}j(uB=_UV*0jjmsN2k%M3cUq>Jy7#eu`pXUb-E5xWOS@xe+q|^(-9W-AoL0rVtH`ry%J`d{q{4v~ z;Nis9FSO`%VB)LZT}6qb*IYmQki{bfGAwk@a?ZRzkVq5+H-I}@;Ud-<-l$nHzHOD( zYPR(&)z~eSb5=tUm^K}*-StgDxBoxvy?Hp)ZQnm0LJ=yYlIZFxB9t}jkfg;LlAQ`! zC;K{Mt5k{>OV+WJ-PreKY$4m&x51DYjIoVvtT_KOLzt zpYuFF@AJLCU$5D1qN~&Cx$XO;;RxZ~>h8jIQ?5_dzFEmbg_emqAM8)M!qT1ZY{swS zcppyL6&$yE##P_C;?=%I)~$e`d_uIwp%1%oAq&rSUgtOC)lTy>lw(IR)GnjjuqPga zop?J9YY}U$1=&c+jkHI8Bgcb7 z45{W`K{cAuVD{~p>*Djp}`7_i=bmS6(P-wWHLTts0^N^9bx(blW|% zY2o##^<5;oTd3lDBx!cE2*1(9LiRd6Jv+j?6LQP}{Wd5f2tgT|yAU-2acAYgO;y}1 z&EA1q-5NnGxp>IHcRPMZa2uGsYZ8HvJRmwESVj$->abiz#xM=VTPrCJ8G!dW@Lf@u?%N4SoK{BF)XFO*b*rW4Rh7-eGtkZ ztugWipy~{&y7Xxy7Y7F13gZJtA_a|4Zv;7;@(L?S^&{iVDTCGDvP`O^r!Hn-V3!_= zb_tsnk1S~4zoOW}^tmia#4|E;xO0B6yf#bw=>z`vrxIa&rrGZ=X{CH%qKlsm=)4}> zEuWE<_w{a=h@t((<&gy|b(v(h3W|MU>+7rEtpRgaimr~B;nv|}SS$4HJx!(&j zah)nDosIUl3hz2PpK|Zt5_?qgC01iEn`Y+?mD)Hw2D~|IZjzw(cX7eXu*4;rz;ka2 zLGQ)r7tf22Bs(AmhGe`64!*~reKG)ZWR`OW4@ONDdB$>xN&!=lb#i-0Si1~a)nxTa5T7r7`*)cLFt_w=xX0?r&>dGJTyU(k*$pJZQ+`b< zJjV6zAUcR)y}D0SWyAjAJNMq=m2FS9zWdVC?7hUxfY7GnZbZ6W;OxLn`P8)|z2pk> zGT6nb@4KVM6zPDu{WmniTC zRQGM)m4nx}$vJ?F^pbH(A;~1WB;Bd;jytT&tJ9g66T77tr#n|D{jE@*tjI}YI#P8>@l^SxLp+*G z)LNiK=^zfu$9=BpL4Wc&*q$Ar(3u>~DEt>Fy}sCllo;TGoQ8NSocnm&qk}*7 zH2y~>oX^hxVR%OWu27`IafxR2*7}LCNJo>{$I>4$Y{sgo_vqNu0POC(cSCvBc)!|L%9##kp0N9AGfqCH{q7;Nw01~l@tHm zs_AXu=Szd_vGODQ3zjT*5nuE=(n`WH4_jr`>rl>cHq zZ={mao}BCm=YRXf7yn7D|Gd}#yY8(MJT$QC!`A<`%s>AzNThD@+nRzzFKls{ zv;4=4{WV6Nf7JuOBdgxa-^>U8_Orj(3V3!mFTi=)zHGf8Fz(l%{^=oR!Y6>D5tf&l zKm9*D4TWuhRH=cuAh<6t@>gf~e^2pWf1CdbntK+%@&*CgmVdbBKY#8P0!(|%7JR<2 zA4BPa%54SMO3cylf5rzBtaQ=}f9pcI5U<6l&198TU z>3_6;1s)hU!Bq5zh<~=>pB}RQaBmXy`^S3Z|L_%l)&M8Cs^5M5eSU-{eH*UPr-}UjgW7;Oh9)S%Zzra*|L6ph`BVa z(p{l%@Yi=Qp@!Bis_jZin_}L>b#4?vWBH*(P!?DDEH#!<;ty0$Qow;zGaJtfny>D^ zGe?g%zljVb=lP9qy*rZpm#5&Xj&od9sAE0rF2*^RWN^aIV$CJM&TP`MN&| z$E^~-4}^x}iw(PP5|+nV7-q*#68>6*HJhm?e2H$gL?Oniy9%bw-gVRemWlDuJptt2 zn$KI@zrcpWk1a=Dk^5@s&?LX@(mSgA_xHyM9O79DI`NWhTPpXg&6fpzW=n~i^}pK{ zpYQ4D3H^efR1||z!l!(~;PKWQXv7hQGqHb-qB?)oe-QGDeqz%{`%_u}Ooy_m0Sy*B?TJhKPe7u-}Uz{0oip{Peq>IHUNBBGY_ z2Swp^pN$q71^$V&ywm%aUmrdYuFvvk=?8CU9p?Yh`wY|ob6`7wkJat~Sq}?0J*w7o z@z)kLsQshZA6Ni?e)tf`2_xPBes=9WInBEW()5qR~;Jyx3Zz zjVjfq&0YJ9P5aWryMK-x|GfM^maRa=02G2>so2|n3ZRDDIKlF5^up0FPx;ZWC9@^( z7uGi#*Y89M*@ICt_8mS>Uz0n}U$X~F*z~@MORg-emu@uj9(A=`{d6^j;zyNIe@un# z(g*Na+5xRS{Kwur=iEP@y6;*4{!v+v2kQGpu-xQ~)c&`je8&t$eh6C(7ys8{@+#KZ z#Z1a|(nocJ4FNS+bm8OnP+Ku>kbhqTJfEvQfhW$wejFpV^=Q!dq=)QWdz$dAx%p6r z`;&nVKwi)HNvQe#Xk1WLyDV>TN_%va_d?ZxZo0LMMCHm{W=eZ4J+83Dq$mrlKE-3X zm-uLYq^u{)post4i@eFEn1^3qm(8lhNJLrEpFMf`{~cxm3jxywIvcju=47;g|MQQi z1L;{L%G!%}qnTdrlE@p2a>t`;Ti`)XtUL1qU7hrDBu`KKrW{0!IX_M@?z{xXZ{EEA zMN|{FcbjUo*d@srzQS_eIG1}P#cc18B?s+>@-H~-j!9pIe{V1%3?q#zRO(^J!igN|Jj`$^OWC21K%bA7OEZ5XX^KCL=FZSvvKiWq1$sbh5( zGZ5A?g`rs~o*Kzs+qTU)MH@~M0d0{G)ul?T)r-G*EYCX`U{suO%Jx4!6&#)sgNy9S zEm5b{C)(9MTSiFz+`fTqL#uMv*@yCk0d(bN9pm)pvvLe>fra~EuYT64-bM)xXR$PH zztGgpfi*$gK4ySP;=^QgARTj?qZA`i_^3P!5M5EVXtAp*XI%j{3<_>EshfFU9Eu_# zrATd}lhcc{uTF_teu{CZbktb9X;4fFMN#CM+$8LW!zP_h{Nx(`S@Jd6_Q(eqtfC(6 z&yARIvu*AW(d`<6bYFZPGo6+YYvOV@()1n7HMg9D0!CyvgzNgy^d_tN6@aC66(9nL z!nRkh5^?Q}b2s1WWIgCQ<2;|20t;dW8t1;{WaC@Q)if>3ccZDVSTBA8BceC6Pe=)$ zKVKi)Q;;gP+NspeTrmdNFWO_EmFD-e9vst$NQ#D&$wxQ~$4VU^X+K1f+ho0sAiJB% zTXoxCl7E+B0nGO8l4^MmzXr4yLa}49E-T-r@j2BD(-%Tkr8kV6SG!bV=$KBI60dr9 zoFTp^T)yfyKiH5lUD%@`*_WxuGVQxQn`#O0JZlTN)9+_TOOfA*?tIqIfBXs)M9xxK z3>IQocN`ljv#jx>Qmk6Kwfz0-sMJavO|jjWoeR_2A{MKPkPtKycQP8<5Jr7x=$RW2 zeA}^c$J-%Q1L0r-n_@2j-N?A^D6I{4;Sv15ADWY=r{ix)9*jR zz?P{~)Q=oN-uPK#^PQ%4-<>+)o?tq4bSakm)kpg)MJ@HAa#a}1#=!$~fWDD#O{j7_ zz=*aJ>xhe+PKkjs_fvjMhPJOvwYK*S7_qhy&okVF&wb-<|EM85VfB>>N+BZJ1xvJUPqoqr#?YAHafy<=l)x#_GZ!$S3Hero`a1IlgyX*~UQz*KSr>yALM zA5jT8Yi~1vb7K56Rpfv;EC1&1^9h;d$}UH1mnaA7OlR>>J$?feK*fpFIArA*F(l`m6}2dD7&Q85eEkW_|h&Z1Ewoq0qs!|&3)N*O!w&*GjF_{weH^B%`4)BC=x*=;nB@4z` z1T|4`SP7+NwHnNYMc$TK_B-pnvs|jL79%c7z?6i>q`sK}q}C#UCp07`M`2NBv0T8x za*V@*f6+?j!n1;c*6So`_m0?WAHf_zbWZhFV~)-4 zqk=jxN7eXtl6t;Kb*KY?jj`!`{3;-fI-`mcORCwG#Ci!B=5FkfWs9?#=#eNd+l#s7 znJtid>!hbcx#oeb+uR++$SF{1TCMt0STr;SEnRN3t4Q`%hC1B3TxE9v0J_MH%(Fl? zc^n+S%Q=_J^*1;Lz$z3<(1-D98yH=(J*K$K)}}Uq*1?sQ0-)B$t|cUu z`<9PW6OmORI`QgJygd;~gjw3v{`tk?R?-G?J^Lr@xTKabPVx`7US0BZOOFu~yv+n-gp#;F( za7bpqYViI7?66`Su)NWVH1u>mZ}vG~`+t1L4Kidnl~C880&TOfI0iNug{CE z$1CPR1CeD~eJ8vE?j1K;1gd6V$U(4qX>nW4N#ORUWCdKYMK<(Q)6 z(@eqeigvPPyP34(jiFBAogReIQf0)Yca-Ni1PgU83`QH9YS1B%i!IFn=s@d$gdjm- zW9Z&Ct>pKVk7~d{xhmvbHD~NjC~Blf+j{L*dQL-&>#vs@ zxh#Km$ZvYZdzxDTdFpPY&|Aj%0a@DNAewsDDr2`H3xhB`;IixbEftYgvzEpbE@;>< zW;-V9&}CmTcG{h5)&qHKP;XSgb*|SDPhQ7BYqzD*45fNnnBDkJ@tGW@QBVv{NGjob zhD|tH4L7F!yD&*XelOBvk-fj4-{XKk1X=Uul<0TrBG=y;)=i3>EZ)T#6WNYddMrPD z8|^9~S_-e*oAbXJHD^17hz5AdJrhZO6OX6dD_G9kNo+PaZ5X?k&HsQ`OEY{n@JYze z$*K8af{VxV1}0J?VOm_Yf{TNB_2@fzP5sq+ix}7YQgv=O4=n~Yh89q*zPfPcCDP(8 zrzCSm<@#LabO(wo_ym_*&&(KM{Tax6ZJ{)a4=@t7F6!rj+GH8lk+aCAtj9p}vsa?p z=j0zRnQ31po|J@+&CjKMyk7bQqlG&MhQ)$Z9$RT-X?FtBbj|~HIOV8~@MTEek>aK* zH-dq7`n@k^S_2NFZQhI3wgBSFwg;$2v)%O6I7=6#y4+f?*;tZt@JI}|4{x|haX~$B zQp|f3&sUPEBw8V~KP#jEv=ja=AUTB)x;^|;9?kzc`$>_&hx$Rv|p{cu=n=-U#-4vxJC*a zPOB6!B_oTZUGa^5nYO9gQWCC>d};Z8)vo8lKX{l#Og)`%Y3625fDYy+VxCF!@2rK$ z1hl)(jSSItA|BGr!nTIS>gP%)u+dNJ4)c~C*j|wH+T?fmWRn_H8vf}&kL?$S%JWKL zj8Yf#S<&(riKgf0mUf)cQ3yJw7Glahrq9gK1b-&x1uM~zRDouxROSOM^IXhq(BZ;a z2bvjYh8-4e6+j2l5}s^{^B%j}bmn9B+bB`1a!=s7w-#RxKlLi^;Ft&5m34vd>Fk%t zXbiNX-N@)X{GG60tNPW*3ok`8^{O9<*Gs4nNf2oE0NY4$UmUw6Q)o9NVm%5V(wYQ0 z<$XLxTzVUlo--D-!}0Bs1?@d==EQA2u}9US8LEZSc&41a)?QA2x2tbHg6*S&?!31E9sxG1HaM-=5=8JUEXhlQvjV+$Hm$bS0JY zx9}ihK9q(^_b-05Lq*FC2#8`oUGZ9-8L>-In7bGs3Do#!%$~Pp0Ro`fA1A#p$BCkq z+oQ$bO0)0vGz(&@VHKyOU7lP)N=nTTsJwcvUn5Z(Ua-KYJ>gCfT=H2iq-C}_Z8$ZSA|mCLdE3t z7m-Bf19N6id$m-`=2{wZN@#oYl}w#T#Q_bl%xIZc>zX) zL_%e^pX8z_MUATCBLu~+$vX3A&{Dw`n$Arr5 zmU;r_nl@OJ;&*PJB}F4$+6~e?euB20MVjv#GBqA9J#+9VQhRVR`R3c#GQ!es7MmKE zOGe=pd!f`7L+H^>5ZDL)mlyaXURX{Edj8}UGe3lV-6U>x{#4t*Ev!83```QgC~E!L z<`v9w{7*`$MxHkpqu{2*DcstI4oYF#_Jf{fhodUmVgvQC1oOLg8$N6tn*@3iYIY;n!GV4x;8f;*)j}& z$CSYwdG%4_GhXL2zEk0P-vi=uN>}a_I8EIl))CP$0F=0Vehj^XgG~R>wDhomQ&jk5 zJVH2cJvb@P(y|G^(G-%B*uJ|UbL&~=2FN`ChxdU;#3>Pv+}Z9T+bfIN?qgT=jNGEO zCW5#}Dz}+Vf7-CW;sxS_KxuK?-Yd}R<(pTs-}^&$pMca5+d-ESplu#h1C#oZQwjC( zT4vSs+QKL%%P6m|a%H8}GNygicXtaHW1Caaq32%TWPh}(Wz%ue=q8L?EJuO3NVpp3 zJLYK#_-B#osU30ct?NF36uLtV?>ju*nWz*vD<>|}wonheHQE@IW|KqCdG~otaa6ES z^&p?0ywOFC_%j>DG{#UsEA7OktRw8B_Fuk22KO+j(f#+s16}LATF?LXjsRSFjns?w z`%8hjp@-j`lBtdDO)ds}E#Wfxw2UVjEK)jJC-@ca*AlDM?9U5N^=fO35^NZpP-wce z)MUPE-m~3bZYqASmfed5Oj+b-F4p^_;GX>TAln+X=M}+|<^=pU`(vOX25eG`#+-g* z-{|CnXns(KmbXLrtGAxjS=9s%0iZtnKW6rOAr)-BzCjQhzVM{>m~Z| zM{{Wn)M8;kLkGaPPoQ>BUzWzr7XWv^#}6gpLfA2*A-fv!gHg95b2c~dB<53&jO#TG zZzV^}ZibxYDhZVw!fQgblyOsYnaGynTU@_)6vffiDQ|QG|1m&+PV?x(&N#<2L9*=M zB};$kfn4$qL;g>cOr+eJ&BGs6$>px9`2K98nhF*#je&C-xddBI->{Vp(t;?ZC~72_ zL-_1`K1)dd8-j$u7I59(prz01+!0B7GtV3Q^!kS{dFvgrI@)X2RCf6lc_Uwj@>zit$?uxQvC7vddcN09u7~9^YNh5+UQZPE+_*fD?82 zMC-My9&nIrLdKQd9(%Ebu!?_mB*7P0kN`Jl(R`mF5$CG*E0kC{+ywDVUn8)(?dgeG zyBWzfOYssfcRy-C-d0#1r@`sEgDaFmT5hs+$>D3+g_prtYw!|1l!Xvu+*+|AR9p+E zJT%2hGZUUJpZ8=8T)wlC6;N!oW6%Gifc#(X!aHXFEYx~RviPrby!v=16eVejL43U% z@rg?&pI!mC?$`HX_+E^SOkdLY>_~*YM8YTsZAnlo$QRaqtljK*wk2;^%D=PdOA(a= zMvJfXS{|@Qt+DW7>zn?)6UQB(Ds}R2@=jHIgB+AT@O3=cC94}w8+!p)DXJXyr2(c9 zd%wy=&N~_|@lw8$0*5hi2pP>3!_cGdK~{@yKJGZhR(7_WapIn1A?-F}7G@#O?=c2d zjbjc0VfCBS;w?9day$*(+PYLYX(xFFSb5dkrcrIx;ynDhhW5|UZ&Q+yxd6MXCHCov zqviZy-g{EYBi)o$w;-+)Wn2XJMMj~QMk)4lO|;#+XSDr~E{p2l$r}?0mWzVOx~>QTk78%G*uLkw=b4mj1~4pha~diru+mEZwTX zRihJw0FP z_GD<)XoWj8^SeCiDODo_wXnKY|MpoqZ-Wbwp0K)xSMmp{t`VNQhJUNNJAf=+lqWs- z(h?54zj~PU;tvKJ<~8>XD}cX}6~lNDI)IF`uBr7H(6ew7X1p*~0wS{Em!S}KnNPoI zn{tXh8Q;hTrl{Dm{WPbHeeFN~@m(k=qHi6@JNff> z|AWUXn4tmjFdTg?Wd0XGbNe0npAuW3mZTuRmpi0sc=$I7+Mk@-f1Q`VoDxu>a+BBc zIsUFN^%twz0-cu#mZQNxWoG`_3t2z1*9G=wvf1PxANijb^5Z-Z0C|PW``KLn+2fB6 zih|$>D;jeCCxW(Lo%S#O?SBQ}e+A%wHNgLBfd4fCzc2y*#uqfx?_J2$E?Gbh8|4)f zmF8^o+`__-@dZ+^afY@6*A$VVD<4Y%#p&mgZvyx zLb|^&H^Q1_P8POZ`QhR=z0Dw|d(0_m*Q`BVB02UL{7bGmH{6W-2n>=DV-44tpuhG$ zTo(&p&gAq#@9~t!NV=>0uV1fqqikR})%<7cgJ6%9#=KJ%@a!e`03A%03YsifVXfWT z(vr_E5P@ksC2H5-cB=SXy`!LmsbP_WJ*d6pgZY}lZCCut2(4#-wjLTF7nucf2(}bB zD4tj+NY;eNOxytACNZNsL0I<3;lB-7cjbSvu#zk|C7Lqyda5;egjrzWtbdY8>z7ds zV)wh3`=Y%a7+)ch~i-HcLimPLgj2F|Njp?*Z4bsCH7~jzfs)9 zLSJA01>jpijX(Vw#7ZUbuS#14gft{fuZeDch1LcPQtr4xJc1)4Q#_gpja_ zC>px6$Jf+rQ-_Ask{2OihnWs^mcf@2gUFiYMrrWfqv*c9jFDMCS`CqW6Moz{^ZBqN zf26hlF>aOuSKEPY@8whk{9Xo3j?%=jZEJ*ptR~?MN*3hi%Mp}rmLr%rQUN#_>qXo; z0UNn~@d@`|c+-P|)L&w3Y)j^kbN*a_>Sk+hX%Vp)U{+SNWk^EET0i{s)#}*6Fu9F* z8H({UaYj@NU^^7C$P#FH+#KCY<^8Vp85V#Gp)53wna_eGkDk+s%U{l5mE7$W#qTcAhEjt^#T z#@t<954)d@8LW%l}SX^s0q#;E2yqbe``FXeB$ z9V$U1V2bLGuYxV>rdTGk&YI^*VU23hn>8NUnSPr=+@->oJWPn}IynbMr3$R@nU@l( zac~l8R&EV3T!jC$dnc*T7F!#Wo~B1eiD!Cx^RrReb?11zlx^!D48 zg`b;mxRe_Aevy2Orh%bCIFbBeJ4-ti*_Wl8so5U>9F7|>m(vJdnQzH4j`&Ga{o8lH za6y4?`@@INT>As2mRAaBGRu+v?RO{nq>0KDm>C#paHxVy%Cm5r%7H ztm(9v-ArI;i9N;=^iCB3p#NcxN089sFY^UB@(eYFyjVgR>PH&03Tm58y_Fn&XtUVr z_=pf5`9V~Y+qdqvn;8~fY);;mE!dR+8VFgs68)KHCRn(ljy}=$N^QIErg35WX2ZAC zctC})@iG7>=`iwywaM2STDfae8I9PjZ!g(~SFcUuCA@l5Z?}d|QA%0W#b`0s2py14 z{Xs(qIk^qLH(FW!jOu6xaU~dy0XS8n_kCAhH4$E5cg8kmm(GW}!A)d9=V*P%F`ojYO9m_)nmLRzhRECZ%@4B<4dZsrA#pSm7{x&Jsyq+#b z)-j-JcUa)Itw8D4wkdB2)CPO~D;~P}7Udw%Dc(H>Co&1ll^J}p)yD|ER@-?{Y>nwC z-K21?$y+|8_JMU2@9re->!LsW<_q8H(nlLFWnL^N!Q<=eeT4^Xtm0uv6t|E`W%EK6 zKIHQh!$SzJl3PEy@oh5R5hN-l2o+HBR_1K)y}@d3+*np3(Y8IhZ+-Qn#^8{Hw~dm; zpbGa5n9v>5d!+taiyNr%q+qfg7cW;%?+2uMaD*UXrB;uWLD_A>+D)}ID2TUf@|1Td z$+3v>DJjz=7DBj>c%o`f4G35HpF(Ik^ozGV zvkUZ~)Q{ZrNx1xl7=UP>haPd3gomoR``jbNAk|HpH1W1(oz|%c>+Df+j)j7``s41# zpk>wh)M6hk!QF=2z0X~L6%VOd)Vl_86^^^uQEjwAG~IT-jc%}t_Y!Ga zM+9+uhH=e>gmy$iuucV>y^%!By#YUX&+KOPL_GZ?dG5GEA=5vcmwmRxKY(GroK1(8 zaO~%PtAsX&LRYG|bHUqIh>*gokB%$OGaSG>k1Jm2hZeb)F&-!2sq;=t+&PF(cciTa zC`XOza^xd;NgiH&RlbkFr#rrJ~n3Ozt`qb}=V;#yD; zGYtHyqN?>f(C}fCYsJf3Hdya++bdxPNDVz>k|@5*8O7&e(pm`c6RKBN1Yo&dX{PVc zjJ{5<;+}s02EN%q1Gea_i8aENFC0#UhKoL)1Jsg^$QkV~d^j8PoT;SYXOGeq4@<|l zh{YMymEAkY3u{%bvT{S>Yw@cMb#` zmCe~Q&}-T}^{P%q zIm9&Ew!>cdflc*xXO<^p#d<1giROTqun9xY;-*)HjRDl8Z07r2`$gEgnl!}KVWEUV zm7@4?x#Z4elfq^Mlpy2M)~C!Q-MjULWFCq9hQjDTMmDTe5fQe=`x$Zm+byAGZ{8AK zqBRcm`pH4nbfDc{Y|E+wjaMq66$~}Sn`~4 zx*}mj$Za*@k~iKne`yAjy50iWLVE)O0VWK9ovkC zei5JxjnvbIM^Qh}jSx1Sh7d_sad^b;ih%O+x19EFBV>&-E%=Y(winEvXp82!X&S3g zCtM`;E?bSHd&e1)%a51WUC+n2!+V?G!$%!W-xLM1$hC3%(%!&tf74-mmm$*6q<)IH zWtC#L(2|n#W`3@KnvJrxfw6C&YmhnvRiTP%VIWU*o|D*ZbrfQC=8{=TfXmkyWBNGR z7IrouEA3gn_;%mI*Wvubiw>3FBy*}~jC6;7Y$qp~nb7*bxLohF?KE-?Rq2h6mshxt zTd>eGvT)zUFA4>(-$9v}P-f2DU&?O*MLr|92|e;!vM0mY@V6bV7Vhz&o5)0Msw`{o z(jlilLgqQupwdm7G?63O%Tw_t4WtSjf&)#B-+ocdUf59PYD+Li5;ylE?6>$jAJ_wBD(=JG=+~!vDg)aI3==0%THB_cK2K>i4?6ahj z$eHSNDkA_B3Dde{ha%spSmI`S-C1y3c_4R8{;K154~loD-r^YiN=U~!CgvWZ0_ltM zwaU0uH-dCmOrVSWEYs1%w2=73L>H&P0v(A8qE6Ghzp7QU?G4`~wd9@MKTPU$HJ+b()OlTZf$4E zdzkbv?Cgdz+Q@wy5*WX%-DuUvq^#ej6a~qdp=wTiyJ@B6!z?#{h|^;!aoN&IEl6R& zi1Ciu3+k}NDpCkvg0UhFTlQ!*lM{|tV=pAnHrLU13M@TPZh}v>u*0_t(DG}5gzyt# z6vxB4^{ojGPw{n$M{TbJcRi$S0E%iD<*A5UQsB_ZQs{S?8cL;DnU*Q&vagwU%n!*2 zmmx1Pl|LCx$$p;IGTT2;*&ZXgr7WE?M~o1RagM_om%9b$cd&4;zXu*oTw2)#H*7|9 z(U#{;2qI(|pHp>Q5G|H?d7%8POLq0doPfeTWg=VKHqmr<*mv;yH z<@B?=`PSMGmu~2!KfCDSt9=0ZntD^|{_Gll07G&ZZ+R^2xGbMxVwKtTh9;MBQ2B}b<^DR0O-M;D$u-j8 zq{b40_LSw)2sRN^wPXmI-r^pDVajjb2yA^}`m%xEHRL zZ=hZMS0UuDIX+}17D!$EE|#_0;r3ajQBJX!8p=&-1IB#P1CeF^N~cezl2YhSzS;6A zG&Kr?2e}bRz2m`G(yjnJE$-#rc)euVxdFNMb#7d0-z4yFbmEQ zdUVjuzEF^RBIO7&K8?>zqUP@#09>RJ40cQe>zZ4oH#sG5Kb~c2b^B`dFO#%B8$gG) z8m53;vA&1l3u^PAN{Yk1zGA|0|8%eO*JVBAb-XqRv36^T4iD~sKuF_U&!+QTkzd>7 z?=;3K@077_YsXfHo|JEcitcJ?Z67y+h;jM`NvUh6k?4Ex~$H)FfKvI93F_ zScA`euO*ttV0L$wXNRBP2iX_P-b!Gt^QeG6@h3~Z z4hf^~*o)iudf`D5KrR(%s&4a)nj&b3aFgf7;!l*6p+64OnAM5E=Aur(d5bYy^PQf# zF5ixu+H-GACuoK_npk9U$|gv+40Fe4f?g{+vT6q|TQN~i{ufE|JxTOerKY7o{GtrZ zerlXK6vpUZO{U)@>m0>{q(L(5{?QWZw&BvY{!!z1WDw<_5fo^-QL+B2#)#HX&@h7a zAP3Yoq?HYWrrY-0z4`Vu=3Zox>w1>H`~zdE`yh2Q#P&4HOf~##Fvrlf4e~oB7H5A) zK_3a7B5dO17<@}o=xK@AYol)VC|%IKN&n)D;aLPPjRgv+C)^4$)3ex7kB?aFY)?v5 z{xpAutzzqI_SWPKV5gI2uOuoI)g62jwDx*C{YXA*qi+;$F6b=$G24|$tFOOZ?v?t8 zoY`SehKe-{Kk`oF%tzx%GhNAbc9gB>j8FSGS;PD#1v24baq{UONcqFGm>`AvUJH<| z&j*b_TW`?mt*fxw9nV=y()eTA**OAp_Pw#rcW%$A+w6ui!gJUmsrU2@OU?WjGm%|& zY)o&uiqg$`q+RD8hz~$56!dZl3;fT^BJS2%I-En|T`n?|SM9W9!k*@j6)qu~&UWZ# zTeLPDI6E3lXX>hkoLWA`;H9hSYaRZIwGp#Rzq&$`fFunGs|7||mX6!feuK-cWg5}E ze~odsI6DBlW_-!cw7cjSVq>Z_uRn*Pfbcg7d{MW?H8ztpMJs54vhJ~5*q(V(E=ia| zzB;`yoMw{jr5M9^PmamxuHLHU5%x6!lk4va^53S)l(?`QQP!Vl^a^Fd|JaBcEwt9T zaO8${o@kmWBeT@%Q+&0krcB1nMT0`skpUOPTkgyc(l5+AjXY#-`(Vta#S6R~x4DMf z@Xnwq+TluVN};X`)3n}?--W|f(L8a)@)X+&k|(~{KKWv*YSa(5 z);?mm)sIz#k+!l%a;kS8`Ue<>x9chQE;;^V)u(LOvOR!a06gVou%)kERjfN;m?eDnfj$;_L$ zrY9binFUDAZW*T$jTB25o@wZv5LSQeqfw%&zf@#Wf1R!%)%Gq?EJ4ZQc?D7={GIWG zKoOS?3x)^G_|};>1s#sHALQz@M2PyIY|C!g8P!-jwv^#0gG};i_`o7=_)@hI)IbxX zzvdk9Noo9PioJxYGpbpqgpX(nU-rZ{fegi}BBg~5NmTG{QHOk=G+(cMw~<`!N3s6{ z3m_#Jvr)NF`CBie#xC2HDe3 zm1Z11m|{V)S)fbE#16}7%i>5kCp`m@LHp^As4C*d>v+$^&~pOS{o!ABMcC!6Z2L0o zZ3mFcx_9PIzEB`mF2tn6_|;L`m^&NfD2m*Bydc#qs5GTY8b3=|zYxrd`r6&6n@~+X z!zs}$<-3N#Uy;0}4m~_*3o4BU;!F`43prb5&eNrmjA~0Lh_w6ccdX0tvD2R=Km6E` zy*)rby}yg|kERnx(5^ChTJ@*wvVs8>txeNi*^}4gO?$}nM=sw#Kn7#7s`|E~w1;gu znI2L-Shm~LzNiMo?OaT{2qr`IY1FVTTj^lCMI524AeCkFUgy9%0drT@0}ahONYQcw z$v$`|edO8*6d-3d-7_mT^p9HQ39{WO5rO%oJ0% zsy5WILFgUIS?Oj(4}Ca7BhX*|rqkC-o)nz8|q$#(%i225EB&}Dw}%$ zt1R*^6Tc_Oz-DXXgm!Z#$4HyDcVL?D?7uRw+c%RIw;S&iEDkG}Z+|FopG^&`G7dBq zn@LCe({B+C5c~`W`#Eni+(TAQmp>VA0iBieU@ChB8mNy$vKR|T8o4PeMqgT!w(b8h zqP_Ma?7hPQ#q#4Fdo_;~L!%#_UdaIgdAfDu(rQigW3Vf$tUE(r z(_PC@jlNQ=Ej&Z8}^bDV(P23jLDs-x-&EO780(w_0gH)_z(G1*xMmqa+1X zBm=+q(yn*+!txMqx7mt8uQNHIlPyd?EJ?MHVNmbN{rmSLF4POErY8}ONDrPn_E%Ob;PZt@Tx zCG`LyaC?1&lqt{e?5s#VgWC1VU;?yg3=i;-aWlk_RFAw3XA5)IahC6`I=*@xU_$rC zxUXwunS}8-fp@~a0~iLEj?WSI9iA%kIa{I`K6=8LPkP)cGz#P@wi`MFV_}uPSv6Ah zx%OPk96|`6-?63oagB2-FL9=s)g4AIj=H8xQL!&TmkvwN`cG_n4IrtmF)HO z``8t@>6ENZY|@P@LLgWG^nj<&VJpF=6CzjLeJhPq;It@7cj&Ff zgat~AWsZpT_ZyTl>z=GvZP z*o@d8`4Jg>!LEFOY_^KJO4^+;XQdGpd#IPeb%iu?EVI*v9VP^_B>C-1JKd9Zxt9}xJ zG(dV*v{=;!Y{4-MM?mIS>ZJ)TVNC3usno(ID=gt*Wqd$3i`4ufh%Irt{XMi&eXcM- zLdN}etOmn;pH%FE^j?5N-b!7gKO%dr=oH1+o=a|K(5ST+PTpQ4`_P)F2uMdTTvHe1 zMMRgL5c37TZF(?~Jofpv8&X=-s%?oVcJ#cw2ak>p#AQ+Q(vwd3+ql4UAPIUh`jtGp z(WRK)B*{ZF(f4ncEP9Rx-@zLRGR5?g)i;a>>b^!^%zr09T+jSJ?7ew7lsUh8vF~PN-**OsAt8ntj4@{aUOmtE z^Bm7p_vgO9_w(29IDYp(4l~AF=XIU$^E}_n>-Boep+6Q{Uxti!H(wflc5ur1ZukNM zNd2$YiG$vaDwU&9VJm|&))n35_q2=1paz($$yz1hF+f$xS}HiSp02H(h8VGhU)xX8 zFCn_to`dd(cH&9gLhS`4Gb^B0vv7r-Lv+v-PsX?ol(a_hal~JC=v|o%x!ecX^KaVuU{7_E^u0(R%{E*9{`}?EPRiU?Y|AnYm(!9hhhoum~4 zOv2?yLucB3Wsl+k*J$0UUmz%RrQXukr@%btZi}+!N)zuBj|Ei>Z_FY0<9%ki`P<=w zvTI$}8>r3uuLfJgv^CiI_fTrNX{jxOvLdj32f_tE%)F4#2THy>Vg1i`(XX9-?D6&0 zsi>{^Z;I+L#uex{8~&iJ=~@Uq;I#zRZMEoBAuTem+fyukJs zrElN#i!o~N%zLK7X&5RIz!O=u`9|81LuNy|^IcGU9yZsm9mq@Mms^Dsdlk3duU1sKy zR|!vn#M%jqF3v`&S0;;jw6r680=DI-3_kf0zwcuMytm%vY-RLmL!riQStCta2`Thd z2&mSFGU9D0^_2BtsJFc=A!fANT3G3r--E?npuH+YAIPx(R(l9VmxEirAn!uo?9pWn zED+3ycjs4l8`{!K!P|3%q(JiWw=eqf6G_T`h2T$g{H3P+ma+HkyW4e%BbI_BTbYd7L{0 zhI9Ge5j~K)lZWfZg@@zj8p1`zlRQqwMFk}wHY-Y5cW2OY9!*r-{aqp38XWu?h(1&> zUysRF`Fy7n=MxZ~p}V5Yzr}&GSOc=#^@fQR)76Wxz28*Ad^DuC?`en83}pH=n3|@( z>)tvfK-yxZ)L%NoukM@#DVR=J4~}1_`Ww1QbZO9iH?)zRHwrhtH}TRMz?@g612Ljo zLttBCsSB^l*3%)dE0s7GHSxYB+|)Unsj(3qwffDJFCHOqD;F=7G*>dBan8%j703)% zGInr`jA(@nlLvv#I-{(2WUxqYYH^q-Jaeez1Aclf5y!q%{)S!X@E9Y?-W*C)@+hMd ztA`5dR5I(RxL@PzEcCEEBZF7wfafhxEDaP~R>NMtvLwSz3m4~|@@h)l(^$jxk-3$K zG#sx~+_A8T!Od_WeAJp6_(kcwp(t^S$2%*|;QSQrKA>(ScRGKKJ}jQNtM&Q-<+C4iI zi)zzZz2QLFeh?wPPNf>+l|zAmjQSpT5O23Fa|5JpuHxsqZ@X9G= zQobI)u9&K=2NdnXn2b2|*3JdtbD8MjjnPD;j+K&zd8voWb)M5QD5IDD_l z7F?yP`!Q89se5|B#Se5Ye_wa=OKA%)!Me?Wt0-=3x9hyI{<7b#`~8a_4m55*$oh9{ z;q9*9Qu}T-?fNBaYg`20XDzG{;Ej?%L>@mpvNR(3JK0)+|C|ueeQe_+^8Ob9sM+Os zEae@48Pb=(J*Q#e1hJkkL62s3-)C&Pk&^^9_Nu$4cB+0^FjH;o){{qe`yQCt0G&pn z65bl=Dmd_|R!G`DC}n)x8Vj;wtjbl^yv0SQLrtC~ROF<}ul8xOw&Hd<%OAwPpKaou zTr7Pb=D$AUe@rTsx`kzZ+jH!s03qudBz695vzJg9E2h zU){)BepGi|M3|oh2&dh!3U3PN+|2iS40vv+<;bz}W1~HI+XygveW}Qkp#Z=%3wySb zDc##j=}XC#5u(L&M|SmOs2n?c7w>ZDwY%c|)35{OGysnqbZGM(1=rJWO&IT7X1`OF z^zMC`K9}ZoZ4oJ-llO@*&Byldp7w*Z?t}INt(``yEAO+^=xt#31FlaIaR5MoJo&m( zC@Xw0uE^64A>1u6y`0J%hMonzM!2mnWwR+SmW20X9Io^!_Rq5d36Tl~%zdBYXU|;A`Emp3Op%1v4bup73{b+eY=)g5J(LXUH0OB5 z|CF_8$VC$#r<$Bf$kX>#Le<{ z*u^B2yHc5VcU13+R^U{brp2MDG)R@i#sDH>W2mzmj47}5?s)(9ODgKYPL@f3kdI$V z-nmkE)?J*3X)I^Y6-16`4|0ABwCaLZ-~?sapaIOJMpK!*u+Rd}(M)Jz>?gw-rfiPC z3M99-5_G|)=Cbfp!{h9z29NzoQhm}e~dx*Vn6qTgk9#uF5Ero^W*0Nf1CSKzxC@0grx;+f)6+*>NKnrY) z{^}V;{^QN;&-rByy!RwPJD}Qrl0SZ8GJh!x|KtwL8%iuf^XEPK#=*brjsGufw;jPx z&H!w!YL&^A3qMz&f4bBkzchyZhcVV=FbEoff2eTSKoEL3kzYNMZ#865XlvgUCnIeZ z2DG@k55V)wI7y4+K(&jjTsG#9AJ>18#?C|`SOD$kf!Xy|L%Nxx=5`V)8Ju2B35~pfAix0ckg#L10)!E_Xi8X_kxt!=lg&F!g=mms|DKsWrBIeu`5!x5*h)#MjIBa`bufu=#Gm3HM63-LMrd1xPHN5msOl7UD5d zw|{FX!&%@VQ~X*cE3W>VdTfwtcdLe13vXK2X7TRbm)qyt@w!$m`sVHvulBAa^0KUU z6~qF4`#x&YCrJg@+v)*+k}K>K5aeXb*j_|?E8WVYawP$%SYKoG4>2VrI!Q)(JXXeL z1C%Wx@Z%86PJWyPP;L77Z)o>w?D>{o#B<0tt3IXS7%if6` zUICD?m9{}hC{KY!k9CD7Q^f}5ZdC{>;f=>sfDs+`b zo$>d`cUg4k^xnaYlC5grns&yuJGMoNRzL&Cp=WhOr$QuE{0t9V8x+}TUGC`spw24B z0>gZin>FM)6?o5gD9abowN>kbAAL}16)SuNsOnkI zwHms2yl?Tvpu0S`=AVB&AMRaR*k&^%+cxpR&$DF19jUjlLPJ1fQ-e8EtujL8KAU&TX|9HVxt~taGgD z?@A4%q?oKR0*Q5w8JZ&I58_u1(&4qa5nn7pcu@_}tBnAoBH~le9j5CW_;q7o{VRF5 z2kLcg|2r(Agw_uA#b3P}{%bQCykQf2uTMvf8s8iTID=z9m@pBEmy3VEOO81wJM^iM ze=`evJ#}hrYArD1J|G_}ZDrBLEa=eCy_d1Yk?$J~4JvZS%&{KgAmjH*t>`)%m1^I0 zWu;AVrf*jTckO_Ym|Ba4T+-dKkLymt57C|LJqrerLY2~fyN-Uvw3V6ct#i_aIk z+7F9RTJ8;j^nC)#EoHCbN5QNWA2+zoL!x{5I{1z?_Tz0q0fC2FnfJq?Qz%N(VoB+GXrfd1->EI#)I=d0t> zwTMmUJZl9a%%ZR+ZZ&2kT_RDcTxA4*`7zVo`14jdc*Ip%YFMSVri5mhqaOjP9}lXu zthScH=ApRn`d~~<^dka#3^|m!Or^|$Mr>2qvRck)fMZp*bk4UZezsFzR7uc;!%(1p zb?fo!@VjLNdkFFTySBKop(zICu9=#$v;LMJD-68AZ#KGR^L6WB+9_lJ5J$?(x2-;j za&2{CE_}Y5soy&9FY~a!C~Zkb)nA|-2*uKka>!*M9>TfXIi{6`ZV(L9_xv=~w7ws` z#O0vCJnQ#5h5N7ZMIJ<}LO`$wW{$F4pRgY$Q)IMYZ%rfW#LnmDDCW%Y_F_1+rFvlyIAVics9{^AmU-WWYlV%C9665mX zfzT8iznJ94Bck-AxJ}@;5|F4bUqtv%$a}zN0CFM#mpsf#ce~$MSM9Y@YJ!;frpM>y zkx`|93ZPgB-NQB~_-eH7<*i&IIm8vPdTo0u@bDa;<4R;L4xLh6O{Ey zCTZi28Q5wy5W#-M)>w#_c3<+VR@jxDXNvUq!~1oRVD+qLIdJ_gl-82&OMqQ21!q<{=+j8Kf;1vO>(;M0D zUXX-)tA$g=eIQ4y(wRM~F7w*xvTUB2> z^QNekO_ufZSt1?)u?=S3m#*D*-1&z`#(%WH#~Yoj2~UX-Q5{7crTe>*e91nVrDqLG znDtLvHa|T1iwpWFs z<~C6lPYj`<1ISW=fEN6q#;G6s2CcjI<)YJZ*f$g3&w;3=cy^o(Br>;MyKfsPKwz)) zPC9F%W=^`jpSm0{y==w)L6gLodJ)FI$RCh>Xa4l8bQcpS%pNUAlG4HKouf5|*mG5& z6qQgw6#xTK&RseCgKaLv`gTMUk7IA=CHrsrkES~s;1HYy2H=?0GD?7M_u-n5;Y#;P z<`16N1V-yxeK1h%`hkJDc<36~$zJ)fEqDfPlf*>MN&%rf$~a_}1@!AW5Q# z97|Lm5}gh>{8;43~4<;2^` zp;ox?)i{>P{Uj-=ew0^Sq0)A)+n^K3QUbeQGUYg@^UKzl{S`nBaJA%%|Kq8 zb<5V_fTD4le3KYZobdf-5|UoS8UNYD0r^S8O_Y>ndoYZd2@!+4Q$H}oSSQqF-nPx0q z99VznmOo^oeB%o#0jXuhDN2MdfJV!@iqmps5@Yt=vv>r-+b!yl=J*N%5#pR>a*3A) z^J&L_rBU8St6eQ%U3@Q*T0_iz#A zbaM7nnV^AbUp@Oi;Zi-oc+y;3fl1r-bO|4F@y)5M(ey=^Ea<^wO#(0KeCDLka?9|# z_I$f8CPUuQ!w4F#<(r+skmpPgy8IM156iZRbAa4lj$2WDHan9y9Z3@)>VBMFdSYER&~R6A`}+OWrHj|biy@7pNjx#LS;#*DuVrbdRM z+7ysNqZq5xhN~54-eBH8Uo1CnD;?SCT&o1WQIs%Z zkJ6Cy>x%$HW^3#-ns-Q!jL-_Ev~o<1G@EEVM?YKX>GVmJkBm-58v%W8&Pk}`+!X^i z(qwGPD@uE>%5kM&q$aii(!VPpVDJFL*jzLLq`h;{o$rv&pPn=4GRr8L=lWKjvcC>> zR>+};53G*(_9D&mDnQWHzWf}Kpsawj?^f(nLT1P>2h(`iIy5v1o!4O~oNyD&$iSpG! z>B3D8j$sNw{_`mZSi1!)6NqZMfxBk;?Zv4dd@TT2W~35Dwn*?@oxsY$$Z$QY>FeNf z&vR+Sn8~XG`kyVQn0wyDrKf1xg*6M=_JaQgF7Zq&Ua*~t z%yFzq^gj4YBC@kaD_a&6Boy<~8*nF0{ESrRF1XF_+H3wH*}HkoUN(>5iXW}76Ap~1=B&!;b zRk-oxHBeV7jhdWZni2aq-T_v%Z{5r8_o+C<6oxu`4hhmRIi{GeVXDmYj8 zc*lDgU0LE6H-m3gFJieW-L*q6Fijj@CK)TO_26Tz%dI19m1rxU$_0+2DfX`=s>sq# zSPYRpV$m(?+?iD9KHhl?jXUNy7AoN7PHsG3F-P~%=z1CrjVik-YP%zs`;(U{VknDF zSggGY(C7k2`tr`*Q$BnvWnXWi`hrWM0^uqGiqeT13c6qZJdC2cir6AxuFL$UM10%{ z2E`JXK||qaYC~33(AeH6H~5DWHamxa7_CL)$+7mB-vceH_?fMx5p9GI2ah0+*Zu3Yxm zo8*Pi^h@y3>~Q?bHZODJY?anRJt=SYS6Q8-yHCHc%zw{q0STOW$*MYk1=UB5n)og$ z`*xI@PjOk1GRlYBj#vsZmk7elK}uRhdC5DslB1}}hEL})C|bL2ueUbSe2PkcuX?t? z5HsH%W<=?#@X)JUy}n36=`sfUOh*~}k<<6PoPu0^CjBuJjxiV!$q#90Lj?EaIx`zd zVXYEY4-%|ZXraX{`sCw2?C=RVX~;&oU>)Jl9Kx^A8ISLZdbowwE?CIXI=xY!<;>lb zih4s}ZX%X)MLOVln1inU0eSLVA~JizqjK_FNS_>P^9gtr9i_Rf;71%ooeC&SqGWLA zTag3-Z_Nca4hR|0y9spPS%x+`@zktQy59FO_9dI6h_KxM`AC? zjwOl?-;3=UE9jn-Q=`1?Nx0g?E1^o>RDd=BsuiNdN=kLtjUQNT813WSog!IKE!Fu` z3Q&tC#UhY!{r`xnB2_G2?B_Yzk1LAOD3WV^TWlz+8VHVyXRVz&0vYK~eTl}UR4GqU zk??KjjWeFcb`@O~=-)aX1a5z!Gc76!3}!!&HUSRzEO`dr@DiV7WF*(H{ zJZJlX;_eX$teU)_Srd3yhdvddOjT-)q)tu;Qam*4I~-|!NPY^#WPuF?kP`rY@hk51 zaFre(8ZMlg`bA9mICbPh2h}HJ{+Eo+e`a?YJO$eImP%}DzqI~RO_>RkO1)6XwP9gg z+v$gc@vXj*??&+IBsoR50Tg^R7eXa{h&HQZ}Q=A|OFBE(ld` zHk7NR@_|c@#8gK1`bs~oZTfN*vhyQr=@d+qb6siqQ4!)G`|^{W1D&@DYGH_ee_D0VtG!3mjLG_>5$sa!6n4lnDd_6 z9pB}Gv?y&r(qK4`t~T2YvCbc=lhCnZIu>kDP2>Ez9mBwi zkmrU0a}$8785daG5nOfx8Lg27RtnQ+z8mw8iIybDCB5I5 zd!S1mN`Q{}m}s#+X3I{ESGH6HjXs3LTS}nhEAq}gq(_I{DW>w-mCJ}&RHv@-dJNAk zPK3t1)|Qo_Xi87OM*wh%0AO(eUg)3>gxAF4?@>v!eOF~5UNfAubHydioD}@=yG3ju z-MKQ<*1HwFV$UItgV%}dxHwtiVMp8(bfEM+k7$b3Y>_P;5eD7+Wro*Iv+74JuzToRG5(%*d3&b)1I&u#2 zwg2mxX;;r3&vvc*bnB}77Se;-o+s7|Qui#4j;L`;h0&jUE*;=J z>^7Zc`1<|>M{P@AcL7dy0KL=1qNWBC0pXiUAWG|+TI8d6^Q?55i2+(_;>~J-qZh=3 z#78^KG<{G6lJKpp#c@FTh?cr;th=)fiQalsU|T)NRwoTdqf%l4CbW_ni6c+n?MKuW zsbbmu8h|1ZIi@TNZD*sfVb{Z+N-Acjt{68eT&-Kb$(kJtlknr54m&_JVk};w12{XI zxjn1@LD`J*sWaz4jl4|;h=&VP01S(DRK}`qjQ4>-LAIAJ+GwFK5m<&0G&NNGyU=ny zKt#yed3YIjO?e05OL7RYtPUC$nU>IZ0qKl}k<=IsP$mDt8|dEK%I(({wT|AaqD%+s z;@y2i4h$FeLV<28O1cN_?aZz^rk^h4BrgFvQ>%O42YINRl{dy+cR_qnys*gki>LLU zx+Lege-s&CW@w53tW&Zbyzlsv@3UKBiI51EXU%+{@0=n0$@sUxZFOTovZYeab5!Ta^hs2*ALMUN zvF4x2lqes(fUSfWC01WKAobb2*0;>xF_{M!#!K&aJ{u`mv){^f$20xXg^pkf%xOQP z6gJ-dIYvrxndZU?mX@yXEHe^Y({5&U^};_;1LC>go9AFJJMRd2J|gfmZ?Fba%~D_t zxh_&X5=RBkoeBu4*h@7RxL45dZ8-gzgX5+cy<0%`9_$4;|MqO!xufdk=RR6tEnWH- z8ire_FiVR^j*>=n48AT1WBD>bHnFDj&A5XHP>g}8u=<*nVT-#?@&$K)xgVb=v~WJp z?_9(L?`Aaa05go;?OF}L_ZtuPI6r5T-0f(xYVOg*&(Txk@S(?MXV-_*ckTxa;`TW= zRHt7PaXpx{9uT1V?0Lua9Bh6b;&wi!!3e%6UkS0Ry==CQur}H`rqT*VZI^y>Y+=d= zcAIt>R!I!=5b7*U4$-p|!=q!{_VTWnBX!CyB@6pNf@8(hwVC296^| zE^|gVV!kW58|_?wd48E*B?Mb$H_m+ArgcqX518d*JOmM-Z%ca$yteePhBBQhnsicg z{S|^B(sFRmdd1w(`eK)tQTB1Tr3u9Fn7Y*CX=#I}H6>1lC-NzEb^=!WM3=>}u@8q9wI>#sZmN%MZ%CUUy9lE4H zEd4ftR-b|Ph9vAqi!Zm1?#Bzxm!9qwXDSUyyn8yJSoVdJoOjv%!#2-haPPlOG>igi z*7Ab`;=ks?Yj<@n1J$sRGEoNLCT#U$A!j+0TS{wFyr!ux7*i#)7$E;XZ(XR>dQg;7 zQ6bx2a3@*CqGzPQu09k1dni~=DXE5#1vV?Zm)_fUDLN36#z(6SPCiric=@2$Y=>1% zNr3suBHQtA*IfqE9Y0>?x&0mGb?DmVA;YqV@fS_@*cBv#wZK7B&u?Qorj>Im9Gmnt zK}i1x7hj;fk6s*0@VTmy%XfCU{MK-eU1g2|n7HNQEI8@UXIEUY7xbZBOFR)*HFpAL zE+cnq|CbpNTdhY~?}fjK?&>uMB+v=BYZK(1@`l|86jnFtoTRS!;}>r1fVtMsD`*-d z$Ixp@Yj&O;%P*t7+eUN zpugjD{X2GM*lVlZvW+LlJk~t!Fk;dVt4ZJC&W!Qa6S5VPr$T%o*0*FPDBfq>7X8ht zm+eN`gGs^HmzI?tg$N76)i1jYOl0EDKzYHN7Q14$nI|tuw`Wh6^#6v-n6x=Sqmpin z6MYEyo;_!*8Wpp5is9oHcOPu4EPgT_H#!RYic>SrvsXo|YohAP4t&M-djnizEtje5 zaWV#C`G=Q#ANPg9l=_|J02bxr!o^q9?st<)F7$Z001Q%-=seqJP}lv(Hs?q`5`6UT zNJ?qyQ0M&=Pfbf?uYZbbgO&E1!uWT^Fo3x0VmWZN2!OTct-?&pA|1D)EK?LzFQuN< zkn^#I$lsD#@7_LfPs2`^BxQMrjs9)(Y|5SF+M1P3Q3fPQSkbi#r=}Q`#ds>xk}Uh0 zBpDr5^3_d~E1>R8t=umhtbY};_;n?i@B*1T;rYMT5d!lY-YyNfH*P0MjH8%z8{Z1< zbYI8iVdN9er^+4)_p;_s9JL)<(oa_L$r$Gv)||`t0!jg z``sB3H=um;n~)L4_a&DAbjGJ$Ov7td#Sb9%%UPb;5i^hQ1_e=2UGw$-{JDHdK%AA zCbc_Z)UOcDw-fDd>8ViDM{GN*s~nocPRV07`$jLY&aOJ4a5Wv9N;{MH&R!XDNoaqH z6d0A&L)%TXcJ_A*UkYdRR$KF67nZ5Mi|-3xC?EV}6N{^>fWjXn?`0~XUC)%%-2uvh zs)u!v59^W5SPt|9E}5NRwY-MS}Nr^l{?QpL)nLfzMQ&ohnd{h zopekGv8;SQRn(91S_hJP$St;+TIz$3Ewj0h?*Zs%j=AFCs?*W*hBYQHh{=7AA z{TBSALij^r(D(5|_tI84puB?XyMlM816ilYSeFMt!%o>mS6xkFwR4KTwIJ%8NM1?F z4>n(S2_TAkiYvvkVGf8*97>&f%E~o9W?lWUJ>H0+TNQ*~01*8PFiBkDg;i zCLbqP5$pGR0QU<5s2KFV$p?a)Tc#4TG%{!VX}eeTcSqeFb1keY-2=*;)Mm)oD8lVT ztD0*%Ovy~qtOMVH(BajndBr2ncBvt6AlpjYL9-y3Is#RSthe7e&v!NyDBTSyCs|vr zD!XI)EU6nUh|GfA9iE&|AX6Wop3<7o&%A6(|J3l1a{!Z%J3D8Qi_trvGG6q=&dizh zN!cB73bqs#7il%r+qUh}$ zG>dYl5Zj*o2+kgi>)5nKuV`FeP zj@)yR-^&z6F87qU#X-3lyyg_|8)hQTkszX$1mSLhmHFH?NfW*+762$!yqW)ikN67^M(r2ZivdQz4LmDhE zTl9eXB=Pd&=RSC#%Nmf*1jsbe{P#5-TD|dJ#$dFN!qldU&<^ms5=eG0Dq+_G`w15D z-eUi_W3*F^99Iz$I-{*Ycek*B0-a_3?%M+3-n*7q51ex?EA*t$RYLCFv0r0Oz=f^|W9mR*f~4*KCyfU+n2h8eyT0DrEzKRs08}ITl-NMOjr~b>Ltix4qRmf+pWUZ@^2mwjw;u4Gyj4(6 zbTiK@H_Iy+bOqOBBwCc~vA90zoD$!y=F~d5 zox*lj^ScUk*g-G$s!|zr)kS{_JnB=J0p15+uhX&vn&>O~UXNoc+S$tZcwZIhoQLHy zzhDm>S(FHCeJ#{u?sNvXqyPM#@6j>eL}-D7{7_rxeprhWk=YZuM7L0T=iaP$G{WjD z(F#!zc?VY+iLk2ux;wtHlks@t*3xg`tt-0Fi8pX~#klWS7+kz2Q~F&T7?X!7LGwNy z9JGO;tY9@QE6VewW_0D+%$ep6r}aeZugVko$wA>-9)QGk;Zn{~3-+h3nG@H;LEH2G zrACd(|Iz|j9Nx}~2l?43+2`I{a`3!7PbXcfU3ju<_r60CTF-Xu{O`Y9&TA+kMtF|e z)ExUC?;nyVI=O%H$xy`78{~TY)t~0? z3akfMZL-**%{y>;I3aIG+aoA`RFRFotWWd->f-!ZDffI-KvYpjRtQ(EITW^_FqKE#{&Bndj$F&rc1U9eb9ezE<;Xgcr03q2!SOLxEZ zM*kLp2@H<);`FEK!l#8r1A(OLO$%Wx4fh&~5m(q7L^OgCSTh)4>mQi$dv>;TRNLCh zCrJ&i6(MO%$$Bqa>`q^^lGIDsoGbnmT2W~wXc>B9>rCvRK=)pPuTwxiLzBag4Vxg6 zE2u%#9H(&vxwUi&T0HRU?i(gNxp=OxzOT{cboYcz| z16=em)08{-)@SfpEcYmG_QluA6Z|4ZXTd9v8fEMkA(P@alQxK7XXEuA)*D;kYeDv< z+tq|vUBSx4fQ+@?7J)I$MA-rx8r~Krwo$v894=k1?6g#*-y@Kt3ccblaYyP^w4%O2 z(s2`&-_tg2mwXvY&uFnrde2bCN?6KdqtkjRG@FptH`?}zF5aC>g?EJuB-)<}4dr%Z zhq$t!--mNd*CGAg@mdC&WAoy~P zKVwg7jD>Yhp;YhTUrZD*+Egn}R~E9TCm>My)K3@?6oLqN#_;{u@@r6YPTl#|^&Z;6{o5rMv zJ(UgJaKJuRq#vz7nmP3)2xQ%Xo>Cuiu1C!R8B!yn020u_F>G3wO!`o$VY@UjFBrQa&>o`ElpCPnp$TMk1WE|o3U zq}d?TmW(Jql?N_;s#_H*JXi~d*q-AdX~4*FLjscqSj5Gx5^v=~srspPJyH584x4Yo2t)6lRrl zIvAx^cj1LN@))U~!ydZtrXQo!p2-sVWVl+F_UcPzZR7?q4^_|oT_kEB)m_zaMzOq~E{kV} zrtJm4D;(DNmP&G)RDy1WZ{=Ldv7a!Y2sBaF)6dV95T`#pRz4Gb`p$(4O6#^wIF>yA zN_tuoPVu+T=u0svh74Sd^tUyytE;2+pK<9&VfwERYSEPtY&ZXyi};B3+1F^eqF2z@ z47edOJnuu>>zy`daBq$67S2e=p%dz&ULN7tjz-XQRVpqOX)-=xH<_;Zz) z78`k;!op<7H4kV~w=O@@ctjzdIl&^1R5>%C0mP}-ijkIHGd+uh+mgb~ZhM2aHa8_z zSd=YsN!-RGk5|%bZ94+dtLXQv4=DEI7PkJJ5H^7|;gHt0M>VtWu%uk`5jbL6#>!Dc z{oWQrmlbe(Z2c2ya0!JKpD|@Zn6fIx@@+iOf zw7q{byN;KFQ&v#}L`*w*E324UL9wnZr^?f*9noiB;tQ!ZfIM@?pdKXbxbKY!Ldy*G zrBIT%pbYKdHKPdq9`BjrHZeWPy{(YZV<|x*hK%z}<-S0mA^2D2(`HhS@3x0>DCvig z0AXuy>-iE*&~bgsc%(PT6r~wMsC1EkeIoYCF^M}5U$F&E|G<+vB(bK)9khuSgAJ-b zhW~dT>&F4s!rg3anOX8^w($|rJ})!-!9I72x+a%rTM=Dcmf`X0#OBf6;h9D0t_P4U z4PVa)F*Ta+2c@a8#xnFCGA0gTBQlNQqxtbJQxqI{^o~D#p^q(L%LwCc!a|IsFUP=I z19&Il;41P$;+wWEq)f`^qQi7jdy~V^3~bih22 z^KJ0t(XaKyMo<&uD#W>0z;_xpAAE=?U~pjBD3FTsu4QQIRDQeRURf6OF278DVKAg= zvJ!k=J;@V((b-y<09{>oFVYOHb6A5dd-?HO7RkLGdapwok|2(C9o!EjK(odalyUSoA13<_n_xqgb%(xw0we z^=fWyQxh#g3hH<*# z3Z^Qt?=}v(`Si6x+Vl`xO{Q6ZY|y5$XT8f{iTYF)FvjS8U&}A0g3qmsz9#mBQ&JFW zY$R8hTabl=amMewydPM&aedB2tjbk13T`1->QDBMJ^+0sXaLFh+yYgPfUj`th57+y-3y+++r zM(JE583W?WLR~sTf`kLDO~c~A0hbu-jogis-$b718!W&CV7mJF*3~lt1kl7yf94=_ zFkompK$?ft7tb8PQMVx}+eCy2WLtLv_taxa@nuCJnlP~mm1R;)8Orzk&r|ZYnCHuE zmd59*8;M?2YGWmT3!F4>|6G6eD)h)7_=-gjxXYF&3UsM#BIymYIVJLc#yf|$Z*YFq z&wb1}vqVJMoNBPhaY$D6J2+(tDxW5EdoPo-1>q$$}bHgcydNZ@6kU4m_Q<`I;<-yfcO2@lf?P zY@A@{QR-ds*By?tKWp;6;S(0ln9}zs^FTj&I8_0?cM)Q78{?Gw!Ii?EH840Dl z5k5#@(+y?yc;-91=KDT43XM=4Js=)*QLZ~_e9f<>m}Y|TohWw`8eJJzU@B`dl|vsx4ng+*@@s40Vm|UE~C=)K!02)lY24fkLFQpCi>8!RQBoNspy|(@DC>a zr2j(gZK=tNH7X{v3!K z%1LP9Hd_gQ|3784Qa!l8hsgf?jl1^+-45(5asessBn1NW|^3NbQ?1TDttVpTT9bRCA1{daTmsNiuN7zj;4e)4TJv5S53A z!2fP&|24*+fBCGh^$aDYB=m>zg5)&p!2sc4WSPU%zF`!pXlq z*!D!g#-?xHhX3tHlqv<-SninZjlVruf4)Pheb`q^a({bH&CW<@fdvx7|G?z`e1;_; zyLN5*i(F!!`I~mIBRChBl)MLChyV6qzZq&h(}0}HLjPer^WP`_=P5Og0Vc)VUH0VP z9&8<82a6ufn{hvXO$TvMYe|xa+lmR=ai}=X;!@cv*j6=&Dm=yEk>Q{ez zup4J3{#l%VHl_b8&c9f$|18cw-!Py3vpE0aEdA%?{Ieqr*qr`3Isf7;{paNTvm@+> z=kSkP`{%p#KW^=x`IkT3%75J2Ki{SQi8=o&`1mL0{PSHp_@9{bFFeJ65<-8mOaGG) z`U_9-|L+N*{wupgRecYjX=G#*Ne*?C5I7TDg!imfywijjv_P%*Kti#Es*G)ghowEP zw`>E(9a~7sQ%?*cNHX(U2n}eXA_gR67et+ZG)2aQ0nms3yER$jfA-LyNcZQuRf-vS zVFN`af7$>ObRP*#=Db z#y9Z7wwu;kX}JspL&{CoUCH+;*yr_6ys%_ofND2HK%x`8oQBOG2y6!)9nZc|0{=@rq=zr zZW^hRZj04SxkD!%`qaaf2ENzekx25iLF|S70Iaz)38Cs&xE6G?`QXo&{BI8}IFx%| zzw%_az)x17b+X8NX;4_x=gWbk7bPaIxSD~?tr^wR^?_jk$3y@gkYC)|Mj-LR*Fr7^ zZmpChKMcSYRE7ee64ux%>=Ub7GUR%yXh8}JTbLKr8=rK{YpF?^2 ziaUzBFxv%YJ^3E9yVt2( zUt4C!AI~*{WzlK}u)f$wtxNxhy|)aDdR_a56$Pb4MFdHU5CoL&L9viD5Rn)V=@^iX znGsO10E>=60TD?FX+~P90a1n?LYiUdn0znR-uu26xYly5=l$>;&v9%&IsEI2v(Mjo zUTJ9=-=fUs9*l&E^%qiJtGlx&t}4A^uEnJ{@WZcrSMt`YZJp%r_e+!>#NqF|{R9s6 z56Gac6zxS`*4m&Z1c?Ck{VewvFZ%70?LmMhy2~klWDAR^71G%tR?CKxg4p(mWffd) zHy=;%+LP>D{-GFJ*`B6{a;bhK99&5uK1fvc3+5_CuJ(J?ygG5M`WPF8SE6j`>t4e# z=S!176m=lpf-SBR z?pqE}Q!$Gd`8=+3sd&50-*lXwEh9+GVr`DCOoQJ2qBr;;2>)Vyr|}b#>qu@58(W3n zs&06l8g)e;t%-uHOsBlm+f(D!cRI5@`Jyd~OD|DHv3!oaXt7kWDpxES=a{EyU!b#q z-%i<2S{-X;{QwCU5=+9#`?^n|CU54kH;hkMhH0|plrJ>KbbwZbOlc_B3u9fOUy9M> zuUavd4-yP+7zx57onDe)d6RD~vI;wyKqqcyY3t_QBPh6>$=&(7$!Lx#d900ln9v8P zM(`fi>8v8Nn|XIMqXD9$2PKwMeDo=w^2gg=!yfYqPpo<^YNR|$K{>>{QK`FK@n8{} z6^IkPX(uIH{VvOJ)yLS{)uUkz3!rbr%(F`A>7^+S-{XYyydicSZy#WxNYy?W`|HJv zVak!%bNLl+P56gQe?_g_M*q$S-i?dh3f;VMDu63cZPWoOruID}r;_`EKNph(f2O77 z5`6W+GHF$^)0;fsP_vzcH|&#itUX1f=QN9Ec*Wcx3a{V0j&?2)^jDp{#v+9^=qa#c z&t98`)`T6q@XbK{q)G9q`1qaOFf{(-?Fud;(hBGb>Vlk^&-!R?$KBa$1N9P`?`V>m zG$z5|_@aK_>1t=g-NE#BTy}|2fs-+bxLdM(?yQ0oBd%f2-Bgev zTT<`rVCqX=(eKEUj9&$w7Z~pLZcu7K3^5NiK-M)=r#QkX>v>Jp-8KmkideAHE(oa; zgZFl@HS^{au!n{#Eqs1#LA^<9y+ik#8j9MahK{of|4R)C$HeRR-hYY_@N-N2vgADjx5$y-yRPc&%mvQFE3$gO zlL^1E^6ng+*jHC>0&y!%auv?bLtNYcI6T8oGN-m}4M+n4eqFl${xYweLSGX;$_E<`1J63Rz|$1QP6!Z_bK3XOzz|9TEi>WL

z0Srm1~ zW^(?fe71`KM64fjLp1&gD!(yN%qfMD%5L~g66&Ltodiv<^#vVnG*hn~LF9kJzT{{z zF0_wO6flfN!WVwb)$_paPe5-CUtXi}%8J(B^Ev4{x_mY0YpHA5l1U#poYwloWfnXR z(ZFX>mc&1^rh-c26vH`Ca-nrpo+}( zRc_{8Q7~M4O7PWaBD{b(y>p^F>o57nGF9sCkIyno&`Fc^5B0v|jlG3G(ai4%E2(4y z(EYWgf5+-iQo%dGtisPGaen#4wa28>58+f8;u_$8mB>s9^rEivgXKNMDn6^!*J^%+`8^W*9Xh7wIIzT1f>#QlcXcZsO(r|+I45} zQ!aG>fF!F&12brUGtmZ$cVxWFopa14D@G_y1WFxHm5EQrEsa~QFtM`^AHPR9eq=55 zMZ_3M=r!KfV^(qe+wKH5eia249=Xg5SY3tr+U5^j@sO2h%d5#wMcqP<6{C?BHFxS( zGqOuXuSsTi(rN@KBC0DG9%m75$MW_IF}|k{@S9#nw$he!o_GwOd$15eXb2ZTsa@ku zMtmvScaEmPrl!EU$SJ8Ucf-gk!e#Kxt_Xhn0{oEjEEj_i;euU^8r*lyXMb2YLB~A| z((71g;QeDLL@Oip<-S%W(#-G&cJxBT@FHzu7es_VoX0irY`RV#Vm&oV$|JIf9nEnV z!J}dKXckMO5GF}{xF-_|hm9s_Iff=zj;#rxJc|0gBrD2?JuNHTIC#AN3PhtW%>)d( zV;_w-<1Pa9lGRyOL7fNciwg0Yo|;h~tu6;)aO@nPM&~Ym7xmCn^C-!(la4W&OlrW2 z8eVoi#*p4*7#m(S_;rE2hzU8iM>(_JzE4kO{v1~&WhKVkm4!K+JY%CJ33KfQ$JsC) z3ua?OYE|Ri#+x-soQCIV@I3ByGryTD$>`A|(^SnQC59obrU5@Z$85=X;#ZAytk=tD z2$nlhk$e}Qiu7mM`$d_0elg(`R+#zF>pUr42V)d@1u9sA@gMu;O!1X2ClUNUKc1(S zg?^;0V~}bcH)fh5<6!&vN=ZE2+}u$my|&?@m)Qb+Hc`aLSU zh1a#shW^~--iNPO7F?WJ*378m5YFwM13u%!o_*d^>1owDFZJP0g28o`yA`tYOmFEb zOs0J8Z?jzfE=^)nn^U(&y9+a?uxWiqRGdj2s;he zyPr@JB`Hh#6QESm8vVhu{^_BYlUS^-VrqTuldpd8#c$WNylNW7a^kyT?-L5KX3D^( z=Z+a0`SG%g*3(#QlgLN|-kptZ!*{YgpNxoGrhnS$fszF|Jp1ni$5uVGc6?_KV!ynH z-sUAzH?KQr3yzUin4Zb6`2bxz`!J&wxvzmvg*Gc<_;NL$ zyWS#3S^gn+=vU5m14wX9IASiS+BsUu!~SO0@pI^ld7>l?g4l6OW1Le^%%=gR@`@`A zB@Z)8Fs%T#Q1!DT8jn4|k=O=(VLW1ya)GOOX67^T+mzpMkiRfL$Rcr*r@KRfbJ2In^L1`zPkD{NbX+6mHFGK=6>s$FvRsQ|m>98N zO&txmQ@8%rpwMr5mXDu=K~`fh%919uRdiaw_*bG&5C3ADMiYK^5u+NFeyviJSo?^* z;}HwKw@9+HjQm)v8UiamLKaFFd$lZVv!vO~KeoW{e}%{6Q6cy zkWan>6j+uUgV05(spdnmtu<_rctyUNCg6PQXspfG7Gh1!0xS~x!%1n`FK*N zKkDns$nl_lPn_z^tDALR?;P^(`ppSf5xq^dB$s1sbMJh4F{)PIevyv@v{H$b$u%=m4DR;o@flwlw;505*)Ypp zCR3w=9kMG++YJe{fmO6Xn8L#6Hd)4|qLjRGGrtD{v>(D2%ij&zT<@OI63ckyqdLDf zvOGJS{6$`Y7rxY9M+8;-qRxgrwwZuPdjFb8bOSnDe56;m0=;hV27t=S;2y-V=pvz< z;>iUkR9JwWV?E~8oqEAr?Q(5Iot9Sl+e$0oXV-lnW5&M9`K&5rWI?${Sz&f9#Dhw_ z%QFpB%}=zd6zV8YrpARF3u~2r1U~BB^-+u2yEmetXe7;jlp6I?b5GDNHs=FRxOyrn zt;#i^duP`$u!fD9Br1QraIagB86Ro_QVJ;9T~g)wJ|}4q`dOA_oJP$jon5lFb$`kOp?%Zvj1EqZGT?KA@4&cj(vF z^7}n|ALJnL4i;@mX9^j5K!Y0r=km$7E|-QE*DS-~C*wi{;4-iDd>^t(+$s>M^*V;I zteQFA1yNp)KW%woqOZhl%~9$|a(YvQp()3OnSyJfy|o4u8%!eKu>FkN3rts0jI>Q~ zj3zEjZ7iC5Iga>gmw^9XCC{0gVV>EV##>?OKPp9 zMlcH_s580QrOJrS`AD34U_UvYYf)33{bj!F#rJlIj$n3|0P^+};N!sEruRN-$e9na)r+pT>(e#w(I(SS*2x8uC=IhPk zaZP6Tn)8@mjfmfc&693BOD{wvAY&5i+C1S+H;iEk>7}4nrJ1_mndm!}KG!eZx?6*R zZ4XXm`P)XMu369zUubAe>-Z=w9OL3L8eterS?LyL(Y=v^+^{ltp0+jPevgUIY-m-} zEK42DDjHx?7OqJ?5q&3EpEXdHi7TN3CEx_qg)eXP+?6JOyqxwA<64nmtHq!o z5H}r@tcvnleXrEK+{{_gjLfU)x8}Qm%~Q?5ej<{7Eip;itPPHk0zOhax6-M=-sGU8r^0({k_84 z7Qk^v{T|{x*Llnq7QTDZW&S*;mG6crHTMZP)y0=RQ}c}T_7gWkAa0@zCA8<6N1-Ac zaaHb>umHkZ2WacJSEB}$0oF@G+o=&z(CjO!3{sezO@!C_G6_Isnq-5Le` zPcMKCd$~nuE~-hAt%27~djgtQ>P_&#vSI|!j2XXZ1Ch3V&V$Fdugm(auw3MIJ@?k^ z^-HMo=qvrw+hkz1)%1d>-*>GW5FG8^j_S8@&fJLQCTK8e77aORl6%u|pp1q9GjpVzMy-Nx?FjW)pN zpIG$Q&b+>J^&D@5GND{rTdRI-DkGaoc_vq5D6cKsw9I|@TsdunKYhvhWwYELHR*Ik@Z+@xB zo>jRv)W6mMp&iQBN%ZmGe>lrD+>-ysl2)(Kfran82> zwNkKhxc3H+zZ{W1PZH<5ZUc%>|1;%>L-kOOczyGWHJ@pQzSG(SDN|)HangKQl*`>`zbL&h9& z5q`t#;b&&OX~xc#C9QI+x;G5bfQ_d4_UGh(_;CmB$O%fa?W`^KBh1W<^yMy`K4qFt z9t7Srl{6d2FzmpC^>&K?F}Jwb%6!@#Ixzm#a~y*b2zDxSddSXYUuN?f;h)`Qw)9ji z-B1)ny9i}?x!(K5fqr&I*H@m-oA^8=QxBkBO1QK=qgLOyy}#Y=?N8S&nq}7(krRD3e3w?cAo6g zsrO0^!o*r!h`Oo^G?e{|CaH8bt&gKL+(q)@06AwCTX3q7wVIItnG=waeyTT)G6*=?CY4-5SIo|9UV+L+ieb}M= zz9cUv{OUyeF-I8}^B$C(X72|i$lJWj@|6hl0vxxd(yrXlvSH6~!BV29ak~gro-dA`en{wjfoL+20 z`g`3H+`g)yXx>-s`da1AKpRiJr+lwtelCy%As_KQ5A0wS9A>~*^bMJxE`_=aM3=`+ z3$2`f2eE2=HRr#8kh?+h=J56YcjDq7YwafnVHBtewo%;N5`+qpv9|k|M=0nqM)F&BcQ|S9}n3!8c2(p@^4$gZhx?^o1-=X@gR~h z?mp=L&qvD*%1?2pBnvmEGXBP-52pd;s>r9%|IbGoyrJiswf^}6eNG1pq`OPE=pTaQ$H5Ub zzVBkK=^f48cW|qz`71A$s1V##{FECwgbWT_?N?gog|=jkg8ra{Th3nO1n80f9L3zt zxK|yOz*+bwjgYr=KmO_Gg?HPwFCAN|ZFkz*iF@lg9qRw;ti0t70W&*yCt<+JsDE^t zkk5WwM@JbQ9i1vYQ&ZE#m8;R#HZ6%x{N8hC@~2A1n^jR%cMH#3gB4E?Da)xq*@bm3 zclp8L@M7o8tcz#<@O%IB`K0SR8|!6dmLo3POzfiD`t_$Q0Wta3F#r|TXyV>}{_UGL z)nouIl0y@}=QIZ|PhYIx{_2usQ&W?UhK5F09J{b?^v91MUDTX!e|vYudTFA4=>4&a zVbO_+i7u6;r9COkH)p4(r9<}cF-@n%>ECk?b;3k|q;lz(c%<1}AZIjzHn_{8ESx;d zIR;Wp%;Oh(YHJ{rbj9&_w`ynHasXR23^{E)L{2|7A0>>Ex%O6@k!>_^u~iy`ZyCpE za}5w~RpINUWo0b@$RR&6Ez$LmcKAPAymfN_y6{YRJKekW) zUNbT}&|?Y+PJR?Dve8AUQ2!I4JrkwjZ115POO; zB46mm;XqNy2ak}lxycBz7Ld^hvOeGfZ#A-s0jan>Mcr?l(9Si%_XGBX_iPs`>hpJN zC%z2lgUo-sX1(y^i$w>gnM*)7s0%rTq^^(033y|_L-~s^=eH6~!1H5CCl}ee)Th157ZXkdjeE#6zN41%z+}RyMC^s`ro}5avTs>^B=jAk ze*6A?)KZ?_?pikDgqYZ(jb&Q02SZ%A!@2SF^z<(#p6jDyPgVyUsOuvF;Te$ynMdnB zJxY0OB(e4hKu)R_dzKua6#Fj>81#InagBo>b_k1}5A90+&U1*okSYoPf>Iq#qb)?C zqaocVm$KtwLDL=;SAM}}A|C;N)~W575%{0E{=38ZzQc2KdPsYT%C+H?MA2)-h&NVM z)epu(%vL5Rh(pcTZ{N7+Lqi~PT=7yW0lm)Xe$cBE%5Qc|qwm%Z@qvZTqG03I<>eR* zxe0xLF;(ug{kL}k4j8i#uvuaF;RKk^ll8Q4c(cmF6KFKn6bV0j%4dclZLnGoG0YB5 zc_cu|x2sj8w-VnLqCKE-j}}tGH8r#KT%dq`$3b%YYQF#a!hL>NUv8C&`_KdH*_rMt z4B!B8u=2NSj2;KY%^bP8x%Wq&zUCc(qs)4p*;W)-yuA2PnIOaFKd!8~Lm<17XrJ%> zHOQDJd}xgqsj@i;CnwryxmAMKKWa5L<~e;#|S%Qiom~i1a>y ze_u53&a)a)VgKbMlJdBet$sdd^3>g(W>iCDL|b=fNu&M`DOq#u4>TErhX*AYp43k~tJb7w)dD$A1sA@g>m}6{u6$evNRyHjh zyk;~GrD2hLx+F1J$>_n3fdT%LMCxj#%`HdT^#Su8`5Euu2ih$YY~-FG3bbRS>ed=o zf4tO-HNdE_U(d+Ql#%cEcPsu9DQ?_siKZ5wC^|%ddG}8@`-~^p#Ky)pcV-#4005RF zbzyD9qW@}aSA~P&)orWcGrij@-3b+A?G60QVGYZxS#s=TW!(H8dE;jo2PmoMKBbRV zm?PNS&|(5_ksZrxl8`P9c2B_fm2{BT^^j6*psM6Tz_jc6UhU{pM{atM*XGUl23Skv zV*vq?Z%e}lRPwzDW{V9FYCCz5gwwMhu6`mRr8ToHNK2yRxJ7?vjC4zu+$FO*(_^s+ z>LLmjiSmdP3R)NupnT?4a{t^S`rISWd~xt;H80UCD4%CI4=!&s^26mR3IH>QYzsjx;^_C=*{h z7t`s)zI?x;^_Q}g!iq63M;w2V=7lCI0fXf4lgwVgd-YiiEY5nB8L9n3!HN_EMx__F z3E4_aPfrGbbn0<;Z@*aeKDK_3sFG<70j6oOy$ZJu+@q@UB>7Y6InNm$vN}Uc>Zf+B z_E}bvkyO26#1P=-krQRp`V%{b?$RG=pl?Heoh1lBRzBno zBzyK6>oT;6MR()IC3qfEhu9EpeGVj9>*i<|9-Tf<65bjVvy6%IwDGc1_1@h)D?OD% zmm&#-N3Nk8sFq1%KKW%;s{dCf>?+(wNbOm2?eLI2%f|?FUyrxcJ?o( z>&4IrVo=Rnv~@}Us_TY^yP8NuVl!-JFo4jrowI$KRF6du_z%BC$$---zk_4kWi6Dw zdZ#5NG-xb5>V#}|`UU7xAm`3ra?M2u_s--phCKpmAa7G8X-_c5Q9s70_~fA#qB|?* zsBHe9$YdLcG;F;Lt;NkX=i7@Z@(bcSu!QUDa~xP2lNT;nei2n(Ti(QwiKM!rq*0_9 z8}?4S3qjW^7ry5R?Hnn)j4huss7j$*%t4Hbg);EpG5#jWs^B{MSS;J+rT@{tR|lJJw36xljxqq z6HTC??&jN>e$py|4Y6OeJ7#Rhu4<3>FLSO!p#nR3GvM?)y*xYw@lzlzC@Zim)gx>m z@`2t)!Z@<+m{qsroszjXPxgBjxsKG|_mMw_RmQEz$@3tlO52v%#j!Y-AfL%5vxBC* ztzxGt($i1Ghx<9)3!Fesn36D=w>V5}@Ob=?XRQ7wbeSB=Z>9UbN4mAl?!gQw>DE>K za;frZ-nH%H_LiXK=9n~%n3EpM9EkyiC2QY4-hEW2mh2=V4PSC%Dn;GMF>?Z1X#a{l zg6!?q#Dj~@J^2y$NQlTe|Buxe`s?3;Ng2}xaxxN{~WmVZ{7N7H>ZO8 z#51EZPp9fDBHN4(<)FO@71rR)*Rex93gi|rtdv1-WHJC)3Ry)UQ7w<*v)wjv4rc3@ z^WEofFFtJfjDNf`@52MMQ_}Ew?_qmNL1AHuXw`UXlo@xnpIpthvHJ{p@$2Boc!z_n zDA-s_jHQ{A^t+2YXoTXCu#?6ob(iB{mE99gbcl643^9TkgZly#j*)cJV%OE$2;_RR z&C~2%h6f4|F{%Wc?(N%35$>iUYkiWawI9Ni?ygB(ck}FcqFY!D#4EdGqMBJ}iTE7D z3|*@>?_DjQHmyRqQz<|{g@<5qxI5mnI3(6oC>Bpsm5YYA2hxvKGfSLep6O-jJU?49 zosAy&_U+qRnQrWj!LpALPt=f$U6za;8Z zyn{{6wlfC;nNPbr!0abTAU7So_rpMUbWyX8Jy>Seq@sHx!gvl=hQUvBf+Q zYkWw%9f@KJ>_#v18@?#+nneh_q-o1R9afv%qHL~l0E=Kl8oJEx=u@jgQ#5kIpoyI zy*T0x1%lo==`Rimfo-(uIGl`ECEm&6yBlh?+(pTd9r&Euwo}q_HHZR{XV7lEWXX>g zE)j3h3!{=Di`3fsP#*Tc(L&wrYaw`^<3h5s4-91AnG*&os>oGAyF%N;4S}!@B9=P8 zp=4(A_CN&XF0Slrxlh0+YW~8LUywLe0MrAa|Msq*mR8@Mj_D1pw%=?R=OcHII%Qa1O$MzH^prYjR#9bFO-=Da z`9xk&w{T;5(V(O-RnV$K*=y#~O?i)=g8S>*Hlkvp3|ZXrH;?pRXl$%(WVk&&-fe@@ zc~8toQDx*@RMT(s9~ANKlXR`>ZG1Qzr6HH>`~GWRUwp1TFsK<9sm%bXOzw8^1p;TN zK&bx58ZmC~7qy(H#Pmi`P|JQ}62B+CQGbAc11B6Soao!QQS$!wi*73R=#y1ls{{?aWYX9vPNA^HpolV`j*ThRiCA>!79RiM^`-B$|0Z0`FYt;d>UsE$1W+nXZApYZ7?6^X8;D(ckx zq0QcQ_#JIX4iJophypzb-My9{1Y+MT>6M*WM0GfT0p)XC-@vtbN+S zc6?`>q4%Nh;k=43_MW7a;V7*edZJh-glrU96n$+aK13+ zHdpvmqF-~_z|8B zB=nCLT4Z}`{NbP@S6N#x+1AEQepr1LI66ApSmLQ(vk|6g2}aq(`&cVvJ%XRcnw@=c z(t0B>aevT1Ngc*%vUwjALbRfeFfp+^3jE`tXCa+$GFw@QB0XV9K%5fdp|%wD-L}4vR}CRfL)m&F zMI8sq6;CX#tvXpFAlJ|imxA^o0K1lS59VX6r;rr&wQ;>$?ZkLFKQ35fMf_zv}gcmOyb@_=s8btrZvj4Fu|8?O2Xs$v$nv}1#RT5r!@d-sEkKdoIoUP|+ z0bN}*@<9cHOG(~C98G{`;p|VDuCa>s?(1C{kVLeLyzAzm7eh|>;&gZSA*K_&V*Sud zf^MK3eisC5>XmRJKVTN2=qznT8m&RnR>$h(;=E;~NdPrWwjZm^LH3tVNyhQBL5$S?L{wGdG%$`^ zNCPx#0i=89@WuRf6nv%ogX!9c0QFfenN`03j+zVBw2FuIm7pm$lx~>vW`;^V%!EvM z8-b@8dg_P7dx)cHI|NQa5Nj64n9*bmjT{bfSRvq0r*a18%GB1*Bro0oLM~V0dovba zIKgRZNL$W=9qMQ27MXu&%c&h*Pu@VHpiMX9q)A2jQ5$Kf4 zlkz9?k^0b~yfnkiOO0Rov$apVHsFimpky>H>bBGHZC3xadU^CA2}dU&i7 zEG?6Ls;zqr+x&!5L9{QoyVA+{CcGn3{4FpC<1u%RwmK7+Cdc%`A^c?}t##*DVhw#J zE<&V0+Y_^!1Sh%Aw2PjDkHpYLL3GwFiFoT>6c9~VL-sOsm%Z7(lZomzx@!f$o3J$2 zf7i4Iv5h2~&r&oUqG4&GO6sj;~+$J2&k7DOIuA>V0tFl6JbmXVrYkt-QIHYaiXkaDG`sQ=e2j zXJ_51oIuABI;Va)#9X-?wG~M#TE~HW%2j11{%{7&Mo6`fST8U1ozf8QfBcAFDfD%9 z6F+r(+zHiK@xGjlNi+y3Xg2|+xvS+Q5{IpfG?*)2fv?S3EcQ6$=){Su_FSX~q3lTG z7lGr+%U@g2AbTLoB(vIt#`)zy;#Mc2-P`vo9W(^hJM7BO2HRe1Y@|N4-c5gegqVsR zaFU)ORV}tFaj(sPmPG6`jX#C9pb)zPb}{XR7TOz}?RTjkV2e4J;KpYtbbd8dKn3+h zF6jG}B(gkh5%TiA-LrtQwB_J!@|T3tZwE7*Exq9s{PqogZqA>M@fSg7df+!#ej1$F zvo%!lTqG&;$G9rNXYBb!eoda*OmkcMR0z)c;i_~Dsew$Ot-!`cXk^TVGb^sCSy?T8 zl=<*DF%XV8@yU2OLX|WY=PZ@sc!O-~0`t<->q?=!54|lN59=?LElI?u(XCUS4)(OM zjqTx4QhW_Jb(Ss=tAT$-IQh}mLt)Y3lo7}U`6gSlhPx{Zqi1?2iAjSl<0N3|K57N7MtQYOvF}pl0#Ysaok_t z%=WJOV&8C2%`-6BnpI7f>LJ$JG=w5z0$Uy&uybL3?a=|1w&{^eWWBc1p~8 zSC{-xobXg70CbRw({i$&1n6|h3Gy{PRV)6&?%L!-Hr^6v!=HbqHd|zI z?E$CB-sT(EuSdJJDmDPuyD9Sn{)DlQOmUY}6h5s7G5Xzbmjtk_nR^U`D4>FgVLL57 zFe|@bFZ~;OeJrj;m{1}-6E>idRK-4dSw|;S5fr_*kk=Q3?75G>KC_$K|M`2zp1eAd zveL(a)iy2B`)-&P+demP-gRoGtFm9kvUd`g9avVm*Nd{iQyf%DSwXPN&l+{(Ck@pE$Q$TNw1h&#MhpC?iSd$2v*cLOi)ObACGV(e?G z5nBq^jBN*f8{0?m=@6m0qon#^7@X8QRNwfH7PyFE8~mGCbjT{g-vV?g1OFr}` zu`FU2kUcwlpL*h&k|2`Ks}E5ILL#i5`etU%YCafM#eO5e+g)aQdU^^i=MX#95Uc$b zHGF)0V|cHDL#@)k+Pu^Bzoof3@^{SeY!PUG_h-P_-OmCl_cqS#_`6SRzAtHlZf6@O z>@%E%~QcA4>q2wq0*K-!JC*XUijUe;>gm)ACFQt1$OoG=m7rY zZBbeS@H%2zTf@vt?;Oaj8Tz~w#_A_(-=}V6gn^!IE z%{>Ou>9oA}qHD_9XO@J+ir6n9MH3yv7=IE-OhRBIs@`?)+p1NLL6b_~c0SGKVduRB zMV(ev?SGq*-?7vaGcb_&9C?p-`=$r<&(e*Ka=iVz=e9)tnI!{*?^Wv76^xk`S>N3~ z<3(O4e&zU?(9C}T83?)C%AvXyqLTEEu2CsRAYyjbIk`DRRdr_z=W1SSQ$$vLBweElA#hw-Nhxs9=ZuJXa;7%K zstRNGsOHSEO!YEU+L_clVj*RqlM(TwQDXI2xM${jKV_tC_zDIqf zTFA?_X{o?#OZJK6ygSwC{BAgKoI?R>W_G5{-}#~4W=ruQ2NzdnCc28~xVNI^5=^>1 zL*$_uGQ$IqjM>1RgVPOXf1c@K-6R#~BTYY3(stoNDU8@94G4!^QstXBF9v;f)e3JK zmj1Tw^c~Z%(-fVz=oWyw3aS9dS2MNId;WojiU(B&ZK(Ze&x5u~i^CAQMm4CZsU?y4 zl(lVwg--UBPh#L^xu(y%ouV@qII&z5OSSI6Isf5~HE&?(njhWT%HLqem}>PWr>0n> zTG>^Qx6BxLHzf^UMc<>!P3N~Ss;W|qCi-#Cf}J|0L7NA#v9Yf<(pQ2$wBBjveuEIVtlVz{e-C2NTFcFCKY7EK z)sxE0X{bF!$8D;cNl87aU}qoB9t`;F6ko+3#1}7L1M1+bisTa076B3PV*g>1zh=T7 zrOj)&la8EK|6pT0n-^#I9Z4WhR;(TWMK$*n_WbxyFM$8O_miElx_-T#SEHi&?@5?z zJ9w!ao$h|qpN!*x7wkY@|IlURJNsuEbt@%qzVCAg*zR@xRGr^{@UI{F{nh_||1Z`* zSVG^_)TyztF?e8`@zHyq9`1dYo_=T_CFSMr6n3sJ*!fGdex+_wSFr{+Zp1!*-1xi) zP7M8DYWV&C=noD;*_l~dXMd7lhYQtxO6rMXYh{?Fm6f;I6IoYsy^Uf%Hu>|w7O&ag zU5QtG`}+0iT;n3o&<%$&90t6{w;w%UP0mh9Wf(#@B?MaUw_@`~ZRmA)75%#$ah2lJ zV|UvxbSk%uFaY;f9t575R&qUC>^r)PT&X$1*+6*D_Kd!+Drc<93XN&d@_C~>HB zW0RP+v2k2?foqL^ELW%8v2`W>FK~fQ&3vA;Qp6LAshY*`Icc}C%)z;jPW|=({3Fw+ zVdeM7w5m`CY#&IS-l>p~-!C0t#7~#@>!111@6uvA zz}vden_wUDTPzGEhPRdPHdwi^eGJ2_>Q4CtKc0k}JAj@aa2)S7?rJ?L$YmiXN~4r*;MlxcCzpPKsIP=gDF_ zI~i<}MsGHqYTX%k^q%_Zol7h#ZruxqbB$uEW ze__GHdtN2gt|qk=yz=i| zOcex@(=LI{ceAAZO}?@inNvy&t>amxR9(s5d$l1yg1h!^-}zW*P%03((se7Z)6#lX zR%b+|K|`u!^((B2hwRSpfP;>TFWT@mA$#bJl7We%<8!{`kgWYHJNsDPJxtv4*=oCs zp=f8*YEM_`jnw;16VPsY&ibLh@nrm@_<>hdzfG(WE-oCu!%vB){$x&HfSn*5m%DR|Rslb`p3^byQN6o1_i#oz;lj3nX8H}} zz!4r7wX03>C5zSBt4m8+A+t<4X59pa6hc+B5A=D|4toOTVHGLq@-s}7+YxbL- z7<{#V!&XyD;QcwevPQ?0a#Bo;`QV959UNAW?DTY2Iyq$}-RR0nwIWfxje$W#dZE#C z187wOBF&&kf-BW2%olv^Y|o2EpQm6d(_Chx1ehbKeiWS(u4S=7C9Q&m0!fYD_^Q~RmK zlLdH|!ut&~roB@m6QxQWmYDMn4h~m4YE)sR(2T5ru!}H5m+?MGc)Q=}Y*c$#YOmTY z!*O+Zn_PmNhOZok)l_Q%TcU_4?-!YqyJZ4hn!Ide zUC{}2yF+UG{+-Wc$83*&h5LDIR+uT~peh^LL7si2_#=<7_U`<~4BB*Owx*vBzd|m= z8^CYm#BFt}mUgl6Y5QPK=nrsMr6#IXK-SERCPA#t=B`S*fB#1%n{3+{zuEQi>a1{t z=m;WW*%{`*oHK8m;5hDqnWm;^zAqThIhH)#3Atb@Jj?Zlq`L|qQ6b|;64}$UE%9R6 ztlx7oc-WUTF;c51AFhZiPtau z79#3v8Y1ekpU`_gFY!``Gfh8+#wg>cj0~lqe%P#Un{2lgx@gJo@_V&+71y2EmP_8t zo%mTYZSc6h|3=IPxo2Xt>$G7+{m?WYAg=>p>W4GaVu^^x=4izx89BM&?X%8Bpd3Pu zw2FVidf@utw{Phk%_(o+9)8&9l&nWjz~j)8U7g~FBx#$LJ=PI|J^;7mZ18nFrYSNc zz&s<-=nw)}V5AWhCE39z?71ZIUX+fSg%`&X4teU+d=6(%f_%klBuZ;(og|wq>a~{N0^?<&X z^hVjq1{j4!Z9f%*s$m5!MR6nF3%S&!mKPN@AK49s^kQzu#tMau8+rV2?XqSwL|==z zBG=^;tU9K|6U{H)s8ZSCoZMiJMtzc%fR~>!6D*pcAAVt%3Wk(qjwJ zeJFlq&-fV70c-C8yrf~!VC ztIj-gNc}h)(*x$2i)qu1lBEORvKa(ZL_y=uBJ6OVd10bMI`I^?^1S-^8LQDoj-h+O zjvGufV#`x%_FcH29npU8I9z^GI(wq;^AX|&I>niR3bA6gU5PObK~=o2_*(HMFWllf zxo!T(urj1ouwRPRxn0_DyiSrR(XraT;$&Q7^QLp!>jXu2G>UPB+8O>hkbuoH=FukM zrj2K0_pSQ3dC02Pt-kN+DRH|vS8-5gf^rcz1bVmm>PS7>V(0w(r{LjJ&-SP7RMO!5 z$y(eN(8u)ZLCXnSt$>I|Gj4IFXNE5D0+HRWlZR|#-+p`;=N*|z;UzILh;S}zD zCIKOIrzn)ft6D0-^8Uu&;-+Y&SMXA~rshxcrB*TiqR+hNUkH8x1ubT0Y_uXJSf$>j z+3R&bqPO&7H z0Wy88wow6F$@!r1!T>1=v0SsNAr0}yNL8EJzLY^v?0^fVmy2g9{ym)joWoq;z>8D1 znqFFK)8xsQp`E?z!-{gY^4uyp-=(grr!risAm8^I4gczvK`9sA=*oTl2# zH}}SCJWt&h3pI=MDbhwwmC=nFxI^uef&{jyRav723R09gsY>$rR*Rls)6v??rIqf9 z)zgDN>=mc`Qb~I>9qr6@ohH}!f+b|lij#x;?mefHd){5NGH25M|6}hxqncW~wP6GU zO0|GUXKx#bfP(bCQBdh!N&rPVp$DXdP^=)}mL?rR=>((&LKl%v=mA1ggaCnrmIMNU zclkW$Iq$dCGsZXG-{%KoP{La4UiZ9bx#qm){4n*f0(Yyrzb;6H1FEtrZ8fcaIg{ct z^l_EvJn(syvXR#Fa^aUz5X92+DN3lCn(t<2cG(c1=b|+J@UAA{EAX{S0}*04+-#*glJXdcVpOIhE7bEWC|~oaTH{ z0OVIAuUhxUW-?#G$m4OpMIu0s+0A@tQ>fB1!7*nY56MCF8ke>)c4FiC)WTJ2Z+N|{ z9`Bju>!!3H=u9NSc$5%Fk87@tZ7!#oIDs9}o;8*uW;a{aQ+>@w;ULgH7Jr}fbHR3QuKT^o zRRjNw6ZG+1yMf-P{GxE$&u;bO)x5uNhhNI{H# zv7@J9#FUB~n)Gs^Q!m>hNFJw0%W!5m04sQ6RYP|Ty@kdm7t9&`K>0m#cDJLn{8uQxn>8rM5H2 zuRzLqpfx-umQU^pC7F=mG9+!*R+mYpD%iI$Oj%(g@qg7ybXj;^k`Law<4wrL7Nl9& z*I{it%jC@Ys~|wS4@(tQxO=5?;sK<4c2i41J|T{!7mFrIsJ+q8qOvA||8l?i|F%-bi& ztf}C83``9u#i(P!1aTfzIaHraSZ~oLC9}hD_(kmCBzbf7zo_@~8kL1p5hRQD_ z5%tr@IVYMtXRPwV4J|n9l)VlQgeSngU&i8fPUHl(y=88;_G0K%($DZtPa~6SgKc3@<5E) zM%AfGKKnt{hQ*}4H7KnJLFKpjUhN5aIG-AMpKH3%W9_ORu3rXSYQuvJ8kPbT*B@gC zEV4#;sDS~zH6xOk1{o}p8o#=%e{4Z7ptZfZDI{U)rFD+5GN?lAwPhPLOt?H!muBo$ z9^=9zov#*dtA(ol7M&qmYUjmSii@VsU`O0<8vfFa9)i$u1GrUxI!?735%qSpoA2mMJ0iw9=w?)%e1+Gu0 znnLPu5P)IvfDTD5)!-wX|6VY!!}Hnkz5Z(7sdLM`*>I^B;B@?XXenZOYN*PA&@Bwl zl!gm`+D$mtQe3WXNWvsVktcH;hWQx%*||QK_!Ya~VbGjzDx{*uYdqv{W8&4+^U46Y zek#XoCgJL8iIBQl&{pCG72kpze}X}-jlmtSd%5)-Le5OtnT@roX=iU_6Ko?|=Er+AG`=(UNt)gzWpp_m1tY}X zPI1j>q68P;f1@YO1jB^(Q*k8zQCY;Yl0}piV@SgD615Dp$9@(Orwt72kcRp&$oi{! z%+-pYKebpp7Fam&VV0bi>$gI`423UuvLy}%v)%962{VLofr->+lc6Re$8l3@Ugi2$ z)otjEi+wM@(qp%#CP|YdkL;47sRs(bz@7h!&N(fF_c9kd);U77|A{*OfDpI-%(*rQ z)FWYE3Qey%YmZZLSzt$VWm+QJuI=Bal!>(@hPlox*1~brIX-`cy)T#J+qiQeg{$7y zw=E56!oBYZ(x`Y{99LtB!)Uw^@Og{5#0NIF+nOW_N6IK_NYBYL=`~OcB2#v`489Q& zIbsuD)B>5VW_dP-ish3%eyk%*g#=0H-&*TApS~zN@-5Qc%ud4(v3x#B+~PJ*jM=F3 zQ5{z)k)E13sbFSgUkTh}RrErWSYDHAiJqLj`mq{oS+9VxPX?f~SLuehQe3C{_p`A` zh+bW7wZ2nWtN(hp$If9us%{C~2XK%A>Tr6g;b#6EqI452YSlK|VF6y^y^cn;4%{9^ z$1eVO6Y-3H*0JJHPKlW_NyV#I5-^itI@ySYyX$BV$;Vc6~kBk+<$B+7b#ljZ0!$5;6_xgNX?{7 zZA9T_0)lm-S)ws2%grV=vvMPTJ!5{@RTD};J_F)ly)sqs-^z6{Ff9KZb}jJltUxgf z<;)-3XkpkGX1cR)BoULf=-HayY*Kq`)^wg+proWY{(O^zZKF|0>t`AABkc;}deQpaL+DGZqf3Kc1%A+!@aPA~uwFdG?NTYlY zF15!u5kiMjY8C!#6A`T2%)$YkK*T`s7QO|eshd+j+O{^)7nvlPr>`p^b|(q6YpY>{ z1yWDd8vVy*KHQui>mEdy*$gHmcaljYJA)sY4ZJ>KYaMvJ<(lgt(4d$D4? zta*JMdm>@7?rhKQnoU_TMJC`Ia||3!0vuPXU7e^qJVCw5MDkfm>MC^vx=7%WGi-&F zBNYloUYj24DT;=x6%7rVEay?kc2su#u&Pf; zH)%EGE>`HSG~GS?bL(frl!t0+xfCrF@!%`9ZoS3;X-8QZXQPZ9HL2q+j0HwBDpl9A zDmTcyzKUR7tmnnB|1RV9!w~M$GZ6d4!|Z+&@(Tl#;ME2P=I$cd(wKF0l?x(+@SX8; z3m&g)=s$9L7duLH$xX{jy}O1!YryC)J9TX*tkx0aT`clKMk3s|aQ~J6A0?Kc60tir zZS7;SFY0qEKQUG(J=cIl$s}LBkA(y_!i3LTFfb2;vfTO9(kqmK$vpfR)8PUoZbi8% z3A6BwmUr}hNlEwH4#LzMSrRduB7@*#ql!nQ1$=)qEF|jkmpDB7K5=RTODZq{(MsYX zgYqn^ONvX{`#WPx3_|)4xkA_R$tzV=Rch(wEq!|Xn9#mU#NrRMwbj*EV72LO*&dc# zl=9TN%=&F^q^EpuaWUgS`woxvtH}9<=mtWyzSkLV4J<@9+%}4TI-M0D^zhJjm|SX) zdu6_Gx)bjXuj|$4C&KZXHcG28l{Ncq#bacuU*{-crrZZxz``0=LQLL^(mwE8A1~M+ zwLgoo<7OqUx(5M_vvirBEg=DZ@3rL{(zD}6;F%HaHLO~+<<7xi&3%}yVL164g!2-GFKJ;*4ytKVg0^L;5l!s zITq5vc|u@Vv4cJ`G=oO_tHnX&La3RUh z2bhn;THSwUl>Y+~sk;L0O6;s~QL{g#(uBjqxx6*rq}os1?|OBw*kg7@7EvbPxFmVs zo}sCD*enKIur`q?d!k{A5q8zZ4>us7p#t(~5Ox4fYWI4Rc_3mVd%)PdbRgc9E)%qt z1i#Le-C#h`O7S0KC!Y>Eo^@&;{3&2s>qRKo;nUczh>Q!>FQ#c3Uko)k27K zXO*5{ZDs6yg+sQsEqyYvC;BtIxcB>86VRSxJ>CPAT1x=VIUM5up67UuzJI`b_EQGf zZVhwx#q*q@gy<|8J~@x;Bl!k$K#G7hYM5(qM(w;qsJFoSWEGZwqGb+}{2aZ8P-`LE zqsKh5h7Kd3SPfCc==eCQ`;{s!d>?^`Xmy2LvuH8sP0miL?SFap$~l$r+4FYFkU(kM z6-KyAxCV;YsGI#a53%m^)qExL8N8cuAoJ!yS4Uu&ap%aj!7498W01ytXqsD)`oO)fhIhN_jKWhg?e{@OVB=%5|dw+7AxlXp>&>%sBhxkrhoRlr3x z44`2ywd>Sdj1lM|I&_(J?RyUZM($(0NMXujKi5T+^Icmu%3HADkq#(ztx0VM3-1_( zAk5+>S$7bHakG!+r8+s1Z_hzefN2kUmXml2VKTwjB(RTpS@MI_^!8GV=%*H^Z*dYhBk7V(4grE;0FhGg7 zZ95({!w~hkVF8o##$bb0Y@t!!FuB8VSKnIH>BEsZP5x|gx%a^n!1V25C>Zn?4T2O?3Q-cZ#hL}K2vF(cLIYN!Ll zInilpR_RYw!zyAcD^ebIgT;D)denB} zxW|-WDIzS;&vB5*8B$jFX1%Hn()rIai2qJ$zXB>;mbC}!a|`}+Q2&DhWNguA%DObv z*8V9!fV$!Eiauk63#3_Z?*wAbXFjKk(JF>ACkODva)lzDNUQIQi=-3D7ApQ5_NUa# z>z{pjc1TD4@wFgJcazsYJqC6e>iZhBz(*tC{)rRA(c0Bcj(K zFWUfxx7X&bSgsw%A6Ft<>KLpOE+vEKHTL#<$|i4S6rRnJX0FD$Q<5`Er3R09GK7J7 z)~Nm@DcWcb$RhEhno#H36dHpA&Z^M)btc_TQeXvX>I+(xAJWd2{6d1b%G+gJdTqB| zfdiF%^F%w_=RxRuI&()|3m{kIaqm*NE$s*RKROnBl5ld5iqpiK?bz_EHNS&j?mb$y z^@O;dWGry|YCJyUohSC{jmLlcZ;Zh>}hKk_wo@OqO%qOa`IdT?K-6G0uy^5vw z%Qnd$Wy5EaV4_mD;;Sq_0GogI2L@!u>oMOL*=4igK>vN8IDN#z=nF3_JbVR0X8w&-AB;(H@KamW z>FvuVY;J}_)_ldqB@P@K7)Y`Gotk%HgCXVr$D$e@yLYap1A1dV< zhSwnYWHww?JL8=OtQa9VfmgZ3kg17msTu*3?;8Ad~B-#=2f#tiE}AqW@KKw&OrDmK^1%Ub&mlu_{Rt@ z=1Nt+N#ClSSJM5t9Xg+=srq#q49v59A-?LL|IX7sBdZqd+gw?Bm9;Vud&!i4>D9pV zUQK=M~roxD#(!{ma~fP`T<*u1rkb zyd{WROf%5N=$U_@-E!F}=Gizgz=vQ%M`e!%ZGP);n%t`D+o~FnU3kcty$m?RlmiO+F}RVGA=F zlAdm1eCF3*2iw`%LEX*MPpVW&Sgu*K!UQg&$o*gQuemF-vYg6&Q-;TQZoN7LneYxke`m4@==$A)DyFC zerxr2ErOezzfbr~&REdqN@!j`#8GWY>2@z}()}-((Gck@_i{EOKB{blt_eg|9Q8BZ z&-+Di{$(E2H$lcNQ8l};ykCjr-f1UAVh-MEGC>Ay;aU$;YQP#DW#VP|$a2i9B0dL( z%udG1A_0StkaV_W9rinc_~%n%+O&G`gEc#_KF(e4}% z5SlPk)d`RlOXq_V!n4GSq6ruPSWUYfbB@XE=KTUs-OM2@^N#rwH@?SZZAuahNcwpW z>?<6C-$m6vKbzksFK32EW;=&+YVfEyaKRR=NIN~j{4MkyUrVfH(6yOwq~_#o#KoOe zfPbl{?PUi`KmbsE2Lmez>1#oo!YKr>R+RfQt6I;MmI0{RiZXsOFXSG26ET2j)y5e_ zY!CdkKkRpVauIAq*EsO}p0l&_?l?12m0*(9a}Oc);M?&kciez|uslY0Fq{@YkPtE; zW^&{b!h!F#(d`^s8iA*04}npvunm+c1ZtTN7{4>4Of&&a%o-5Wt2 z%5QzJukj)E68R3(j&^e;$&Y?}q01glYY=g^leo zZ>a|sCBADrR&@*gYD1|b42f6BL!Nd~kBz3s0SJ@w{RGRh^6LGurovnz5kZjf+xR}; zQ_7nw^?N|S>>!s;1O)#e#;j#p@s^J>2PGi}^KY% zhJ|54B=xdE?UhHu#{wsMYRjx&(L3pUWW_a#hEH?YTX=uSjLJGzV;6zAd!BXem|Lm`KPl@Xh%oNU9sn5fE?20H3jTj{C5?PDPX19rL* zTFEP1Ky?y;t3~y@sXWf{x=a%)9mrB?faGi~UpG{h@V1GH-LV-W@mR=Wafn&g91`>W zEZ4a|zj0^6Gc`fCQrw1A>bu#W45dHJ_0lsu3M5YPuxTdW4%#yhATHJN zDl{6RJ1f_9@xJ|09xi$yB@F&TjB0C|)5xd1G$rrJF#jVNjJ*3v3Wj#Kf6Z915|~*> z5`PVKWF#lAN9WfR}FL8<{V`vKAn>c`3<`E5JZidl|2u# z4xAJwo8CU=%}j68;H2l#>Q|A;Jqp-nz8WsXR+N2>VMH!-WelT<|PU)bTS$AHdK>Y{A7mh3e}y8 zv3q3pmkHsZ9{nUKK&!K{n^&dE_o=0OxlE86&`Az9i>Qs#w$cmg*f_GZoIJpkh7E|Y zJl^5oqYVYkq8wu;YoYGLFdSn|VKe=LwCI+a=bTecuKg5HP1)uzf#6ZmmV->4Kfccx z`-O)4{_<{M*v>_t4z&W$N&9S|^+FuXY1Oh6X|qh_6Jgl*?e+JR^}H{nSieX$6|O=s z9ZiwSFC5h!EQaxUDwgu;@04#kkJNsJsvxrB0-wY3I(oPam@sLPh1p=zD@#&ekMLvL z5FMEpt)v@c&J&&9xh?r>e3*iYCQcZdvh5&0x2G{@AeaNsup*$fX6?%G^&uKcCW}A<{Ku~h7s0H&8>ShY8 z5y*);ySUT3d=1H666oc7ARY4*5gJ(b4gBzv2X3TU#RlybQbgy5ft|LrG*d^Pf6g zg|ZWEOzRVUD_mS$8Wr9)gVXkq&t(=3J^W(aAfDoQs&Z0H<$e5H$0B!wxFZRTI&M6}dwHmL#2XcJfflvgZ#&_SO-<;xAY&{-EH zg{rDW;x8}(Xu;c+$Nnm$sr}q`RrK>MSU&D!G@<03N4aVp(X8fONZu*5#mw`L;B$}s z;tG{~LDSg8IDX#qbxOYR&$504=IsGtWXhKV;&YY%tCjxyJIynOmu+aA4I;|{A`!^; zmB4otp5r0~-K&`^ACIq3wAR^h*OcV!)vgc9BkfE;txi*F zAUE~`R-Emqfvkd-_)dbkmlP# z)te&4gA94YP-q?I)j-G}k-j4WQ8v%_4-ENMX34KTk2<-7z422nu!j z^yH<6tgp<__;{L>4lEj6aXzAv#bq!PF{v2RbQQb%?UGL4&;@P1k|x^_R7fQ2a&XjB zsmKzM92C%Fh)DZQE2sZ}J0C6prM4>>EWy9wSNvGC&;_Tjcko?vQVv z@3t9Kn=qHop&WJmZ)~4Pe9{WgX!{QKSag$`p7jD1-kJ^$8)w&ToSh2*iwYZ>J9lcG zd;5P_JRSWWzz$MvX|9g@53KaxlJc*A2|BgBzH&0kcHd)O?vfnP<$(VNT7^=Ydc)xv zkF-;1Q7QlKl}DfnA+@mS9~EW*mZ~PF^q%YZmazA?&nK&bNq$bNqpnV&no&dcr+ySU zzZyr@)TYfe1U^NdMrIlOzP4PQF2ckv$HPX`WUdJQmj91m+&k9W_Mr=(?WI9!|L)SO zuNF~RDP;mSaR^=ue@Z|gMmWMRs5%~ZTZ5L)2RUXI{8&{%nmPmm@xG(YE|cx{{LAJ) zSNiYeo<4s^C^2QpmGgJP^y7E-@0msB>!LJFFOYVIybN;k^4ilK&iqfGp7%c|qL#^# z_6o6f4G1=4B#KB!3Jcse^dPPo9F*|n={6LFr>x{vZMar9zb6RKpzdV{rdm@ zrH117^77LI6x0BGmjcoXZvJNocC%Zj{J_cAbOBX`98^m;4Lo?uws!-^}(yZxdvTU~+9P&8K< zRpIf^HydUFxRD^Pt72j!7LUaLDTnGq0GrA4Hl9vN>(_j{)@xwp7nUClnf-i8X7Rzv z$L#B7$}0{sme zd#%4fKetVc{&ODS2+ny>foi(n?A+^A;AvA8j9C7$4ZtxRF`xguNuHlbikJntWYnJL zm;c8*Fr=raV*6;Yr9&sN2+twV&uazF%dH>m%0KnbX8!CB=RBtGc{DLQ&g}CwT_OA*`^K2pil#|EPU)EEQpzhpxGLLnqCQs|RC3{0d zgTWR0IIe%JO{6$HMC`4qSz-`CX8did?@EAcq^czOi@11CF^kCOA(5CLq}1a>V)%C~ zxfoxX;ZFkRdu2Xykwi&JH^=uV8*GFUGF*S9z3NN;IA7)4{X;*Wuj|*2fn0vbUg~m5 ziTfvyop!gx*q@|b>df-m+6gH%g}n2~H2dC9XYXG>cGEj9@TO7Ua990?{BTF|2T7P3 zwOsNlpXTvm1^J7FU#4%vHhWYwGD?X(&T8G$9WDF~E95=5Fas=DX#D3Tgaf7(1F-)%}-b+%p7xg)_>c z{=aV2Z=d()OZ@Ns|M&g>ul)V?{6+l1@=9pVzNdHZO8OrROZM$QNN!V8Q~cGp&H{=` z{qVTfr>baT^-*@yet1G|7gpZ((d%mpOs6$8G}_b+kArUCaA1FX1Gk`$4ndDdXDT?W z_zmQSpLnry>eic+rnh_(FTVL+R*>u#99-b+?BvXSKMb1v&JRjLHk5>*;bz=3dsmzR z>twHUuB-M?(j@;?k$Dp}In*VQ?H^|0$C1AGLVfa#FF!xyKkU&Dr=9bi`iN7%hhZR3 zmHi>mxPGxGF{BvW5LaYeQ*2rP@Tp~meOM3F@~w!sOG|tIEEtsr#gC`*l^+#YRyoC5 zKggDt(Vf%W2P)TT3u*Rwb$e~hceV5dyq`^eB{D$Syn!J$>%i^;Ow_m#L)MQjjt~uUd=6x>N8b)?9ErB!)+>GEPci-3@5$~%(n0K z#)~_X(qxcwDRwelT+0ta)cUF^9ZR}we6muDVy4$)xW%P_=9_HM#?7HYBNavtaw-cc zD@$m#Bi7_ge6G{)Uy54SW>{8xzq4!(wX8IIn-bBQeBaBH4Qe(mEzUqaQ{y%bOPo6zSHzpWA?YaN0%nQdU}YI+~; zCG~a1KTH2A#4bLY>D3kz6LLkrpo?jT;6TO?jT{{A6PNP&5G=CYwTBk%6)m=~vXD-G z8Q&*7vfpXK=&}bF(_8v$pDpCR`q|hengW(oXEk-P?q^lq^|yMF@rOPI21)OFn7scB z9)*XGdom1^_e@QYwkq7paEbu(gH6iQm-I?VcbrqAxb^r=$oRBwIyEX?!mc@EC}{A& zJ33v+_KKoy8@UwGSW6Nd=d!uR^kG=`)O10>dLT5^){7|anX%V>s9lNphz z*yuDG)dZn?3q$L-T#3c^lCI{PmrXg%P@zuaeW|Wq7H_#&q=tRr0*Nuxc26h0YO(B% z^M6u6(Ra^Yd7EPUSfWcS)>dDBg;NfO1|!q=wwFM?Z(=h-W}g!3RFBrqZqF)tU9o-| z^hZP_qF?;u?DUz{;z&YyowL=8uyo$ohB&FrmP_vzQSAL@U<|%>Hs1uN;!ret!u9JX z&{9+zF;%GfNMbJduqp7fwouyFc4qeKxRQo#NB-2ILLUc{T3yR3m!ZF^{)|WG{!>O`1USc+FW zye`DfXKd3k<3#ow7A>e()Yd%nixxSbFahED^JfA65zVFR&6oH%#D=}^zjED+VB@zP zi}7lvufRd9)HU8N_9RKWkC)Eo3&`(Af@+_kqMfbUaDU50o2#qzA1$P{TwZ%`RkP|u z(a+Q^X9#Y{s@fL{jNJc*20E0T9q)YxpH7$ z`gU@&W05-xc%8!^M=KGlE3ygi>D(66R{}um7qDB)s{K2*;)T~%B+3C*Iv_ASiA1dH zmZ#WEbEF5~uua#$!P2B(vpOb?B0?p{3XR%5P5xMbar=7}^bBH#ipE6=jwm&=@<(a@ zk}HDf%O8rpD!U~;`2^ClPAWQgBrz}KLZqAQ7UFt^8nR?k-|G@T=x(u>r>}1-rf+eL zRf&Wur#pmBR(^2$uHD}6Uf#&L)~tsGM{as(MVAoFXG)y)BocTzO%cYI7OqvnRPnZD zXR6fTN3L)04pW2YdTKpm31ZynZI`UHfh7T1OVzL}O3!lz5Ui+&7RHs_?d=mYwBX}r*Wvd?mX(h` z)^C%o&nB-=1Yhy%aV=;FLe2yySl0R%tpv43UU{+Tc7tBV;W&4M=KWCEx>JK)n z&OAez5AZyWNDst8kZG56&NXc6BE&MWVb6tJYv)uY>&!7@2SM9?-@DKDzxXP2c}-Gz zsH`FGV?mK=k@5AAy-G&_IV|sIikf3vl5v}!_@TE?YN$D9zz{=WoSy?{)DS1f$L`23 z8V$w}8rTH_IS5KKB?~RQ?m#2^vL^>DX%j7&V@^j|Ovm>`27$>#&6AM)kga!21f8zG zFt>n#XL?c3Vr^b0$GNv1>@77An`cMzuJGr%W0KkF8vRoMlW;PVaRp63#rrClYGxEb57@Pf7EFpYqT~aKx5pf=XrMc z-0^GQ^}NLI+xDjh}D zZ+RTsW7;T+fB7>8e>f5su=V-m(mHbX#MWKP;nn3-^YbazUZ^(yfX_x+LA&;WD%`4q z3ZFu6hTb)5Rf^40woBgwIg9KtC^&}g2jWKk+q^mG=rqj@;ryz*AM{kSZQIZP0 zv)&Jr55a~Ky;C_aj-d91Ff;Z*)$g`pkq(C7M1-MGo1H>IT?bpe{&EPozaCjR2kAQL z%VbhxW!r9|lI{h4h+PQk54X6oC$)T-s^*0V8k4;?sH9VwxU#)R zA99EvDvW>M;mUaJdix9{k>a~Zv@n=LTe*sc|way``(EHEpQ9{8{Y#uBnF z;5c{86tlO3_0s9Xmp6aAvdxw-cC=zk32UOv!j$IbE+`tn*5P;1*P}(#?b>ffe$28=5(tj~q?M^TzlP&|nEO(>rC^g%xfQ&KL2ozznN8uT@4WG*(?Aj=sa zy-%zcyU!^*un6N>3qSoc5*2+%xXP11y71Jam|ra3B|G(FCoE_r-jUz}S&fSHII9R0 z2`_g&#deeXEW1DXPi9tjrcJkI`d5LoA2N9!A3og+rZXod^q909bIw|bY?l$#V?eib ztu@%i1AWy&4@4?(-%Xg_3aW(Mmg|-)3ugnxT|EL%)#%(u1nH&A`t@?opJu-^8hy28 z-00LZz)|AlM+B+14)u%!;|~qPs$|h{Elf`O(Z}+gm;)QW&C~WZ63bZmPXA_VGCCpW-Ps=!+cY*kod>Rwrwi| zj02LepSCSgC%|Aj8oDRz=m-4g@WF{Kk(^2XGu1Oe z+}!qpWpK{pA&0k9(w6$IFDB*%lXz>74cii?Oe;dO z%4}z$##@7xS-YYv*QZb;l@eSbN0!B;sdI_MnDn)T_w$AVaQVl!*pdUK8drA&zdy9u z5BtG7(2rb?Ye3D~u}o<#8s%&+TF_*i?Fd~Zu^P$L=&i4H+ihJr{!}DM_3tB@u#B_-PT@#z72bm&x3@GB1 z^BBcbFU~A*7wRL4hF{$+C(VAD4?w8r@f!Okd0a9R zbsKMbf!=iM7K_H{Z^3AclE3_(GG5Nb9wKoUXmlUEs%J-hhANl7o2rbK4hnd*&7NL7 zojN+EDrD)rtzWuMYE+{2Rh^B*$=Km=uc`)a0AX}MWn$@}0R=_Dn^hCnzP`tQ5@>p({V-e|s!fV(O|CDEX{+6`v9PPV)601-ZOmKR00Qc3wX$3_V-);dx?Yo$ZiG~bw^m0hoyOS!P z#qJnuEZ(0?{1s-s_Q|OfmVay1Fj9k zdtnyPZ4tdxL&Xtw~@(Bk2n9!6TAheoAOq_OR#t9Dj(5rH)AG;$mdE0FLLGN*%LbgEbB@OrtI&) zU#ZdL`^oR+hXo9jLe@o2T${!>_bNxhzahj(r$WD2;!xWN+eRjAmRU=t)Z{2qrI@U+ zY>&yK3T7%c_=W=c5#MP$?Mk#WGaz)?nb$1H&TlASy0-BRFrO7j1M>#$txAsBLhJ@m!dLiiT^}uy| z_T`z*ByH#p;7mTN?Fqd(<357BCI*@=wwUfddu3`<4IDK3TD`M4i;}%ZObCNw3^m%e z?@3`~RD8Z+wAgwSp@cPFVG#pR#4M~6{w56k2cr38z!{#PezKqdrQ=BiZV{AMd@Vav zS!%+V6q99nkL6sS9I=s<-@tv-pe>u3a|hj@+H#l{Ai%jMES1a14=65xn5)s$kGK4w zPH~7+nayMZ9dJ~Q!w)`Qt;8K9P|rj~YC`Rn-RY@4PZ9O&?qdNMB=5$`%!i|oS0>6G zr}0vQu%QNYo2L!5sSjRFF@|ABYJ;DRTb$hyeCGppc&c}3nM~ML#BMoKuSF|K0BFo! zlEiDvd;s4HG0j$0@g()j+8z7OENm8y_feVoXw>NNouuUc2EKKIRA?@R%?lVYmG2A8#F{BSdPMyc@ z@23RJ;m6Br*n$=78AEzZnso8OBYP%S*S0NHQt)Ez<&8U$Lm}n7ErlBI2ud=7rpA_| zdCkKbFb*i?Z-nDmx#lb!-Oq897ku|_fL+|)Cs@;6N=X)5j|H@E{it5SmD4WbY+{W-+m>+!Z_VzHeumukURx;aVv<71~BD>PJ zJD66z&O(S;_Wmfb;zE=IMn=9{l>+5hQ5*>=s#TacT<0acobgKUu8^PY-#NJI-iu)T z9$Y>+XL^`gd%2t2TuK!Fc*bTn1NDfB+cr)xdf-4D zV%N1bMwsuIwoVGc4^DgJ<*X?lH8iqEB#P6$*as=f%I9kg%uh3YNO zg&HN7ff<2@^HBzpO&d0+gm-!+NBSM&m0g0@=6XSM9!RhwFp^fP#clW<{ko|>XtKCq zkV|ZfzJ(MNatY)nLRXlnqAH|b?mD;sE)MSZ0T^94B(gD8V4xN6%f`;>|9(EtmWj+B zsp03NdJy)8jq7;P{DzBheAhiO3&c&1>5vqb*5Mt@LW>kI>TpFzqNN8^u^e*@t+ro% zuHF`IUE7BbGL1+wP$s`fFNdolV?j<6+og181RP{V38+;_)OV;SR7H(C$e^L#f|$!L zBRN_ec915Dgni%~E=MpAhf|k8HLBioDs3_aUyh?x8ENZ82@w|n6VCX13zNbT`Z}|A ztZwP4N$sLhYv~($O`$r9r*pY07|*Q)QN7_A1GtJr}H#?6SbE*B4|72ypi0Ynh>z zazzo%FA=x`+KoL|HRbnn4>Sx0j$m7x^OheLS1s*kr^uN=l(%ZxZ_@t0cde;lbevJN zSb1{VP9iGy==&GPXVRoS{j8fq;3#c=Xtkf&h5AQXVK6n;lts&smJ);!wV%;`RnQ3i zotbPFHdbsAh(oxIxk=RB#}~cJ^lBtkv9XR5fq-qk)_n#A)u&&s$=1!nOeRZ?IRD+l zr57w~^RUI&=!2V?MT+XyAdQgr5`nBQAjw>mdA%iipiADC;&HMHEVs?1G?#?jCH`5w zos0Hv;@~7b!w`y}DIrn1&QABKeBZN2;`DV+MLGaR8K`{n4>}UTD zqMm2(yI8~s2Q*8zbw&)XYW6EV%0)kRVrpOIxZi7GG^O~=)jJF^6rcLOMtnWc1DNm9yc zl*io5z$&=p-WPQCtHTMIhor?3QspWoiNInMW~=AerKrY(LX ztb#ZhH68Mj*RmwSzw*6ecZ=L|)=1S}8r%jKHzGGh#`dSnVPsav8p;m|8+X~j={Mb% zZ19uMOrGBDAbI8oy3@wX?Qqd052^=5`+S}t`#WGf1Mxn;#BIjH#G@w39+lU>PNfjG z2Zaiwf{#oLo#aI~^di<)PY+%p9j+zNa{``Lhw8j-(~HYGtKG(JcZaGUb$_!@CU(!F z4JF?*KQRspO{G;n(gaQH!3vpfWrun-YpQkOVY1VjFc!WS_$Xw7Zq}NdDEaI5yZN9N zKM?=G?jpC`WX=OkHSG6qp~q7%@fe+YcvE!uuEyhgt8F$-DbEtK~b#Dw3%Ji08JzE$X~C&aI|mB$eUJb+zhR2%4c-X2t%N0AAid-IcQ{s|@@_bh(S ziglCADp^zrGq3)6HPsVY6#Uim<8yOg%g=F=X!Dfp-gm5HcQo%py=Q`hnkc}%2f>)P zys5jRxsJ9o#gd^458(ipb8`B6^J zHh_cHLpl4>^_g)z>{%4-)e5lP*&&iD>3JigO8sNiUJMg@A4aVLu>R{UH#N}7TfY|P~^PTT1-mCx7T}M*e_SeNjcl+kHXuEuh{@C_cV7omU zn=BGdI}49JsCD&gN_VuLjjZh*gINxS-T%1`MjdgyXX)yNt>3g$Ha;1;Ia!cj&lYVl zUl&X>RnMnC*Nlt^Vg75-U%p7rHXA^OFRG}eH2@8`kM#Jmg{sVy_|E(i`WeO;XlBd@qL zl&fk*bg#CVw><(}mbFTg*XhLA8xlvkY2~&jU<^-|Rh{~&W8}i=K7r>0DfG&KG0xrJ z9ATa?4azOr{1WcpKUc18P=)_uOKZo=c)sC2xZf1a76>USMGYk0Y;Gmzr(G+e1cQ>C z5`Z{l&IDP?m<4~(TU{zM6K%6P-54E|53e){6#eKfCZAp$%CT>nNQs)$He#i5 zOONKQb)?un_*bH-)_neBFx4WHOJ6VTJD5Z9@DaxUF&GrC&6odq2K#mW+ZQv+O_#yJ z>M0-XJiM=xb%A-Mh8vgIha*x{U1L?IP@qt8r^BVB$t$rXw#LKTmn@A1KKSM2G&$X9 zy4E@Kyn9PW)}RTypH&M7d_S4dyR}(MqRSOyab>ZQ9wn1fqQX`Y5y4rDR~LJ3$DYX* zJpetabnLmsjZ0@waWvP>K@#9IeBE!F!$$&e0b~}|vW&k8CCuYGOZB>`s^zq1X;C|g ztlL*IeXYDXlsA{#wVG~uo$O}n(eBNq=*zr*F>XCXlEqZRk>E!8at!&=|6%Vv!ruGM925mU6eP&npPpix^C9Db?%u=`AIxnnj<}+uVG!02=0f|8gNX zb4kTRYi3|oe_>(v>0@y(CuX(D?Er4c@)*U7Emxfa1qpMo#C4>RE+G_1P3roYUoVu* zZ`cBeGjFVUKcQFa(4BNaPfdDd&!n!&v8(Y@6*9|;8beU`M`$)z(N2Be7+#4bhwD<4 z;9D}5GiOA0>k!Ugd?uo2688ZAG)0Yz{dbxo>_3RSu)4WFb)l6!aecFHf`#pB6}~8D zO9%*BVI7Hn)jIyvd&T`(S}d>}ZdDA|yCW_)w1KR*a7uj0op2%#J`AC>6BVytI#Oku z^>qCM2xG@l|KwExEcEmGt@@&ZO*5rpo%?LvTl+q(H!RIsz#g(d`Q|=oJ`^H)H3azY zUn{-0G?y4gTdFClxZLXuBpZm4;`l>7NJ|iVlmFss`a+ z=yAyd)P8oBXQkA{O~u9w#mzH&mi$&i4J~xEY4P)G?|8Yncoj=&UgO>J=J=abRm}P? zW2v$T&P6e_DGkAoTNafiv2mS9_8~79wSkhIsYC+9HhEzTANE#jt0$=lXtDc6aQoGIjr>eVw3b%9s_?iFvyBxccd*PmUMNgYe zfPdHjHVGcKOZwwEK?2v;2wm7;3E3LchYyz8@<2J?-N||tqKIPR8*JBKosj&5te<5| zMX!DK(+w(ma)u28ow zt8Qg;$Zq6IFr3iDvUS>{9|wmnjVvvkFv?Wy;T8{7!wZcYRukwn4zwWaQ^N|JXPFs* z>lm`dR>yFLu7-neLe#f+K7a8M?O5iCPJJqWOFWgAwZz>_%@tu&_xZAg)j-aJ;-;dJ zDhkJzHl@ocWVoUcFHsc}qRm{3@6lDDVHek6ln^5e@<;UnxaIivHpK{9Vf@9TeL8aG z6Gd5GRN0D*RWC#sv%U5x!QY3x#38z>w%>ooJ{vDnjQ$4EC=?HZ2`G5EeYS(5M7+Gg z==JadcMEao@O5G%keGB?Zt%usRt7yn3t5wY3KaYZ1hQ<&y?M9O0PD_Y_;L+02d>~L z=Mh4k;b%x5d$yBm7#Mc0B)R!(Fu&bt);LMq%``eG&AY<}*W~n+`+(*0Xo@Q=P0K47 zo@kh(v-(=r;A1%XsX5^qch%G#szC7mm-F&NFWbe3w@nRI#>}b%kP9t3!u8{7Qt_oh zK>C%nnX;PUhW?%{jOX)bZjsSx`(4v#B9`Ml)8-p5H-AgA0`YcJt`iCk$JRoY2df)C zxr?wm5b@nuiTn}7{9JII@67E!!UT#$JOtHvD&(@+*p(kz7jj}=LS=I#He^SAb#A9@ z(&=0ati9fFYk)4K5U79cxBllQ|$fAh*U8lctcGrKIkr}%<0SD zZJ({6CuZ0z=7>qf>a1_30PVz@7YII>?^=pK#Tmb*@YRZN*x#y9IK@>E5M+0OTriwK z%{u}4cFFRg9$4YkLmuyOwmV^CVwN=LGMm;tM1A%#x8J^K z_-nA~ogQN<@*C$(KX7Eh1L-{T@P>hp7oVf=kqMyJRObMrZ6+nciy z=~*f@_Ojam*5T<8{x; zpzql7i$C6wj8ErX%+Ji_^GWrxavf^YgQd!OzrFgz4x1hF)57tsKRMFoeSvPgOEYAl zz0jd@w)0E8(kUL5!U8{#MwF~2W1`PU!;q4b=6rXQ7I|PIbfm~2Ep-0}Xv#AnvmmH1 zdGFK12K#)W9_j}v*SUh+tgFXT3 zz*79|15vb5aG*%N2+GAV<%WvTekEH6_Mywfbyl38yPQY7nVE-T zy6-@gu3?nL*gD47$YEln6=;x1N!FxpK46DrCmt#!0}&5wiFUdN1W2W zHh+N#KW|t@tbeeRY7w^vGI>eFiR&4@cD zYM4q$w1GMP@B0~(Dc6T&DRi*2xigKKy0vNT1LSZ$LTeByYvhh|g6O-m2k_UqWh*a? zO9~2JcgJDvf-j7ZNA7qdJyv6JE_#m@Oi#TpHY-j2lw3qo@qFVJe2(Van<2Zq1~2^g zqvvf|gWrkmfepQv-p_XV{DtQ=05Ia6u3guq}I6Hkjnl$*+F5&|k(vIA4#9&L=y@VJunMqON-P z^mf8zT}{bzH-ptz`R-32uA?Kk7O{?D{M~%EHKqjQsGQGN6CI9MpPkj}nID@&HL^8F z0+%SLV-tj#`-(W|fMyY3)yA(YmS#b05t|oo-PP4XFMPbKyC1O`p{01?G3E0sDOt-S z^&>WcGg-^OSDv}bcSMp_S$QEYA{H{SvV%M#%{h8loNYj8l-9jmveu$-;%*BscX>~p z#TOPaYJ?pslpacdhWQwxWGK$(^xjaob?^|#v91jEZpkP{(@f(+QHv8bH1(2sWjN|r zhV*W3lQE3ZUpLPGG%zeT@`+R_Ych15~{<1ZMpcf(o& z#%pv?*-JeSF+-ZfPzmvrw~O^g6{%@6%o77&-?sb=tHF*J?l3e#{1-fmL1Cs}_Q_Qo z6t@Kn1&yCol_0KkQoUvcFKTm<1ck)iMYBBb$mJW`4UZ;m;mfKA+#$%)bKSIyP0T7#6?~ozh)r4{48em04rbm)!^Q* z6N-E{va^iX1b^j(`EMXR6Wp+6jv;Gv^WXVI>+PX--ftHUVL80c`!Z1iu#4;7!Ia8W2Yr!qD+YG!Cdk$99H`m1Pne| z_*SIO&Vx_YcjswRt#7OOmU�Yo=Ovr>PH_EEqXkMgC0$GWRkofWyw`BUh89Fz0Ji zpNfzy^E;v*ikIy^oliFFeiQO+AW+@eS{N=Cm#s=IZ`1s;$($!BwVDx;PUx~Pl@fipyS4O)Hb{dP43#Tqi72jDx|q|GuKuF zP`F7XtoHp9qe{tUD%RoW^TrVC_L+QQd&b$VnSF96*SMFQ=FugT>HbE)8QAq=33JN} zS#)1qw=O{idjSZ0RnN4qTk)z{$X(nZ$Hz4cS11xkDf)T0rpxE#C+9y8223_iedj=L zdCei$vvOmqKY5nktFpB%*pwVbXtQ%)j!$szOqKJh#+&=c29W7jomcZWX<4Y~p?$Lq zeLkG#b!%Rv|#kDpJWUdH5t`uH;eQDN}*3oVw5jLRVa1cVjTrmONLneP?g5@93XWv;mKngH0-DAz>q ztb0HV$?uJ)G;zFd;NXVpR?uB#OpQKC&sL9FOJeuy5ld=d#)&?AF}xd;%bTK!4-=BC zSZqDH%P9lO1R|Om>-;*;@{ExqT=_czH z!k=4GArkuI1F0a>iBI!qU(LAw6}N+Lyf*Rd9ntOi69Yb*BkUgvqaVS}8ElNic_n^0 zP{_MhFrg_TdQ$QSfIQUO;CzzEH$Xo~R!~-NV^=7C`!wPkuQ3#WRpr2I_l;YEpcfo= z9C9^W)q>r4lETE5%FEBVAC8<=aPMrBK;zlU5n=d5PH{1K}AIF6HmsP^RotWZD;4!b}^?7N%-u{HmB1!6gL)7STPe!); zm2}>1xL+2#(SV0fIqE^V*O+or63>WPMoIlhfyT~VXW>S&m)}S34y-bSXNdrX)`={r zQ^O%pyXxx+T2#aV{D8_QbQz;kn_xB*cg|D6YcYwW^Z`6IrH8mx7|$2V&-fgP$;oo> zLnO@`BSn7s*pgYM&2Ghl*}CCTv|-o$uA7qYB2Ghcqz6(IM*ZD;Jv5kW09?PpyTKU- zUHz!E{i6}_xDd~&(Y{?dLO9iR3Ag3$R~ywXBn)#zpI%+;GfMg8C;}GMOcb`KE_iyt zGQ!I7d+4M9{~XFRD+}r%s|Fe<6tle0_kRS!`$fe8>$NvDj)p92+bvg|=q8w4|3yj6 zT0<349$>48s9hO=Go{^}@})92>X$mPp!S-20puKi(pmzKt;X;^M#gy zt`>P2XDpbSsKOxl;Ui&No-a(^AO!Z$@f%2~Gd-561#=a1{?!;tM5fR%>Wg+ep`fx9 zUI`H&^rL*#5%!M}pdL01Xm)mxauw5DxPkEk^dk_nzA- z0E~EU@pVA}&t`pNFy+MTOZ4{T51E!GD**cqhVcZC=Yk$iDhzD-R8TuQe4+}hYovx8|oJ`S9Y&F zvd13xs64=FX4xHcK#bS8;3tcKT$$Z0-z{IVZH*vXj!t|8H8W)DN=~M50`KG5NCICJ zZSD)tNjC4N@ex77<;`iEaSYD;K>pTDGcDo|-XU^(&dg@qwmPHk3?dym!ow#W)Dq?; z?{;zmOKYZZ-n}!??T6XMA~FY!XH2Ba-?dGHb=L&pt`PF?k$i$e+rHcotL<*7Eegh< zd!>Fm=y9;8daH}!be0-jk~)%-ty?udAv3Ecug^vA+R?ZXk151{SD>vd3v(q z8G$3kOPDj6#t{M8QsorLm*Ir9FF&qORk%U=Vl&Rux_&C7KzVf_38X)_ zq;^^rVXt62E`{C*^*2>uteF}me^`I@dodz`S2V9l%ogsJ?t{Cmkn+nqcis^h_^sGA ztfJWos)E+1K0iQ>=4Lcue81?Iy^7*iFjQqO_RY3mVRDhqgxSLFAj>Flq=Ed6g$)He z@Hbm=_2oYA0>_YEyoCDAcFXRnd7?pl<3+Ch1W03gUwVC}dU3_&N*wxa=N-P`&w zAaQLpV|LW}9433YieK2$E@#Q|rV~7OpS4_*t^!|m8D$-s?15g$8_}>F@T(Kxb4k53 z12eP(;4j&X-j=AS`ZJ;4k{>}{!5ht6WBeDl8AYMyE%Qhla&Zb2c}>ljXnTW9>B)7! zw}0F1>rsPYRoHdJ&z{A_%FsTQkhPIRh|@{YWqu6X541?1UT|LnxiMi)&uAx<{$X4a zM+nx!9GQW2s+34s`X_tZW-O_ETt^TJ1fb8x$F71f(sFlhtsBB;@IyRun1YBhFxu{u zFh<3QRtr9719BH}`%0VaKBFC@nR9_8uu2q@$eEq@zB%R!ty>6=A?|d`RbTK7QF@*j z+^4+a_$%>zY)+sz>C`s(-E0CU@)a=^`gKsLhmbaiy+V}Gy8S3W1)mhczl^o`v{Hxr zZBJWO=B2iN$DbPBn^9=}&6uaB)B4j@cTexczI?+@{-*SWTYM9iHFl7k ztdBmL&|=R|`fByXSS>~i!)gBBVcsX?iS6bXwGCyb6Qe^a?n zb3~M8nOVy{Gl242oo^WjWT5%yYQM7gZ)GK#;R@4n*y5Q8NdKEN8J>4$l1MUaBmIc+ zCcwd!_}qN)QSf=6vS&*MsN$u8JI$K&b_Cxd`$(q0#^#fzIrWMQaRPO7c9zSvBy+a> zncs_!6g~hSVt!fA5+P&<2we4WS`~nKaMoi0Z}p^eT1~YCX-f-x`}kJg6K%kSQC=w! zDfpJT<hOP?X8oKUy{lQuIC^QyTU@&nM*a}y~DXfSfEtzC0t4t(sg2XXXKqtu|=s1aYDdl zfDG^W{FIAx%~Hq;t;IsqZ~Li!QF=O=PX_V}knaJzdF7jA{~}=iJ{<|Z;#uOj25iQI zd`WAPIbZ{=;<{TSu0X1yV>5u**%<8C2W7TXDN6B`Y{4>wmG(J!V>1y)Wih~ zxy>HP-62||MF==;aB>qoNpIe{^IP2J-+@8!MtSGTCX9e!uPZE&pIJTd*+ zo+Gmhj^8AIraQ~wtZALEbEQ-3{mKWEpFO9Nm2RHoJfK{5OCng8kVZ-(mM!{e$&q*P4py0a>4S0qRNu ze}1jMyf{F=;yFkAi=i+|HZ?; z>-hcW?Egpf{YUcu-&1@Ls>O|eZ~^>B3I1QS0kS+=l~2d+WpI3X%^thnkQ^&ClBQfm zOqOxx#0rNoHZ?jUo^o|;AjDH%#OL$geAN0^EZgwhzq@W{=8w7Tp{m+MT^OFJEf)s!ahW^cp z8^CwD1BL!hfx}`_2DJCEIb7<+DZQ1nfa<|L{va~^+JWRH1ReK8!EriRsv zk9U%Qu&)1dqm1c3)asqg+fWg&h_Jt6%ALOkn3AuKCY9`d>7fy}h5oYXBU)-0f-+r| zq3)Z(ob5t{(pU4n#_F4m)X34MaSWQmS?w4ZP^_SNRAShN^)pq6PmdNDNp~LH6X*N0YR6>*OnJB|D?;+_Q4VpkX~zkBx?x+1 zziE_hxMR!Y7KWj{xw^9-I7F@jsM_b&RX+$xlI9m3MDnin0bVC3(2V0!7P4LQ7 z{$te+2f{xe%&lkVikHIuiyivU#zVOr*Ux~nHF6^Rop;yi0A7qd=X(juE}(dSbd89` zG*UobYS(4>6yX1$9;Xj;?U^~=O3hy=1%Qa)zM(Sx=Y70iNCUuO zA052VD&8p}?*kntjm1RF)eHiR31Zk+sE}T)cf(RO?jFxmU)S@-0GcMs57dSa`s05b zz<$9tL;%t6Q;wG`v52H?W z^}O;WPcJFeow-B1oUh9JFR1c%c|JoY0IzBMM3>AS{uIqayvfoI5%k4MOvKr~4Oxt; zqoESj%x~I2fsN9hB;_4KU2uNJBO=^EIh!D1DesydoIjjrt73|VLMk8k{4N`?U`E++ zj7tIF>01N$qYYB!<-{`|XFnXPud+hA#GKObN)M*bB*jEbbKQ;>4k;|MEr_-Dj2T;} z6EeBvhy4)9jxH7QX?^ti0^EhZI+K4r`p9hUaYN}CK{=VTI9SZ~S&NUG93J@vHrf(7vIq-8CcrXmoF{yLfA$4S_-Kt>)1aa1WebND-6%PBw z6s13;O{{*{_uU_8(&B)s7V_Dg_re38duR_=xTFS-c`EpgK59wHAFRDSQ0&r`t~87D zMqM#d-Kn(#9Q)qIsnJvgZ?D*@;3a2ULRW_S_c#&n%;3$3g!rpD$tm@*{#^<39zzqW z&r|2xIW`xxQe>P*LjdBJt6!dR`%P~aj5|c9+^ce{n>UABq$DlYnT%kdZ?jx6nfU;E zw(K=5Y^N@mQH2H4iOfP8vyc6-G|>1*A;AN~j2AbM@kUb-5gF9@z6)flDLMM1X9&e%^~^2BN&&#L^kbqmeF^ zH7sR$)Srw;c5(_nhh4f*NFSr&WpUnUNX0kF$2;|5JAG{BTYT!DVvYq?>|ZPD)fd!6 z#c|shDO^AkGQ;rwa7(HAbDTC|<92Zb?$gOqSsDxSP3(RkdJ_7NyPNuaKOrO~Lh{?{ zN1F8)LbypTk%RnFcIoAH5sUx^9Vq8HR_Q)xv-3cZx6mZ|U92;rE2Fc$Iy@?3JLloI zmwdD5amkawXksLN`&=^v66sr2*whMV3hnI&B25XG_45MGxT)ZmVvbytJ8H=JBy6Kc z$M$Ue^7iruZT<1)FuMrnhGlQn1!6?+!-Dkt>YH;p_HtwHh!O4m8MIN^WPafuq+ffd zLRz$NsI+R@p2DSFGSm0sn{D(_f7Z*`-wK3=!z7%Qd~B!ki=}DaT~PA% z&d>Pw1S8_kcmP%mc(9C|9Z-K-a7^Id1L&iIAWz39PR*2yItdreJBZ$>hiiFJ5AGb@ zWDc`)w{{f_4p89}n`XK=sM@3ZZ4<$s2yJdhfc7I8k~dmiZNgTl9mZA?aI-C`V3xdgIb0SK--H&&)Q zKeKT~P_JeOAQ&wg$7ZQRVPSqNV!>*ZX#Q z^?q%1h%EV{HV;3&P!;-J3SAoj*)JgP@qis@V+-@Y&gL3+)i;-G@Q9Q#&l124WH4mc z9;Zf9tZe!IegAPlm{159g?kF=pTat^-fcfyCvSe72Ifg7PJR9E=SL5msUhk>$!6%x zgOQSyy3X}A*hRXZs05Xj+_^2!IfVKK&9L_qlVdNmuJJ100&E%9Y3L2DHE$H78hE&z z|KrJT{I-q}QEY+tmqx0ZO8_9r$=Bk7b!!#vs~JIKEaRb+7%OB*z~^&rQN9Zg3+jR^ z)(8p?Vk#e&7&6?DdH^e=pCoC!ohvA5Q`)3d2?95Har2#x(V!Y1pxsTH3Nnp}Sj+f#FlBSQbWJd0B zBmb=jBefsromuD!!Zm7`Bq@;kk6?UbuuF?jpfr+4vB|$`e>*Z{UH`lhK#$(}n~w0Q z5(N8!o=gI!21y}1MIuyin)HmN&G@rg%SpD-I^52xo|GKefAIn7_1bL>myVMPp!P0h zN{2nDNV}|pw7{pH{&S?>T%xjO$rEYbo;bTjMsZ2Ww+v;rnNsT!2_iLG^iGenk+!%h zSs_m&2G=#Mv3sa3QiFTBRiAjZ0>l=qGNjGFwTKK-C(BoJY?RqHusb(yrn;{R(EuaE zePo2{FC^UG5QLgOEPo^>-G8<9!v#mlD(>rMvFg>dkYF^WOXW~IPdWDeJAtcnqYDM! z#V7lbV48gj+RMN5CO84T`ch()-VMP97G!itZ?Un$`pYLI1$~VE4PP!mYXO9KIn7sh zGcfN9|DC^fwHR&_H?vS>qe1Oe`?g*W&EnqSF3_z`@@IodP?hGgq9#J9Zy;sdZ+OJn zevf7$@pXVV=LdlkS=`-FcREOmLwfw%YoU0sWgyAGM$K+J-9U!3D|q*c=G^K zF!sKsks6-wa;tfs7KsH-bgUgj&LM_~XpnTM z&k|lbZgIrG=471+zLKymhKqzMW?Zpnsw zo&JTzz?-9~gWC$wdN^F+JeyvLIbuQd1kWB3XFEyLSRYz0$(;uKFZ`UfMA)f)sG(K4 zV^cXuXpM1sPEGXWII{~|2}betrLO>Nn&PanTb=6_;TX=}X}Z%$`SoKY035LN7G1ZL zH(HP?=e}v8&^W!0JDxB1VS*H>LiV_5Rx+1ZTH{q`2;A53$7(gsOD}maDxz(m0aD{N z7U3)qw(%i4Vt)C@kKfLIj`!N8U^I-9`AJ9(2dygxH^5}97cef*OvvmhKdtjaXve~W zZI`!At7yiOH~qGXYu9O6-=DXp!7-Sch>VX9dVXibm)`=NEi|nuE3!mnzQ~NPaIV}! zAIqUF+{2yxeHg-zN;EH&tp4y_PuAs+_i=~*jWfV0@n$THdU4TiSa{cj1DEIT@29dN z@H1bKJ_-+pq#Y34OKU>$(I_eu`wo@<=(KjFH6Ek|QVF+D&U zpMCR{y$!$=XGnNlY*sW?4Y#TDy|xb(l48j-*V^lgYp8?Xd<*!QPPdcrYahM>WUD8s z>99)%)ga!39NiK_Dv}WDfF=FJ{K)_VC&9y+QeUohbz8E%%L9zf-_JaOwpf&oy7?C0 zsd6iSQG#NU8tj!-R|jezU0|83Dibi?#zAj7Adu@a0Uii)kLbD&bU4{PVMM zS2y|I18Zr~eeu%2@CN_c5)pL-1iI`wN0vRaICPAacMkcpX57Z4*b?rNsvY4;2ILz+ zLsfcLj`wkT>lL%nAxcOsA(Z4uVnD85!qt+Y+_lwuC!5yOe`OaDCny(zkCZs3h-VkjLZyUhjTDOPrF0jE&% z80SIe`WCq}5a-E%nt-H@xvmrOYRQ8?fHggq4>%2;>Zj!|Ib_0y0K&@3$J3iAaSGru zZhrF`%F>FAnqU5UL}l@4=B0O!5;W5L1?jRz8bXwyhCc?h0@z;jhVZ&6)V=>uL3ONnoE{HJX#krw&WZ?^I#S2Q5PYFDSzK^`Ck2uR2Cl9?!#PcKY*GD3E;iG(TqVG zKkC3C${mB(r)1ALe2iF}KG2nR_2Ij6FBAQ3-uXNmElkSkxC1kMxxz#)v);P4Yl#s*(Xs? zZ>sh*-sF-6iX)?ti`B%kLw#%pi{q89z56zSNR*hzW(Kz#O_y864O=uVZje-F8~Oc@ zW_^_k@E->?8cXz&BmrVGG;^n6cr0@ZaKG8%MI0OYEOYT0^zp@{-#>%&Hh#t%b?8Z< zPA*38;gH+45nq~S`9C7PhV1I!Ao`?fP^=uvfR!~(?jza=g=6~2IpuWq?e6RJkSY{a zgQ@#t{oAeXvWVw^VVF`LdoIwe@B8Q@tSu=BI~F8ZT99i`;ghhaeZ6mlWXFH=5 zOd8GuC^{bvOsivtb7aH+(64FBrZHe)n-|W+sgN3F9qt_$QVG1uxy)0b;Nd;{Edk)( zi!X=g#429|zT&s_)kOstx!45KXAU(l-wSFPEHz*{#u*HGl&E3V8N45Ru_v|}Ke6)z z@TB?Cx=L7wg6by_Ix2Xx{u;n;#w82567p*6tG-{KN6q_T)D#>>i~#I=`Gmkg z)xCCk<1>4vZA^t3G=&C-XZbRXLzoB;X4p zWK9}_UXGX_D~Ri<=22UHt~B%B^w{8qwif`4jNy-+c~_X6nkQmbU9MVflBZ^Whj{wq z`#$;{r+uD)JTj|@(WYGB5+e=D>xToy2}E0vR;STTfkTZevuTqCtJKeS1zxtYbBHjx zfTi+lPdN_}zZGU6&uve0(p--N;K^tlkx|V1ZBm4Q`#`0wIPoV2{ z#G{zP$*+ZR8UU8C2fzL#42k3s22Z_+3dlb0=-Cvixa27KV)59*7^o$$g7>|}a3=A~ z{DOPgBP@sy2SysvaQm2mGTYD%G8_;+ds;MXhmF7X*{L0r%6EKF-tX*M?Eg-<7$5vQ z{9_G-;C%aA+HNuZM6>nyP!&URc0xV4c@S{#t^kc`Z_ll$rk%Ag8s^NTHP@4Q=-vA1 zSM!=mzT+mG*}iW1zvH&sQ9O35#Ch8DO(@_PG2F^5mohx#R>O8uuxY4>ndl>eiHH^w zV8hgV@^+s#)%YUXN8I_t$Yi%tp+g`=HJFxA4c) zb)_cx0|z;bIRuA)OPKD%XeaFXs1jsYpFtd-&P$%huJ0F&BMo zXvmZV=O)Nd({9nZr{ZU3=kT^LQZM6=gj|%H&N!rJeN*H}rqlz5%_YmT&m68t zr?M!pe-Lk{=;7XEQ8K~jtlxWQcC|#WKQ^5yAj$zxeSKsJhkeahfJbSc>=A0DtmCvn zM{gzikEuF>J2a@D`i`B5j@tk++0w;mw1M}@q>(u*Aho3@?1 zv!WRD5=VQkcFIehI(os+a#%&w+c^&G=i4Y0$mPCj)LtL3b|b=~Ebc7R;mZDH zWrEI-b6>uJ-Vp4ZMVZaRvc@S+%4Z5j{L+@}okaIC)W|QjVRQX$6yMU<2e>bc{b~TX z)Tp&=cxAdJ&D2nRSU*+qii7P8KhlegBnbO4&^ykFlC}b48EF=E-nBa+m1xhS?>s=d z3ir?L%|ZML_;u=U@n5g0Fi4j)i^adN)~j8@fxvdky1X&UBuCo?@Bm#FlR&9J^XOd2 zt&uW-KGp@f6aZZu`ba)!-L_JwEj zpSN9Wu;Xr#tSwMS*cNSnD~~9A-fPBd^3rx5dFU1&E8r0*x&O$Nt)yiRFEuq1gS%4n z&pFR@w%x9vfFxKC9u?KJC$X}2V=|C($3-=t?Aw3fZy)}pKbkIa9?XK>^nm~Vzx>C2 z;dRG>)^9=UgZh8zLH|6e%JZU6peH_-zWnD8|I(Oe4S`mEqr=uf;QBB9{@3LEeRv(& z01(&eYxTwd?LQt(R@uLQ&Ck`l^MCooqoUHU4jhZ?J>_hbTk5)wS8WKMVTFCQ{gI{(ccU! zk*r^i81A~}3VCQ&vBNGXKQ2|bk$t7*`yIW@=B3E4`c7~D^f0>s9f(I<(x9z3((Q#< zV#&^<0rLSW7NmgBg{DO{QD{(;s#b_XsbooeO99ch;(TtWJQ_qDC6H|y1Px{pYPk+$ zMo5PYX1^)D5^OvkH(7{Z8w@gQzf`Fou#JJAufEeF{Tx?j`^Baz2l+}CH z%_Jf$tO5oyuPNXkUk{k!vs~LQeSHaQZfO^MGhmuq;eC&qMhmXE!@u!^8kHA*kj>HR^dyG3&DXGD<`YXZVo8G+6^q`k+gwOOEBbhm ztrQeP8DZ$Uj~jE*8bdZBu4kq*B5>e?$?*&%AdL28H?%kTNVm%0KW zS5q2EYlRu`43SFr07|EVLRgxBH;y6CI8cYj2ccO~*}~?+m<9E-sqU$h6=djUykqfn z+}8XWV(8eRf9x019YDg8?=J!EyN6BPyTjfkK{^ zjKF$mx`Mae@%{w++Q9m87UAwt+xsuXQtc-zcXn#lF|YcUE7~QkODo!n2Rv)WEo=b? z>6ICt^fEGYD7TNm2G`F;Y1`}%RShkRBGo67M+wCw*4aL6WzBOknd+*LR+9c=dQ_tp+f+H0%McTJhquqCzOUM5r!vZ(vQ8{J3#!Kx5~TdB7J|?tRZXTSO^& zN!zR#@w_W{VxW3{ zp!Z-3BYEBlEe_er?k436NzpILTu(gpyM}HQ45R&a zw|^nA^~Y?f{-JjU%2UhUhAxSjefn$b1(~v^lrA5bwl(T9Pq8uUa_>8!`kBkheW@y~ z6u9?^F+(BkN3?Ws*RTP{FMjNWKG>C)tkpmt;lEE{mY8(Sm|d03eV`BWpQiNg8e2X1 z_GP5G`uqi>QVWn{Og;@$ute=x5Cm3=b663}mV=(k=y64OozI?mK_e zL7#ftSfrryc}YbC>xUC`7x1&ju8oZQoXc6;P5*38dc{WE(nNBK+HomRlmC}4@Ez893mR~$@S;U7%8YOy(Z-Y71>~KUc z9#?cezLW0!=IY$Xt3N7meTkIMSph53bUmfcI*8=L#Jao@%?Cf?^GnA;-~-23T++tF z<_10yiR;T*TLJu&(|kX}AB-6% z@-Q@P_LO-rr6p2iv-^yus7RYufmX1K9 zb^c~M9KYH}dML;90Mygmc%I z4hea-x&B);EnWSr2(sO=I77I~FJT5vRwFO!(>BBxP1HOZmf)<_5QYS(EOTX%AkXu= zZ1YMB<5L?Pr#G_lTU?2-l~j&usNVJPSCWlcn**)rlAYx(*>)#Kb&7qZhvT#ODc?>x zteJ+&dh*{?pgyxOBdACikkQH~f`@2jOqxa~Imsr}B;bb@Y)&8NF3K|qqJg|Upqrxw zJP!q~_yf&j6dFGs%HIHPUKp#s@Z*ZcICDQwi7MT;=8F;bW;N8jAoSBPtsA8c_>cj;^)M@0T(rhUc)etr zi2l}Bakab=w=_@OE22`mLgHy!pQ8#o&rY9i#4uew3GZ*!V6JyR@{(XLiTHN73`-khK5+wV1jNod7HtM%tn#Zg)OlEzjaL{2hE2u8 z6D(1ckA4EW1Zah;o*9ym(VB@lXYDFx8rlCeBj)6NQLJ*^pa)0AxETn}_;BRp)(#ET zXEo)7aNW!}-WE}T1`co8z<0s%hI?Lgy4GObcU_^N-WM%c7$HG74O28&)1bb-GGJlt z-FHZ_gZ}@p_nvW0rCa;31!XuEW^_hJq&TC1D1rillz<*bk*=U3(gy*N5?Uw;BqB%9 zQ3R!TRH~F9oj?*9lom*o7FrS%LP!D$5R#DoZq9jTo^$5>o^#$W|8Mgxzp!C%?tQOy zuXU~KT5CRui9}-fB(O8$P<;jE!n5={a6Q_`hPT}_P8qS&#japc{k>Gw60f7jc9x33 z3WA5UJ*8i0`OL*QdX#HD$3vL5YVf^0P(OJ~pFm3xXb0uC8bfVMG)o3zu#4nu_oiy5P zwQM5jR*OT#FH4qA(1<~LJa;KW;YT<_B=ZFmKbFQ#s<_Oi4Z%UwuE)9i8oXQGp zU>T4Nx-;nF;2@+>RipQsm2oju+CV`^l;Z?Inyph6u9ATzG_hTA;c@$ZI~krPooBN! zmwl##)&Dj2IC45=TdPFWf*(e~EbP6)Ojmx~ukld|=OfNH%eLyWC-;Y`E}>UGh@L4F z5#s2dmM@7qOQ%Zq=CCsNtry9ssh@jgs}Jtl0FJS`DSvGCGlieEN9Oe}TiTW6PgHymw}xhhyzTw)yL_*twbMo+lRUFZw!MO*+3a`7H-TJwXrcaCM$Q_xVl0Jg5aozs}|d*myX?4Uyab zy6>w|wAwT$`?GIWyT3j{P(=9B80nnKo0O9HF^-ZFsKmagQMUFA*U~J!!hR(P=7LVj zz7;1m@9R|eJ;z+ukx}^>3AN03bHk^P&doI~cee&^L*gQr37Zj=c=_{}{4iNvVyOR* zdm0^*wLH^7MWSGzZQl*|9qanlxX9Z2yrYs==Q7dLeO#FlQ`QV9%AxjUP(d2(pqjSd`a>u{*5REHJLM~-s{gOm2)b^ z2UPTLoN9mnqHwM0!<5C^4=33wUbLE39- zNXwKP%4kT7O)r+K#4K=Sph$;z%Vu|Ca)oivQEe(_#j90_##${)Qow}x1N&_%;@6y6 zfwt*ZbJL}bM+294XLasI8~*56kYDpc_SNt3GJ~~3~6;bge40PUnju2c9|yJ_01ba%8&b2!7vx_ z{^_-iJ8O5@sLD%h2E6YXA~YQc0i*5v!bduS>-MW%H?r66f*w*6 z8JJDe)OCZmjq25vI%YZc?5qXzEoQ$PI_pZWHR`>>=&upA6DS>1^iQVQW40T{i(xNz z*e@vO(UaOM`r^>Ton;H2KI_$LxVL!(o8A+EJZd>u}pmCzo&An^1C4DFgj`t<;2-^ASGUG9nVfcwR=L=U6Pdk)*@ zI#?%C4ujjgJFNf~i?aS1orGqWm`PpHIKTaaKGjbzKm!+9_awd5Af_K38I5iNpph|z zV$7wAGq$GK?$J}Zh>s?(h}=78f@l@axr1j`UI?Xv&yb7bH=Oe+8)rH5=WGPf0jJ{e zrD|Tdo}1h7%5g(<-TnbVwMd*HNUrkS3F(Il%e)zQ?Z6YgU+THn#!Ux7-0N$3kh(@Z zN>GV60j65`OHWcy_y({KVoTe3_|RzU?WM}JWgj!&QwXEUb{&0(SjI?)KV2+QCz`@Q zoJk*iuU4u;kHhvi*=idM`<1u@FQ^OPAVG&4^jC1j1zfaA-<1KwU?(FnBeSIzd2zsS z6R|N(2O{J~cimcMY83D*Ij|h@vTt_p(zpv8nXn6Qfjm?g*tK-{@o)L3m%$EJoQXl+ zG`RZrwErKldqTjz39*z9&dNBF6^KN)G>*z$uJg2bZ)2^PtXUWuN9rE4V0sj_R1R;y zt*WYdi<`(sfNwxuhPET+o@dDiYRcAVV_*a)pTRQ?L2ehc+sGbd+Z8`mMZVW^5=7BAHgN_26*s>nT1@ z$5+FqY!yGyhZqTp(5u|OLRFI7UrMvbN8tR9a%W`mC`ecYcZ!nO)y6OwilEjQ7dq=(LZ%;2u^g zN75MMU#d5=Rva;=H^S7D)D1IR)hZNHdo9ElxFUT*kZNAVONW8KKFjO{dGi_RYN9Lr zn(gt$L6h3M?5`PSJkKURR4-yE7Q&B&p+}DnmH>dRkqXu zb0D%ts6qGJyn83MBI&hj+1&gqjt=uFXHqAZ-wqj@ zK(6f`hy_oG%Zgy@_|$-gd{r94(N)|G=U75t&0zM*J&na%7&}OoCZuSwQ5Odp>ppV& zWO=d3R-%!`!RMdoZXy(W6@{yeApJ@Gb&)wJ*heVqwVKc?LdWh%@HV9peUZO8BsBfQ zzBXA=GzN|8{lc##yYWK`A{k)&0KEGlsWWLhW*A8GhX#5DU;vB12R$qyM`LbC+A*qj zUiAIN;*9duYdj|gQ8`e3Pq=x0P~q9T?zh(T`uv~0l#^+?$5Ou=drlFBL@YlKQ?R#5 zyH&>xCqV(!?q;_ep^1}zzcG8Pi$gV81wiU?tH%d^>jhBNPPU7k_!)O9pUK!Le;I(k z7_09TtyGFR6-&^QZX{ETKozutbXW?_48blB85A7jAEvuUy)sw~8}=Z_&^~&zwWe^z ztj{S%nCOVYSX+r-9#$+!9pbX_sgupdD0Tr}uohFZNu*D`S4?^WOS|^mg(UR70Jv|4FLQKy*Zl zmgIw2n=?7jXOE$oJ2Q=Y{XF;P`!(3o3UVT%@a)*beQPJRJ%dH{%Xvvg3aW&Bw7KxJ zVpQFYSsB&xlbd=S8ojN-(3(mv;GA=xxhyvsjAa%)$`&tf{=Z*suAVHdd+Eh zHV2Oif`mvGDoq)Ivd6=xxwy#ojLtny(e~6^$}Q&B@Z|Q2B5RLE{HQK9Mu;nxW?b7< zCMNv|Dg}I`=2^tyzIJUb@I&Y)bJ1D;-gd=vD3-C5fDm77_9OX-LsH}2I0w+lADE>ts+Z7yD~*wg5HZT=a7tD|%w1C}K}iU_prRUoA# z+L#Z}j3Mt3O4ws%<^;&|pMFE@PD8iZJSA)V5fnb}WwK+K=?DGZ;k>=$wv*P@r|q^a zyub@ZlsD^NyE>}scsk2}EQ{vJZCiLbxd~@-IEe@3zFoi(98BIS+|lKzILRNP#Eqob z>8|?DloTsGTKcXan{1LE(z)8hC`m<>#;)YBWBU-^DyQRT13f5m-DUnbB!Y_*RPFu# zHY%1Hk+i>Zz1=}=IQB|T^2-2&6$Vl2%vlM|Ho2nSg^ax#!?80O>zZ%9)8Z$LE2d|7 zJ=r%HJ<7*U%Mttw6)+n=tB9rVO+qykq0{JDe{4n(0UkQfuQu>IPM@|^9+w*^ zR)QlnM<)g7y9t3DEmMwAaJ-`XR^j87)FrJ5QovQLBLbqU3F^r5*o9qxNVs9t1pV30 zJ-Z>^jucAEx%n=dkv?zH#cS0Tfw=3JLUO;!8%cN*< zjBQDvyC7#q^|aI-U&cY+m=bhQvjizf;F;U|&P>IV^Q)ogLIS*7OSde+Ypu{nJOqaM zk31?f;0<;r{vCqYbNe7~`q^p^%}&F(=tad*EWZ%n9Mn^$(|v1H5MBqcJUarWK8W z?;1ceTE7aqVPr5Q)#`c{5c>RjU4BGLQN}FC%>pgOQf5Z`hx*15-33Se8bYk<5d%Lt zJ`)VjtwJCdG3!~K4)H2v5-cn*qDMuWZ=3CD4&M^b$Y{kfWnA~0tj8AOE@r1Ss8W+U;U_ zSQxzvI)U;Krg=CL4d2C7C<3*`bcU1oGE=I(oJT~~<2V~Phs z;Ko-%EC4~!!?j|+FJ~1Dyge5bZ?Lo(bSu3s@JV+pUJ#F-q$-Q65-mPeMc@oN#xJY^ zfmmm;@q7tB{yfVxJgyUE-ZSD8XR>oKIzAWcTjrEdDozP56M~fk+_Ex!>f?2!Jw%Kn zn!3!s$Ka$GPF3b=$o9Bm5FWBZ-QG(rKXk28$(p!9%2Vs^2jW6xsrNu6{%pIygY`!- z%|b+PXk*NyE`&m}9prbFN!j8FrM5QKOi3v<+w-NW+d50jTKc~*#9+ZYkYC8BtUt1X zW=L|w`Ot0r0c>=q2tDRXS*^3*6015KPjijt%@iijs;ht1WU79b?d3HX}9xCqIbRxX|a}XD_5BDoL+05@IaxUpi+~oN3f08h-ogBgS2?c7tiLbcjkGO?z{CO0LP;)Z&{ud zG!&?*#QQ7y`cAF6n(r?d-b`)j3H9p@SzaAu#2m_&qgZwIn4_`%-30oTNi6-bDZLFk zNxJZteg`GFjO);S+LVep&eIWlrW`brs{VaTMsAd10N~zy+ap$u2hC6U`c155E-yjM z9GWDPL@iI?o_d6UT}o@mCaUBvXHxux`bp>qf!5unj+U8m$7ap6z~;wOt`2|&wrJM@ zXNA*uWksL8#i;D(TUO*inq>#Y`^4AFZ3TRb2YMa?JM&0wsszm0Nq0-L&QaOUrQHIQsw}0YLa!@qV0J--%%okWH zFOtUBP3En5$VwdJak$-ebBct_Hv;=w%{?mhEEeO6&>{S(9=fuTGj|3E_x4XxQE%l4 ztrZ}oxuRy~k(J$w5$3qK{biGtyPOE~-!d*T~oQXZc7#oj~@`!i&l1 zibec%BtmvcrDg(db1SP@!XvQvgRc%Db>o&_%$*`` zv7&$1>1=&5izOQN7|9Il9@iaN*0UuUFTFjNDZD!YV|a6J^G4#0NKJ=qEqAn+FJ=yJ zk85`blwt5F=2_1Oi?MjMG$tkd=>qt$mLf?D4Ala{-qr}bN%d|+@cyMZm(y3t8KW4Y za!XuAo!$20(%_c(i3eu~WydKTqj%wwvq8Bb#Df6^BZc8Z&PvCkWj8UDnC?Bkq1Jm+ zO?I96of#OK{q3zUI=O+l8oz(_j}Hq!9ZC3E{c4Hnc6zWR8Bz}u{on;P)1l`Q;P!`< zIW7&YqAQIHks z;)?iu-*-1}y`}e`n1-@<0NozeX5YekY?!JR9B|zTP`H>}=VhznhNoBaDZ*#vL~$ci z{*A&h)_02-GL(~8*gyf09qL@juRV~jZ}2Y;tnVDxEtAJ}zVyoV&8qScydmB+azn(A z><2w8&cj>m3&`J+_M*64v@G*Qe47y$r_Tnh#bi1>4>{GD9qkaRx zu+do-`Exr-6;7u-CC_O6K@m`F2SI~hYd9UpSxAT-@ZJ{b>>3=N@G0G;w`3$zz9my2 zi(R(J?}}1{9qn>X8+^!-iRl-_#F-;!SlA z^6BcJUIg^%a^_l8))1S2AJy6;GT3u}A^VeWp3z^{^WYO<{TBlU$I(xp=wj;O+kf48 z0~$NXYa*;B&Vx6rT-ri02hZHyD(@&2scg?>ZRY9~2m1+#1t&W&a#=vT*G7R{Q`%XU z@Do2a%#dSz5U}iV=G>&mHEe9D^T1)#7mk?efR7v(7c8o{cAS4~6GprTR8;Qb6A;xf zM;WOKd#H6Uz16*2Ra1h0*-ds@$5A3v94^**RDs~Hh2#@_ePf60>q?H9Y$`{rO6v#Q zIZ%pdqA`ukY)LQXYUTdcg5*py``SUYE*>OC#D{k)2(`JFO}}a+t{X>}zYND-e_$t) zc=S~8fso(*<3>fCZZWM$AA9Ypz`T!Un?;8c-zW$PXRk;#K4Lr%w}j+AHhES2xrZzH z*^vikHNwi2J*RJ&8bWR|-gUmME7Vzn+PI2ZJ-Pv_*8i+`g=C!R6Ly08=`?@TsXuVi zpUS@MKgPc-am1pUJ0-fYY%V`L^XBdL#y&UCXd^ewo9d^&Ul7Dz7c1iURvxJ;KGg}H zZ!Iuij;M-DsumivVAzy10=fkbIrF*o5mOv|gEvhC?L>~n$s$y?+){m- zsW5&!Pzn}!sQ#EmL0QnSda=?8s&gMRz4`>Ym2U%Z(R{~P-&Ip0Npl^XTX0=aJQeof zNzbm+1KV3R%Lnue(E!&d=)fo4je2dwHGz1;(%cQi7wFzyYEX$yD@G{7Hlpm6{@rhiR=HOzSU-udty&1k-#?d)c5_`T+wwYBcw6u!Cz$-IH9#QP(u zQSgHI=bvR}FUcA-jvw#x@e~XngyJ)W1|zi%j9+6Hjk~|S3}g;BWo%a%`^kj{Lk-?_eCXwK)x43;G4~Jr^Hw^ zG0QcV1*42PHNjPak58v>6CzL-34*76R=&7wv^3}n_3+1*9b9PNT~u5R4XI;rAM;%C zt7u0oG!(Etq;GU;ehTVz0@Y!fnLE^coiFtN0#owUNP!JuN>uxek6suciGEHK8upHL z6^moIgZ`ij&g$6)a7@;&V|szK1TcmBg4A^K-vf2J?D1P-P6cW`$Dy3oB}fUMV88W zKg<3y&8)SY8yaD@mMsi1pJJMs!2#4{IPnFQziRH^VC(5&G`N^OoTjyPy}Cu|?OxYb z+h~#)wx?zAg6y^o=Uxn&to5~?!Tk#*0v2n`IZeK4J%lf~_OuLwU_X+j##1m)_0hYztg z4kO9*J6>Jy_StC9+PcK`(Q$G7cFJKGb)z+QuPvnb_E>IdHK_?o=y`Z1eR+=-Ci{-B^)kcj8XtNCE}O zL_$Rsy{b;`H{=(iE6lbGZtq`z3ZF~ic=8KW$45+W(XFtsqFgCicS}8G!!<fhzZk$=@#^~~S!F6BV!(XKcRV6#yze!T zyE7JFV?6l{ak2%92A|Z_Zua)s(V|PC^be^ z?y5YctY8V4#u> z4}6&#gXs*p`uqqHkY=F*etJQMj#Mv~1gydaSr_?;@vh6jQ-6p_pr5QchrKX-2WWyc z$)cfWAC953+*_*lTg3Ni=A$}^V%>PbNv78e!G$cDnASYzDP6B%G?+XRCYjvTy`ZQI za7aBG_nZy67OHi~p+0ufvbxq>V03r}AdoD{c~`K8+WBmR#3u7Rpug^XJGC5^3WnC} zFmoBS2Cn&1_RZk4(Blcb?s;9%)$FDorNEmKDE`#Qx~Q{~)o%g5>JraA`=-K-OSijN z10UfjSrkItf#7l)qchMZ8U@K!BoED>p|!Ms^{TiEsxxhLE$<05{*~Dtk?07mvA@R0 zknyV~ThIiQLl{K4+OlN6oE0T<#BPkNJ5>>|ZjdXs_se54p<1+()w)TX@d>U=^osb- z_$QDZnXwKaCg&URr_|Qc?xouq*1~K(vBqlU*A@ZR@DxMBj*q4o1!ho(M#F|NNy_s@ zujT`D2(VFN{r)mJ&5CR8(YMRt(^lOchzZunJxClNGlF*LCfTT7ZdTIF{tfkMzA`GO&KHT4&}X zY986CKASf_O)Gb7wRKjxwnk*@r|i}gn!YD>v|9lei*nZq* zPe(>FYnHc=9475xp-h=IohmB_AxEId>r!brxqTP*Of_-6`zdh#;XzlGp3E0?4z(x- z)?Hf5&4_=oQ$>A`Yk6bA<7e0#y;ac-(gM+dKo|1tf8oA7fGcbnft|kh8^P)yb@J1v zw$X#v`2I!LK%r0M$3P=>w?L8A!98*>3M257V}^>bn8rFYGu!(4JB}W!MO%b&44#d` zyL@~kT*d9W<67==p6!64d7MZkPaaI)!Td!P%{+x(*Mr=bbZVsecd9mMG-7Picgm}u za^_EwPYwlguTC)ea>FvAv!;=3IPpujDkh%0L89@a3RFMaY>8K$@$)=($nbE4a`q}!KSjq{*lWQmKt9FM?(peB8OSJ%UYtxm=+hx?Z8x_4>dLhT z5wJ3#quT33z@y{Vg|Rb7ct!fQVRxP)u~O6tF#A>oH|ZhkgHG$r+EAsOw}U@){uy+c9znGsWS8)g#xR@gdl`c`MR~j)D;2?@|C4#&K;b* zMX5ero+88eSwvqR-QL0CP4I|XinO>-)y|9BF@=!v;4H*NQvInGDz6=7I zI3yd)4;a@Gxxapm>BJ^hXsDvpK*$qK1 zJP?nF?hgDKRPN1er}xddjWS1`v*Ea$B|!~E>?;l$dzc>#$NFU|Oh~H3Vs7HwUz*`O8)Poc+Rs z`Z3NO;uXCrY-N3pQlwQiPNyX31wZ&!(;5)=U)cYC0z`sxAz@auLYTe&L|r4%6`WW^ z96B7-=A9cnNIOk?bY|Bg$2SM1-V1*AP#M9jF_p!Qqc_&Sb%#D-NrPXpjXldcxgBcx zccm8)4(IQ+Xz@d)i76n!-&%s8v_gS4CBO)B zP)AOB^U>_`A-GLqSriHV5x;ciN2dLeXtHY7Ww1UFs;X9d+#S7+iq5h`Zs(%O6c>X!BXHPHsZikjzWjUTPQE0 zm?HNwJ50UJc&mabK-bnoadOW~hMnB~=f9QTcLbO-iq4o)Wm-gi{* zo-Oic2SiV!$sF!H)F5uom3$M;+5>)5Bv_(le&Sdhd_R(z%<@4j$xb2Lb-Q8|3;{;U ziKR@{CTe2-?5iBjTQ5t^DkW51`!^wI2ps$+VD~jgg;Fao#|5_iA=xIQC5)b#&7$M@ zazh#)wYnbSjJjS^v)?Fq=rRkPbrB!0KY&bgd}RwiL^?uS*xwx=AtUM37`-Z$eUp3N z6%TgK+37F6)hFxqicTebTNY*swIx@w9-^HGFjLes9T50EY!*Bx{x**jnT@pH3EN%M zzEGF~-go_zy|Ip}I4!xw5|X4_1?#jMNaPv(5>TPs9dO0q8smncW}bg1MHjR9YJs+d z^hogDB#IUKND3NzLzpqR!o}7a_L&a6;uk4EzFabZ)6aTBKkHPDE>mIVBU`G#N)68n zPG);dUt8N0%dDH#0e~8(n+c%R8XG5Yx0>NLmmRkq8@ckTaG%_{LWrFU4+w$$4lTu% zpRt0r*`d~lO<`$j8VH3W)@*@QK-{OjxBARBEPi83ya8mJeY_v@ zKf4{SYaX8(3N<|!^-@98_-9)0(v+J;h^u^Ui&LHVvl`01>%)IJNd{1-9tZ+I8m6}d zx)d#)qUfR)AK-~=QAqqFsMqw4Jz3LpsO0FF_eT%DfjOyevi(fcvs4=*q*@n*sZ+7p z!l4@+laV_|Qry(|8>HT+Cq04VHzO8DiyS{iy){v3Ud%<^WI&`R1v!hHEYys8ZD+Xb zGG+g%*A(^{kJpf)+vO)ALC>oF&6vh^bN9tr96MGuG&5C?U0)110v`&~W7W!GvN65Z z;Fpt|*pmtK(TnUj-ih>O@`vKJCiGOgQFp+%x9TEBj`AZ*z4;#^QM+BE_x>{hP7R6e zN*b!uQQ2qUxpMpa64@QH_&> zfSaSO=vqE4;#E0#Zfw|eH^`f<;FCB$H&L@T#-7x`4rej1iT(j2Ql5~KekaSnbN8IZ zYnDYzg5U1=-8uZ@!#m}#jvW^`W5t&m7vu;_ow&L}x6)qhzSFt0OtVqXV6FgkOd~Cl zeQ^g=bQM<}Vcii&F=-bQON9JNLFY(%Xi5J#WgH-qGILYrc+oU%~l|=ZL2YkOF zu+lWJu_FJSc=fJJj!R9Ltm^>Pxq#PD!`3IG$FuGiVkKPNA-1>*AF4f^_=}Qv zCv@lmu?=*9&wX!g?PG0A9S?xE>~#6QWVsmi^F{$_@&tuC+kvRk&mTHtZHzAD4)qDK z#lh}( zF7EalUYb6*%z2^lbzSFX%0T6CPdeQ-%CSJP#Hy5)qZ#B8qs`FbR^}!4}8- z8fJIouWRdH;`zvyn2%X@4wV6mE1T*a(3j_?XP;QJKl>MR`TaUkGxXut@#L?cXOu8r z-`@HJ?PrU8Ue@LCU?u$NF<;}VYT?;ieFoj*&m%s+5c8~i)%cBgUhk>t{2p&DBU8{l z+8eoq9zDA2|Sifcofi6+XLV_IeND`+GP>~I_8_-5PWH$?b`Z|=a$BCbS))5<^DJS=^hTr|@ ztC>)wJ_NAc#zF4IfWK;Btukt=Mjs{yIn${Ufb%fymhVd`6;o5Lw)2?TN$4WMoEods zK5l8Q_@i56#p+!Kay0ty+|d&w8&rVlP(@*Ag5UtS5SW!OyeCpo{UkT z0IH??bs{uU)4f?*J-8J>o(F!P9T0Aj+3KP0ODXpbs_WLYCPBd4@*+TuYY$rG=Y>Y1 zs#3>;H036WjVIYHzXDG#*}Inn2=s)8eyTj>=Un_xq!)n?N?Czro!(3<2XcgC)X+Al z*qPNk?)LFYY45S2%9;*m6^bg+++n_e*Ak7XfPP3o2Jo)I+BcDtH*Q4rvekvd6mbhf zg$)OD%Udz8;fH6&3q>tFvyn4qD!wM%3yg-kBmR+HsX?^yK^T;%vS{lpkw zJ%qg09wkHa2KfdnGa_i=oE36fG{(<2X1#bOn{>!0&^N$2@n;Hky2m%A8_Bh)N$3hy zL!_~+3~zhS$UqI)kfCBREIH%#b`Q9hlVzDQHLggsI>RZ$JNV@0A26_2xg$s~jCw;g zO<1LZjRi0d$7icg+4cZQcgB+@)zTuqrVswe=Y$P3(=j5o)1N^jm$_lC!#8S;)-uD| z$799rNtGUQ+jxKI+C8`-uUc`hh`}$DsNh9$-00Q^~3# z772)9@#Lc%*!~z#dAw$(pssW67se*PM?a)f1~>_|QP7k{YuKRwv_Y4y0GI%{oI%D6 z!(z7eHDcs$A3J_T@eWSfce2|-v|LpjSK zeus0Iy?fo8rvOrL-fWWG_)Fzyc*!WqnUZZPe=w z-aX9|`O5+FhcGJ-cD(_^=K}5A)4WOzzFM?5?y=a^fb}}_!QF9$uuPP>7Iz*-<|hK zfysT?C~FeG@aSIlQxj^2=h?10V^y_l*l*NjQ;;|jG;>as#_4-NaMr&7YZ%!BRQ(!ys~f}Z^n={bO~(17JjLSo3@e9RS$V14 zU@P-k0U9i2MO}#FUS%3_M!`vJFK>_RGAE?=_&c>rFXDp=GB5JcE z`sRx2VE_ekzvg{R={bLxhP8fd!EQhhrc0Ov166pVq4?`{#-2d!=hF@W}%E3DFI)nCMVP=zJ|9HDvbj3R_T zRWv)Ysk&yw!m#xUi-QfgGlk4iUBqg{ST!I;$D`f-cQ`5M+{?v-LZE+RK~ys0LjiTv z_apaX{}I8Zr8sMFLmYNS@a_qCcnRq}s+dXc1 zL3LqM$q>>akeG@f6FoTk{U7<0?MPgEt@B)K!8FI{NgV!8-aUa7h=HEPp1h3VTLVr_ zo7PxtQX2cj8UKV{|5}vtIJVl_q;)YHU~bMWRLsaK-d>7^&OQiSA8l;+&;&3E}$@DwC5AtMwk)P=cTB+QNJLIJ&>&K;C zik;w>9$ovMK97&IPgU(+D>*_$FoN$AMWT6e?fpVh4s7^1W+)5?Qgg$H1$4IKXfB%Jy z<=c#H#RbCJ1t#gep{1 zYddgs(4DXPOIRi!ypH&G#2 z<BAwrU$nK*+3^wfnMIWbk+7s`=|L5XSu< zc;o%|kGXV@K3opB$o*UZ4p-F$b!G_-Q=Gz2MUU8VkRM=~wcbeox++TLI>6tV?4+00 z7_}MWBkCkm&X}f;u2-j+U@-9k$vRieQuyJX6MnC=~=D?{cPbp^YgYNZq54sd2T6B^}{5-homX(>L z*q*g$AD|r`8c#lsJ5ih)a)S0Kx6<`R#mqD{?q=OZJsqu-E#ZZcKuKY{=JfO##4oEd z3rUkHB{J=D7bzf(+RVuc%n3*2h#FZLJAVvlTjRBMzTKN6i{maI-CJ$WdoHUs2S`&! z)7J+s#~UsdHPiV03lS%LO=zUoh|u}JrtA){

DyHz?ke0Q@unM(mr?lAQQ~-EGwKy4GBy5S# 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 Date: Wed, 16 Oct 2024 19:54:35 +0800 Subject: [PATCH 14/54] misc: addressed review comments --- backend/src/lib/config/env.ts | 2 +- .../integration-auth-service.ts | 4 +-- .../app/self-hosted-github-app-repository.png | Bin 371698 -> 375523 bytes docs/integrations/cicd/githubactions.mdx | 34 +++++++++--------- .../github/auth-mode-selection.tsx | 8 ++--- .../integrations/select-integration-auth.tsx | 5 ++- 6 files changed, 26 insertions(+), 27 deletions(-) diff --git a/backend/src/lib/config/env.ts b/backend/src/lib/config/env.ts index 376b03005..2b7a3a733 100644 --- a/backend/src/lib/config/env.ts +++ b/backend/src/lib/config/env.ts @@ -120,12 +120,12 @@ const envSchema = z // github oauth CLIENT_ID_GITHUB: zpStr(z.string().optional()), CLIENT_SECRET_GITHUB: zpStr(z.string().optional()), - CLIENT_SLUG_GITHUB_APP: zpStr(z.string().optional()), // github app CLIENT_ID_GITHUB_APP: zpStr(z.string().optional()), CLIENT_SECRET_GITHUB_APP: zpStr(z.string().optional()), CLIENT_PRIVATE_KEY_GITHUB_APP: zpStr(z.string().optional()), CLIENT_APP_ID_GITHUB_APP: z.coerce.number().optional(), + CLIENT_SLUG_GITHUB_APP: zpStr(z.string().optional()), // azure CLIENT_ID_AZURE: zpStr(z.string().optional()), diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index bcfe2c773..728e417cf 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -18,7 +18,7 @@ import { KmsDataKey } from "../kms/kms-types"; import { TProjectBotServiceFactory } from "../project-bot/project-bot-service"; import { getApps } from "./integration-app-list"; import { TIntegrationAuthDALFactory } from "./integration-auth-dal"; -import { IntegrationAuthMetadataSchema } from "./integration-auth-schema"; +import { IntegrationAuthMetadataSchema, TIntegrationAuthMetadata } from "./integration-auth-schema"; import { TBitbucketWorkspace, TChecklyGroups, @@ -642,7 +642,7 @@ export const integrationAuthServiceFactory = ({ const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId); let octokit: Octokit; - const { installationId } = (integrationAuth.metadata as { installationId: string }) || {}; + const { installationId } = (integrationAuth.metadata as TIntegrationAuthMetadata) || {}; if (installationId) { octokit = new Octokit({ authStrategy: createAppAuth, diff --git a/docs/images/integrations/github/app/self-hosted-github-app-repository.png b/docs/images/integrations/github/app/self-hosted-github-app-repository.png index 6f9edc56e6ace371516ef372c2dd90c5c1f01b2c..edf1d10870f2dd03ecc25e84e8c309b8be477396 100644 GIT binary patch literal 375523 zcma%i1zZ&C7d9ZN5`u!Dq=dAR(je01rF&Iax@)N=6;V=BVgXS=rKEciLFtaALz;zM zdVwXr;a>IL>-~SBs3I@V^w7=O%GLplgQNT+(SXQMr=2>(BraCg1{eR`(`o!y zbh4_%yg|Dxqr@sf51(Adzamlles){|-(lrr_!FX*=uxAqH}(~-5P;2iMiWIjvykxZ zhC_JG&P-s>@p4yfWorAipuwS!aUtsuHo0V|=!LR;&=(+PjDs^gu4XqjPad)}I)s{v|i%GOldGw$lC7Mdyb6EC|eM|$+!ajq)M4O1z(*aH1B6s{aD%zVl;+rG}M$VnR)>s=#d_qiL~ zl#WXuPVbW*bSIpYiHy=p=_&WYkdPe3jVIOj`|#u#B*>nah12Y~U$D3)lJ-@{;wrrF zNa$|Fhgp7?7J)`>5ILLCmin_(a?J6}pUes8H$ z(K0xXVmateEGe3;^p7u(ok?a%Eb-4adx8@$&3A|Cjh~?pnfE1{pQ=}fyt?f3E}zth z^1=(;7K$en{e*~Cs0+X3P4kmSo?mFITl*y86I2KvmtXYWp`Xpc9Au6kK2 z38*s2?cXvvlhhv8ANDjzQyf;%Ymyvl=7SJY5UinzY9`l;=vt;Vh9t^C_?$$;QpdQw9j z1;Lh(-AGAss(>p89+k1kJ1DOrGsEuii<3A zHZtD1CS3qVT(t9XA@?!5X zqbrMM^J=w}X%n-zWY5>UIrq&RZvr?~ajVHD^59lIuQhM8 zCtRtdBBSd0(lDgqt;9;{8Ls~TQcV*dp3;)ilG8%k($J#Q;`M~aHRu7$>Z^6->37PM z&l8lm*b6x}*kP<@w>;yeZ*y|fa*J^iaI$feB)&}ONbur>J*>^$RbLe}f;q_Tvns{; zEYL12E;uf*Z(nm0Jrq<3eWI|H+wzA1=MLv$f_R5f2ejh`7!1|{lP}tUgSRCY-4>x8 zGzpBHfx7*=C3=rPsO!FZ&!aQ;#!YoGy5j~{qMgd#TXvnD_nq&BhXjY750QTq(j(HV zps8Zn5LK zRMutRjW&+uy-rO_jpXSusjn(8RWCQS9D6iokz@b0lB@h7In1W{ zQ+w&yBlltI3eSq}Ple?TPo9t0jFGI1j8??3L~dVayQwGjvDy4ao_D(6L7{Var9pGI@i4GJw)#1~Q_J`Aje2@Z?3`4qXo z-QlK@pn-QPCQlRzAzX_hOw-I7YisIWOs!4&PIXV|Oy*BYTsMxq{Z0ED0eQ&t##Yl9 z3kF81Dajp4a_`ecFgkIuqBGyRVA$|<)X}1@UZX*5+N53rx+2Xfody+$YWR!6hv6|N zUB})56DJvW9bcz(O?4%oMxQ=8Yd%FAWfY7R=-?X4y2z@?nq*l$@_(c-+srhWwVO4b zb@~V~o6?kbpP2bEGq=3>XqW?EUDy=k8iTk*Ih#5gk4OQ_x@)y#^}TxAo8o*PlWVS+ zTRbdJuaLfCileU)-ydHtnQZVz zdaL-mhZuipd7AnZ^8)upKBYu!41DBbn(^hX+?HIMX?abci`$aMo$VU0B41(}Q)r?DXtplE0d@LYsEx3+MI# zgpz;IJ5WEUpR@PQFRxe=-M!g;yK{x=6aKXjgB0eJG=Ujw1*?rVx-QMG>9n^A@p0}C z-g95V&B%HWCM7joF57bMMHg zYrPKmB>Ps@uur_%>suUc@5RuIfoUkV5rzykKC1xjTpWmR2rOYeGYGwekmbCW2a zrX8=IysqBVGrw0B{U5WdE>Y45@d}yVbAF8AZ)zN(&Zmxukf8SA9WTEQ;xU}8Z1HJ7 zVw+L*W=mG3SL;-5_it zVG&3kq*J=IG0thvpH!3JXsl$!VT3SZFrTiT_CI;K2jUXoa?(FCKottSH`d+@xZvDe z5fyL)DMIVSHMMJ7_Go8=x5;EJpEtj=lCo;a8CuKxc;ay8dgHJIV#d7o1W7g*-2=NT zVPZFFZ|6n3ZfqVgqH5;{(VB#MYJJZ5CXTJ;_4C|MLS4YJVl&WMV}VH7(cq=f$WYJc zJY;(Gx%7M=l-8_=Frt=19wO|*m5d}(1CtBG9tZE6`{`TNqxBdN((q&a#g;Erp&XaA z$kHicYZ9=4+I%0?od&`A-btGmPPP&^y!OA;WVu`S2=->y&qC)$6?!9-`0nxvn|jrm z&a9359zYN?IhiEgkLnb?f_GH%jg%&wvU~=CO647a&r& z`H>>JJGzR`IgKcrkOAK5gE@q@6E%=a$OuShoFyErjxDc(ltCSh@OF>F-PMBrQ+j|X7t{sT3D7bl3TFWr^P!X>Ff^ULF|L-|RWD%p=~ zcmYml1Z6k;wWhs;9soH-64+41N<#yO3)m*cA;6`?xd3e80>3!8bT|ZmZsXvn;@R7me!A|Zr&K_|D>-NA75*KA7cN`pQw(~z+6>Zi{92~qUTU|pBLk)Ft z3ui~Z$Cl1dz#vLayv_r#yM>#ri-)bV6Vv&1A3t&S^pIj< zIls}bpTC|H>}~t^ot)f%ObeJG|M?OAyL@-}|JN`NTdV)eu=68-4f}Imf89><{9@vI z?qD~0XGce{lZW)*5|{k*PX9Xi_jCR=@S&|Y*un6DEilp@n3J^N9RZ;q!+t;XKZhFq zJ@l^V-8=sr`j12Z7vxDck5cQmFJ){LB`Ty7M-$xn#JxuzpkP!dfAH)8+ z|MxLQ|CcfU-2eL+EjL?0j*rhDPx|LQ{<-hR`I7wS3h)nw_)FXV+zY6i^hHVjU#cs8 zG0pK%8V5%fN9BQ>t~c)b6jA!sua%$YzH3VMA9DJ*&I zD^K{92eFaitcj7T(Rg@xaqh-$WW`#%Q@dR~>pfjP9jNVM%#GaIy4qSKGNYzK-Xw#IX~#+?fcEHtk~3etj5i3Oy3Z3 z7-yvwv=Yka2f=ytxDArzpOg8BT8I$`tLWq^CvxefOJ(@&8`0kNuP#$x{P;NyiZwI) zWLIXTnQSDO>sN5eMc9R71(2*lhL!qqc`RHRQ=ZZ+a=J-c|#Eo8Z3 zQ1^qjO4(93c&P2w7DFiEDM3d9=X^;CxHAdA&o8`%$0OifTB|Xs7a|MuFoNFOnW$eW z@iwRL<&YKmYhW4R_J2OZpZ}N+Ngi0XF#$J9;4vyw4U0@+bsR5W!bC5KQubWO#Xsf6 z)!@o*%*zmis%qYpaXKmTHSEa{+i|APnEy3Zg!<>ej!Jtk)tkVGe_s9k7Q|+JL}YCk=}!W@sDXS-Uoig)VXr+O`HpVS(CfrxC^&`Rz> z*;o6ZIy0di|N9}!uz-T~Jyej7R2V}<$iG)Rwv<4~1#YOT!U?fp<9zu3lVx|3*+7n( z(x!h0d_9sZ_!F^>_LUQOADZ;!v=4pdM7ke+?cz^`iH##@lg*4P=ChFhTPlBU&5G0X z$>8j*537CD&u52tu3uMs>)ISPu$*Ge>Yl{2-T$01)j_RT@bF2oMe^cChHZ_xx2Yx+eY)%?hDrx&ZC7 zT>mw*Us|XlHw&z~z)G64e?|w=xt^IEf?6-x7+cPWN5iq2fcBya8uvy_*dQ5_Rz`wl zQP-s>$Ciq0(iHV8kHkHZ#=%`|mdGUDQtz!NhbL7tmdOSW8~tSJim+27@P@0r+7AYd z#?tk9KzwD^y-8mqs9!`k*Xh20C}%fRuv&1smkhG(&5-ITHM1SAtyt(x?&UGBcaaMt zy(HFmtWCORMn-4@3AOEsK&Evq%RWahhZBL#mQ}L z$~6u0M7HAvDd|#v`uZn_d6D!I`d+Bfx$-?d5-)%F5wR7FUXrm(`c3(;`W{RzL8vb7 zneeOzS_!1n=GB-VaQDSNTy1(gc+sh9*lg)%kX(Zb7>m1eioW3l#Ew+8%s zO{-lp)OXvzuerwkaK99hIJ7IF{n@-f&FkkfAyQ11e4%d*yISQRg49KZV?#o@Th#0+P z`3!N_rxijQIJ8opgp4#)t(Hd5?IFzLn?ebF92kVWKM6Vae=)+0q&aucWCo&mCK5gM zXT6gOj5ZXuqytG+&s@LYbDGyz4}LSN@joo}KWHM_-cn+$F-Y@$k3F>^=t8{zqj|O1 zpf_VX-jfWKO6g|`y2V^k|W3m;jO+HuaT&;IU+Id%`A_N zk!~YvgCT>~eZV=4=ci*Hwk~^6-2V!LO82R6`@X)-O#yd}&s_?qyIzbX)Sfh25w?eB zVF?CA9e;D1MKIY1VVB+H4`0S{>2Wc8pN^XmMMui2(zL~~MUZ48W+)KFX1vzD=`~C8 znt+Lb+$l7FuH$`bW%})m_3;0gIWg4%Ade3=PVLz>-KOiN}Q6db56i_;ZJP zqr=yWR1RpAgh7$1fa8%zW7E#K{)Js(lT#vTy!t8VGi`pe+(;ht(iUf6#D_qez*;Rv zS^X2p6s#4KOrig+agbJ~1qH%>i_HqUSI)wR4#`R!z*jSpUjz)WVEk)BQ_Qv8DJzSbxi&*JojXKeg$g zyZKfQCzzGvQDE;1COY8k;ZM~HPGFJ6fvVQTMPB$%n0`Xig`Fpl@mw9u!x%=}&oyFZ z&?Sdw=7DCYvXBLk&mq`$IQyC8*`zze1f%~7v-M%(*$Kb?(jfy7`M_$)NvZl-{)cXh z>J;#@P`&;vluHsJDV?{6L8FtIPk{mdss-4x7*w3m^?Huhbn30ORvz^JzNh%sA0G@q z#OW3o_FHr&aO$vrG`#!4Brn_{JEIxarH4q=Ij-? zGg$(Qs0bNvHWC1LEcBZ(aHpMSNcp9El1ps{m3%S)Vth}L>R*yswI$fB>jWTDjuHli z(z6Qrq9HoNlcSpGHUe24PzcBnA2#wb=*f`cb~LVVD@A~6JyaNcH{}lf<`q@aM3(aS zcV4d^A8PCePKlO$TbAYr?Y*aDgAJRAoXro-e-v{1PJ5@gv&>38#-7GH4SOABAwl~7 zcjJ=?24G>TyR5NF+)a<>-KqQF6JA%H|njAuBLjB?wINh{=TAOSio@Ew!Y9#$n zmHVYy21`25{#y+FKjwEs&$zQ8I%?f z82Dhn*i0_HX*lvMl!#3E+4f?NT_V?#-dp1eLr2QeC(AuBhB~cEfrc}2Xzgymu`9>D zDQO54QpaiuiV5}Q)!pupmgz|~%)&)aFV->3OX?@`>3p*oYxrb4$WHDzl^c(nP0r{g z8V`7cdz~+YrI&FY7j&i48h-M>POf6`b4ov)sEQ$z{I}O6JE#|%DhD27!hjTT@%AxM zCnxcEVJ#HD=F1$Ek@hde`SXZ&f$TiHhUB;0rty77e@T%8!-KU>{;x1S^R%m6y2=cw zNuz-4GUk;I6IOTw=mxYj;5?!RL#-?ZBA31TEl`ss&E~t_GEU%Z031OTl$87&)KJ@X^43#+aniqZX=G?b;z1wE$RrQlwaF{M$h<%`zR zhEI>0@apWQhlfC8)sI7aHCnaOH*3rd*hdbI88$n@9twQ1uRKf!d5ge{piU5L7=&@c z+Crb@XCVJeF07YuC5(dnSo}-xxoT1ZsID;R1Zoj@#ySz~^8Kgig4BX=d}#>v{*7$` zl~6Xq13c)?^;oM&@^XjidZY15+gnP}H@9lk)`mW4$R5?59JMp22Zc0S(BTd4v@Q8@oD?6QAY`H&TqEy>&t6Y|`9un(90dnP2+Tjg^5r zsbj!?k0ZcnKGzf19s@!@3>>}&EH$Y03H?u_|2eU_t1epOQov6n{oZ5E6Vkj0JfzDJ3wKHuK}FLkB3ZO+P_ zql|n7^$M3)ECRmkhGm~1X!DqjD_5>C(5^{|5LRb3q2Q`^21|aRiRYyBTx>6ClJhdW z?8(%s^J~q$g&|4I_n7p8pmFgVu-cUZUn&aBw$RFTkKY;cFI!v!@f|m5FZP zPE|IfQhfY-JxNeqfcJy)<0G8x9R-+%4!i@-hMDC=J_8Lm1RnjrQ_zt0-C7O ztQaL(Y5NchxOl0NLz6z~4Ah{Kc3yP5l*{LfNsPPQqPaDMZGk&`2m#-r+lTg3;w6k` z1xDWob2aQkmaCk`SaMX8y=u=^;!0KZf7nuud( z7AlIJybB=C%cGjj+=<`yM|?;-sv@j1Gxw3jR(Hk4jm?2TY*b;F=zq|!Ats1hICWK`@AOW-0Y%^pxsT^BFIcq{lvMITup}ct=Jv z9*6}BAe3j1qCw6N8UsQ13W%cdMuK^r1+;@wBXu+$G8;2|t`!v%o6$c-_PfsfWj>$x zm}GHI_FNKaZ~bl{oDXF~C$N$`k%9uGhQ*J;LWqJLuZMMI{U6WKL`i8;U6miAPUh&n z&BJ=L@)@{uqa(j6Qp8a*`YrB}*U}-na2-?Ja9TSk!o{T;Ms|bU*$`Q2*tA!Ro`7P- zCn~n*pOW-!Pl~xOY;k0`Bnhuzn`2~>L}$F43y|Aww+6}#_^s<8Y=C=Vm=Jz@G6jJ5 zPh1)ybTQG6iVf>2`#qy;!1?b-PbZ>Fyt#o=gazz}<>U6H1gT%JKzaCmexXwbBvj3_D%JPT+~ z;EaEus3<;BF3@_>7f_OXL?yrvl^UqL{T9{TX*BoICJ0M}Zdfibs&q(M5yw0Til&!% z3CH8)HYiGH@WZH{0@%QP!+LkL#0_8=`Y-R+xGhq4@1pns{zWK)WDGHtSzJ3FMJG0J zO9D<;Be>;<7Ij}zH!8D=!mPz6Q=N+-fv{mhZY!19T<~k_HDWYbH3Y+G@UR{-a#Vc; z!Kl#xXMVo|<+*@@k#a#eN60xYLB-$YRiqQFmduw@umK7@@$ADZu0Jk4cXYRi%>{Go zLcecl3g50Xh+){z_Cb3u!?w#3&7}PH*BOuvG(z@Ja_)%}AVEvl@SWyw*bJ#Z>5=FW zM|ZrsrF2ei#j&YTqcyA!w*Ub0MxXsSJe=6N&dLkZgDSdl?tU#=BVEVY0IQ;sNwhxN zeHE9Zs?wb*d{SOr>pLGtIxw7Aa=MoEbofslNRha09=clPFzwKAx>b`;*hoZ$!^rKO zvA!d1X7pd8<)8k@<>cZ!c);_Xw%-^M3R$Kc5}T2IojlF<9+<@9TXLC%8yyL+fUHXR z;S{JpXkWa-uDvRhsB^5$8Y&{;`u%DBU{!Is^z zv_c`7A?+L*HKbx*91{f_4s&V$*bv6q-zFd@oq;NK~UUCt(MDdK7$9(uJvKA1 zckR9*toO6dKuCiE=8Wp>r+-_1?eL%zlWt()i`v6gllgcp6k~*1rQMez_e`2K5DSvp zM{+>?=Z~Q7frK6QHN(J*9WpR5x+8t8tRRocN-*CUp7X}W4euh}+|}Er)#0ls<1!ETfg>?lf!jri>b^T2O;sq7Ok`aV5gx zKqm4AO-E6Wbn1p#+1zt&0AKpI4)Poy)h4msZKXj}TXm;1!_07Zqs+$UFOa^AX&0Xv zxVe?dLaFb1Q9yNdNybXSWe#KYW9eCy!%wUW5HhKC z$=xA)F_kxV_mcNn(EqsdpU?JGZ#MU6PwEJH1cZ&Z*8DM^JWoMPfXh2)hn~;}82di> z>82^FH3^8b8a4SPn-zcU`ELTz)F_a2mf;)K&khNs6$0Eq-c^ z^mLESPu%(QDT0z^0npC|J=(R}_@ui=}h>bLpAjH1tr@%<+(2c&Zqu0E_3%ojs{@v3vJB9`3CVP*!@nB zJ%Z4KeNYjzVrI>C-8$bqv@sCI}HlL zs~V=V?mxS6o}-sKjJcf`F&f6vbpg_Ly2VbF{AQIrv)DH0=MMjnmk_|)P(>w0|5qCU zGbUD-y)d)4NUzM;HjUpyl>OkwzoSL)(~FV^pD*M_#B*r1+ZQ)5H#ahJ(OsP>GBZiJ zGsn?5Rb?}6n&Go#+n&gsJO~7G!BW?G#nrvhd3KzsF_)a|;5J6+0elEJf8d>p#fV*O zfQLudwhBR2InVILcx>5{O0BC zDh|n7Sn^n)_As6g!vLVE(*P8}_pDHbaQ`Ih#vWaujQ>;rBiq2dLbICH+@tN0v@>fI zvmXqOY}o8LGY25)a$R5AQ>%!cs#zeov^*-;4iaE1326!yI2;cm4AsM2K}O zCv&VDfl#cuny&7P*AVVo4N1IdXLr#@y#*ucEJz7c{+U8P8J(-82H*@ zN9OD}qW)l@b9-WPEKb;7zu#dOCO);X<4-4SXG4(IxO^pi-O2lC*Vbocu4fxFb0dA2 zEG~2)(UQ#K6<77TFW5wu$>6GwCbUr64{T zd!P$;Kdw(zX^DH)cUnxQ+6H#5yb5S7q!M88t&S)#uIN}T^grC*o{DW^h{sEhGT@3x z=6U5bf{$BwjA=Z3m6zfF#eDa$NDebYcG$Bl;s>sBGRvvkyO`sDxM;BbY)`dIyV~W- z;7P?PZ1j|@eq{O8>yh249|^-*v}~8|XyCHpO@jXo2Jt992@a4S9jWyrI{78-&G$>; zb)l;lR^r%ydd8or$5Wmxxi4Ood(MQUA}3v`QWN#bTt?cZmhF`J&ZLR~XAJ@DOlF~p z!hR6!goJXYbg#JF0#M*hfXw)`TFmfEGp^wGI*;$hkc>FH+e;koPcZ8%qIGf|^YwXi zjE6t=1kg)Nuj2RG>wA(CI*)yo;|iuQGf7dCp%?y)SDMmnN0|N>?hXJDyO^QPRoT~4i1_0#GmC2%b;#w~#YnINS$`!B8dQGP5 zm}YOE(?c3?*Xt6^eJIpU7K56SJo4KcJ`-!&sht7h!r}%T-FB6Gun}rDj4rH_yl~hW z$*>5_hWY>$2xAwgz0bj7lLb#YKHP4n(%SWkPQIl?7UPN@Es>W#Ua@eO^eYXU?wv7g zECxzfh_T|iW}|MuJeTOR;OhaW5**!_*< zxm${DC*+crA-#K&e!JDFV)Xz~*mDTooO@pCiPRr_PH1?BIVIA-*#$x^Y}S#qn(tv& zknIi@9r)UHB_v}xzqo-9;C!hZ8R?-d|S~HS* z@#}qjSGHd4hB1RZ2py=fp~jj_OtaHT%D64u=6;X8LRIgC_CrfyMu+ds3_qHx^<3H; z=qxtGMLTyE59X@OK&BI|GoU?V1{@Eo)zU@^(-mNs`wRWZEpjnongx9-)W*B!ZJ9ES zAME#!0V*c7)*OQxk?w8W%=U>3nwGCEHZ!iYu{BtPV^P;&>2DO!u>GnT=H@V{b95dR z>pIhs$Lc^k3^KjCZjhsTEpNKe4`Nj3Raj#!9D3ZE>CcsKP%Od^Yspf$u(y{noQ=TL zEStvyk*xD&B6kkLq5-@%l&OIYJUvtriVyH-8+~-}XrdM3U-=8QA>w7nk+z>Aul?Ut z;5SUg9iN1OR#0`Aj^ zI$7!~DJi942uYn>Q*FZ_67R>&KhUn$d8~3hyGSDt++S;cp{2~K+b%VdR!|X0jIBgP z(Kke$%JJSHRGwWFRekaPwsji)onr1<&kZ|)Y~pV0)K`Ov>JeLNkM2i-&7@!r>SO-K1JhJtXIksV z;g4qB)o1M-C$P&~`>sMb4L&1B^OMg=W746mX~qgnmw+orPEKBd#0Y z0|sP)c;70phCoZ%^%#dD#)pK`-!JXc&@QV(S5~Vl;AE@-TMBuD?1}TBaQGyG3czy zMiJW0Qe?Dgt)6LB+J1Jp%ykGPdo$-nA; zcna*g25LHH%YGuzVqaG^6ENsw*ED>hEv5&VXxGVAP3|F2a}@t$u61j^%kpA3lZ@^5 zRlw_RF*F@4NgrXIIU&uYR+#|&qk^tNbH>g-|C6BwT6K!9Z=bNbYV`V_cq>Tv2I+-t*lyQ7o8J^R_t;$kw$LzLXlOfaqS z;CrWLBd@Vga+=deG>@MF5b3`c3~&%0aA7fwF8T)V4Vyk-^KEkX{MYY(9;`3^Z8eKblYsVdzZR3rQoU~1qQ7!03LDY`&$(os3-Ys zaHu79X+kogA`ca#80JkuQ(0I800El&&-obD+XPR#_fBd06;1}8g_ip6*)1~+c#3nr zHE;0!ri^~;w%D<{mi4lc$tMsQx|aU!Z}q=V=<9^{{}=Ocf(`LfaZN)9HnPViPOf!# zIVBgGRHX(zAvHvF?FLg%XRG#M@y*z1v+7=_7aPE6xs4q)M$qte zz@gZUVYl6tKUO^uQtT$DQ;-?9JtRVKtfitM8ar%oW(`h}VHULRcH8&auUXch#!gIB zC4bYPQ(06^)G(P^2J#tJjWwa|qZ?<-<>U~BUhw|9n11d_SS}KC)L>8G58C#5O~s+9 z3?w{Vl`IM`!;6`Y>V0d_1w`kcoEu1>~q?{f_-RX9)uyI+;E=gSbBv@uboHpeZu3+_m`8&88bhLA!9Uyw<5U+!%k*9cwP<0R%N zKqC3j@CmJHKQwgJQiIH9vbw~E-4}NI4Vy-)(Du3@)N*3PQPb-15)I#Z;R}a0<3ZaV?qwzY#8RV~{!+tK7Y&}3Nw5mP0 z@c*}5vqw}b136`aD|s2HTO3;H9!VQ7trna{KLwNcBC?!FQ6oUsr-@LXqzhWlx49GW zisf0M`rZeH3(FNerqvIH@@omF4c@!FwVADeyoih}5BXANe8LzH6v5hnx|f&+8H42Q zw*U{BbfIvi#?GY_zFY6R@2$%aaKK!KHG_C=6K5e3#o>(KVnq4PoCe;N)MGV4RF4X2 z*Qo@9%wrHhj~aNSi&np{@~i+o?$nu7s9od6R;Vh){mHL9hG!R$gvi8R=CcTDG0(tj z5RpA12LHBsI@?Mw5bmz~Qjcrt4pJDS_ffBqD-{=1d_pc0NkbX}s_3{rwvpwwUOPcE8%#&KBMcx@lK14^ z)^vXt9}li=$_S65`ToHj{3nt87p72d$D>m=Z!i`XY$??L=13X|s<%`rK&bIIJ}K?C zZ+_0;|CxELe3elr=H*Mb(j18!g)a%ywGLeCkM9Mf$L9p}OwOdUqjxuuLmTIWIryj? z)D-{_f)ET5@mx}=X92X&&QfAA{OEp$|94lP?_1MxxBR@y0#MG45*xd= z#1-}kx1@@JY#(xR`9dSq-m!10;w7J_8TV6Uw`No&=Yu6Yg3l zrXZFt$n1<-kCiTNck(yd3F-)#`Ebbth!h5$Y(*%FH{CDWnP3CzgkHic5P@DIjc;WC zFgVMsnB;K6pF95F!RhlJTi=`J4feOS(Z0t3aG|faIz3&^?AHFMt5UP|?S=*p7SQR1 zo!-V+fCK5Uyo$!4B-jNp2U{|#?-CPF0jQgptC99v8nQ9Y3$SD&p53>Ljh2P6{%`IR zfZM7<7w5I4?;=x$oOpUAcgo#0PYNAoyw2&Pe)WUYt$<_l`Gp3|bn?vEfxM8-;fK78 z*opB9K@CLl*~GL$DY%;psAvmz(!DM=ni39eNJ=*M?I&qDTSUArm;>Bj`hFs}UXoI+ zS6RrCXzIS>#55P+^+fhOk%%-1HuK!Me*1{K40J5Aa2uT3I;-|!Ydw*cZ4h}Wc3yAD zd)lF4aex_&1B6a>N7{3(x77J8z_xFe`h#)K%d*b!SGQobjU7Nsq54Rm=ZN}Na~RpH zH_dPwSW91#qY2RZT-j*0n3u_}+8PZ>-4OSA10Z|>=(o$Ag^@y4rTcj*@!uQ<*S91f z8v>pU{2tqi=a6bU=rpsVV5|(hmCdGIKxUmokY8@}0he7VO4z`mUd!eU!zrLgv*3VH(j6*+%a)6*GQ3Zf0rV2Z9rFu^D zy;Y17873XsLsS~?O8G^vZ#P$OQPR`%VrI@jocaat$8xEt0#fhw4;>QyGHE7T;&&a? zDHykbd)IpKe(nC5F2tqECa&Ezg6Z>_qz`FE?fljabnYsOByh1+sW6FRt4d9tr&}_S z*SZ;sn;JclQwx?97|;4TanHEr%)k+cqus&N?TuKpdV@yV$oA4%!<;=$ndXJkI+<~K zq2?-}FZl#0!LbIy{r5i_qJd(SAnrPfG?jjuEF4l?g|zNTeCdqa_vtwHhW=OhujYg+W^{uW{K7UzG}Uv?mG#)qDTpySoA|-JNh; zI@wCI>_}+mv7^|tFFwS4!t}eFl)J!Eqw{V}O$kz6 zMzQaH%Qs=9MK3jFy-%Xf+zYor8~yWt_`FlI&Lka@FV2MT!atZd3tH3@enu2C3feXq z5COHKstoGQ@IT3;0&1N+^(25U6i3!`6OrAFosgJZHRYHpGCFHy6cOriwRbtChj@7i zpj(ASu&*a79h3K~AfIR~rl@)d4HQB#pg^fpBx;ZxI@~*>_%dA`-bG_G4QjpS4dA%MXUBkd zVMr?{C+$Pv*h`!b_~bum#oHw!l}k-uMc87`bnxX_#5<#%BnG)LKtr?q0rJx(t11a# zWm9n+rvh7}=?74i6H-8beiWTezcc{KZP%KPEi%&@p|z3&!@G{o7?DAq!>L*st{e45 zZz~5s?_9a1NO)7Sxb^zIP4^uk+=3P(K3tWHdva#^g-CK^x#L{Ap3+Qwx6TKa+T&k21r3{{`s_UX{Jq<@p$ZOgA(9ea}4{R zxZOMYMB)@(=h-!KnN~m<=<#J$Tk0yc+p~-5T65hf#_Hu8>+Lg+@&lfEi#Tq-3e*%r zkn`ZhZSFq*x9c;FGax~0D1bQ^zTN0dW7^e7J9Qnweza_lQvkrnwLYJNahY_aYQk-1 zpX~(^Dk7m+NoKad(_`%~zN$@x+{$OOO`*7u9NIOY$B_5gMd~=mi7FNU0I$~6_A{X3 z#|Ahb0M@4l#e5h;b|y76rLM=0tFw+)@t-2|<8STSUZ5?sC^D|#%JSnc^UT!$sN1j3 zVp#G7oE}fIewQs7BGAW?%>C8p2TYO80-z)jmjci;{kQ7=>3ZaGu`#8Rlo;{)gUhu4 zkzHImKwxXQUCz>Sd!0^!M~u${^c;QG75Y(h3btg46;Da$$on5v<)<1<)Zzb`Ogoj|8>_ScsxYeTkAU~^-F)(d@aLV+@G zjp0PSf#j(!Bl7OB4;WJf6L9&QH=R~I0fye(+u?^lk?IhS>VgTH5u2`8>M;GlNrQ6Z^ z?@dd8BMR9NeBvxE3Py=v4Af85@wt(+ufnhQ9yw&|yMhrGL6;(IQG4^=CmH<-AVj7B zX7cdU!^bL#T#2S|e=+?!q^m-ET#hV`fW=#o8+BldB*Dh zcm?MmnLsGK@<~p|0Jc3Z$7{;BBsu`7M*$6iB`eqvpFj#pG^KIXK0nan9FtyBdf5B= zG~fP`9zGt`ZS8mOB?lUw``E%lWc~4~gd8kU$tWp?h+@u(pCrS76#2Y{{E38BvO;%M z^I7z78h3v1Grm=CDzjjomS7anb)fxo}XUZeuv61iBHb@^}T@E1l1MrxeDB~t3y zX>|x*vs^uEf6iW3@7M=#hQ*1wTlw9c#hkxg)ni)oKyaK$2cQu6Qpzkztde8L!`uRB z1;KFzMrF@DB+)RBf&0-nUrpyrNeMu{1p%mR4pxgs#6c9aszx%gQ*(= z-4=W3ccE96&u9fK6HG^>J|eyt^kb#d5fTZ#p~X9H#e&kVkxf%0W(e13_7123`IBRy z!QiNY40YOo^yLR{?Lglk^tw;XKxp{-q6;P^7JGZNH$p0`db$kU%Xj5Ua3JCQ8h4IA z%>kXo{cpLL*Z`$9h;tU(P;Y7DX|oUPgg$idr^sa8sH=fKZ8vFX573+wSAsJm(|+*X zb?wJ-3bmliyCuqo!GFv0$5y-1qmG3a*-a2p{r5H@TF9Y7enION%Y1~Z6rdkhIkj~~ zjvLJ3jN&a8?`yS?CKE3S2gaL10T^^w?hqwCDPbFH|6D>`wdDIBJ<>FMrm;YMxud$| zZ6OA#=`K|)-3xz|Lwt=ty)Cy!F5HNYY{V@S8q7V`<_(tw*wlZMKm{!y(0eFQ*WCY$6 zEv!#ebd7G(XJP~L+K+{W<%>iAJfnoykYxL3EGGe*T4E9r!Ozx)MJI#ip zf%mRD%c-k904*ISoPV0|Lgr*;SMR;c!fU z=J0?bcdVS}wL|gxg#-m;)^CkS zSasDEq7(QD$?kZbC~55a@n}ug_f*IPp4K~zSId2iq+>QFFK5M|L#n^gu8-DZKN_4_ z+1f#?MrYh>%{cO+XoUy-4ScH*iw~tc;Ya8cwZO*3i^ra8gCb{wVaX=aGq5(MzOj)>Y%Ydbk2 zrY)}{9%+)A4ns)UqqzRKubRZS(QghJTJMUH8B=mw?wP+LSs?d@?xsn;ml@Udg5ZkW zhD1l>(5n?QdVxg=E6vZleK9h?YY(D<#4;|kK{i>1W+75CF#Ju+%w^WVQ#=ORzP(ZL z0GQz?@QzjgXQw)w&375t{X!FfE-T!(bB9m)?Z$13>c^^&ysjYU9Tx%GBejeCeZ<`N zBiBdaQ)5cp8vlpA_Y7+)+uMhwh@v7YHc*NM5b0e&nu?7oD7{LTDoF2Q1q7r@M~bMF zARR&oSU_s%0YVax5+Fe6fk4QAWzOgv$C-1^HDBKM!!sY|nz>+a_TFo)U%&4=rCh}6 zOrg?rOMJdBz0EyNHW7o@m$Z3P(k&SMB`h@ehN=&B3ndVobvC}$;R`!va2hFEt0%uoIdWc1H*+`Pf7>wSzVvjXxQrcUIy3%EA@YA#}h z;y82;6`-c}fp{OjYjdNV*tc2g6RvBM6^YqvxMI9A%_6G+L+TdkJA)q5nxvYG`bek4 z!BO9skhRyA7rf?EhuyJ3?euJZwsU#}cC>A|E+b(?Y4p z!Rfd^@UIVduE2?_&1wKo!Tm~drJ&5uZRDCaf&%VEV`jE4yGaH(DBRQp&69)?m2#ZIU%wg5amwRT5kMt_6 zl*HvT#MoHDQC20n*s255HE;6VS0%8TTTh90DY1i%axaxkr-3mezJru=Jw(A=yu3!tZR~`IWK1|HfY5`KH3Q|?x%tdkhfYs$24*iy6_jNx`$>{fBt9KMUTtjNY6 zrYoAs*~fI3>@y{k^ zv$PF$N!c+`wf{Y_nxX8TjH@|Zjb#7OPS@2Wk40x`vfWmJ`EmH+mjGb)b!`qcUP$p% z4?7kWv$?$)Jm|7sOt8wAJUG_=<=_wf1DFjva0(?5QM$xd$(YmDC zA-Gr;kwJt`U!%MW>JglrrZGf1&h`Y6zwD_a8%ZqtusD2to>pj5xy$epdFx*E{m`o~ z+AUVn(=AMbV2WXe*n^e&EbJ?6Q$F?;Ta05(dwsa3zHUXVT1)EOJlBb6T`>zvsCKtW z$}^lA-z(_LY+pUnat>Q^=Y(Z8>->}btd8;_7O_cH+LTF#tPEaq8~TAN-SSz+QumXT zoE!oz!Gh<3BME+A_P#~U>dGU@eBB!$+lo7GK8m?mZIc2@Ip6Dxw&JB5q(DbZvhOa1rIBUu(tY2xG zFP2BPDPyhmwv63Q4hNC)z8{MmKet)xkKlGs0iirhQGZea}#NxT!d7vasL=J!wAuq(x;HF-`Z471MBeYjR({ zTJ)vO{a&x?O_@$(%S3r%-6r1mrQX;Zw6&eGCFW5AOPP|tKjb^3yqBNr!l{W?grYcZ zeExFiv-~>{3*G5zf5ivSN)34Toh%jW#b4RqepvVQU2X$s>y)T`tB%w!uk3XRHx$Ws zv~}e$*%{nSb6$odG_jON%Wek@qnXS~j^KB_jGuR$uDR?Ed<%ia34%1+?9Rd!XvTS$ zAWC&T=dQD4I%7*~(1FR17|_hKl;_QLg?NukpRsskvp527mCloirxko17?@%>h$|n! zxy{_X>YY}W8M30OFC|mRD`cm&{+V$sAds+cmh$1G?BUo#b;x6d*UG&2?Ya;RS6YXK z&OBv~O*9Mm6d`>6e2XbNUjAgjlQD%oE6Z8L1Pmu>qxUZM@_fiNPMfZ}ygh8+3E4(|gt=JDu*w$E}%+a5!9Qdb1r`xBW4R%X4d8bh+Apb}_F_vXfvP@bP0a z3vZjnWwHPiF_IW^Qh1zU5+ zI~8$Lht4vn-GQn|TpnkTD`d?;nB&ez14ZA@u6fRSktbzNgKS?q+*iO%g)Rpcy6T}Q zw;%}+`W?=%Bl-phuc^>|^(X-4D(GN0w;r$LIKr&cbZ)WEyX#VvwTYG@)NTjFL?XQO zD2#WwVc8~kH7Y%vf%3#qLgW%%986V|e;I1R6A=}lPBE_jxaei3>BmX%Vxre8y>EFH zj81u;NV|PEN;%`~0X4qcRnP2;8kWGo6%5YcZ`bcHNV;Y~9xFK7ei#yap{y-Q@{>%3 zfdx5xa5zt+PS)p(DJRzNT!tBuGs4zL^K3D}Y*SxW8N~OZYgvdqCV=LZ1ApLCJLs9; zVL3N1VEk?tTZ!l`v1*@zH48k=N4O4OYw$Pq-``lSEx%ftqXPd_OOOsY{|J+}cal6h z)EXqo9dOJ$O6;{|&+`*&J$Hr!qBuNO<;*ffED}M8yHr^VvmWi35C#v@T2@TYmt$4Z2kl^L~aD*XC%`4Iu-kIWBCdl zhfeNIZZGU6Cx6ef%wUam>6X*ZYmnlHn;tUJ+F4d@S7_R`3UH(Oj@UZ&ndWw$Sikg( zJ}=UsXwV%Q4%aXd*K*K(Ag6CA{YXqV@3P_%$#Wo+h&yj$7d`ap+}2mkr@`!a>~8*OlZ=nigG+mJ?QA>+ zeW^inSf7fORhuVTt2a3!Gi1#dHv5gBFf=*FHn_R&$2_rY)axN6SJ9OIHM41`-2JKh z*O-3WCclrN3P~TKsqjN*i||qUG;5eI0dOCeo(b1g*2v9suMpvo58jZTynRzWM;;uy zP2f$JiVDLzqL0ZwS1H|gSnv?x{w=$AztlKMDD^O>1TH_=F$eWtJcnaE^V&ZlAgvT8 zG>jaaPxSg;bL8UQJBuz=b{aHzct5FvhN+2%oWwI|N6y{Cuc#}9iwCtQ?7RWWozc|XpgaelN7uMa4MzV;8?t52*j z*-8sn_;9K8O&(|f$r1-NB^SJy<^nJKFzaQERz*GBsHGRvCGYQPR*-b)lVWj_*bB!b zlC*Kypp-M9wzW5he|Z-rZpmase&kUgVs3ePu-i{HV=0rxb(VL>Ba*?If-TYQ0;Cjb z_PzQNtaS5er$DD%rAz$jFIk_rDP6m>G@JEOKb%@1?6q5{C6lwT(pDK1B82AJ_p0#c zBOv0qA29tZ)T$^Xm?7N3#$7P^hC;O4+AJ$8fIS>K_!59E3eQ`+oU;|PcHk;t;KdNJ zyQ~(Z&6+2Jq>|<%Ippus&Ypo-_3a-&J}%#Et9$(QAhZ76SS>c zUb**M+KIqyXeb2~-a3s>29?+rrGlh)bNePi3y52q~)d%J6Q&V`W6yO{MU7U;5awMax?-=5o`hf&g9;6tOot#EGd?4)J0>^FueKX5GIZvR z6CS!o6khMjDlre7<$r^O0}(;!?=+cG`k>E%}n zzo*Asd|+%c<1l0o?#H(H@fS|*wey_y->`fbCn@4T{Y_Z`?IHWe&+ORYTa8jlX7SXgX z?(9V29&DziSry0UVog?}mOb!TD_wROx6d%X9N%Kg7kDl(RpKtSxyQ2tfwGUQ597!N zO@^#(X>7MvAjK*2T2!AyZ;U`7kA}CzJ~sP=pg&@GC{?wi_6rb zXQ}7WBF`8Z49*tbIAdGLd-=-sY#w#%=@=E8L5Y&>F2#k4dja{d;|m~2!!F|xDI-Av zHIHo+kc0#I6uZFRYGh-8X}PaE#`~MvMBG!^21o*Dk~qH{Q>CGQxgx zvu9ohg4M;F_VWr;doz%=&GZ=f-jAXcdyeq4S`rXBfjE?P>tsGw95~~-z*;PeTbhSi zK-M$NnI9n+V0`Nw(M_w$fGeGPUdFS556VL&WkYO_HG(+)_1-I-3TOR@voWRpF8M#M z;mW0M6>W&X*q>`GTs!xUx5OKTf%xm{D_IXVKAS$(L_U5n+br79y4LwLKzhI`uriSh zvn{55lCPWZEOiZx1&=ko5Dh7*$-2=q$>VK`2L=}@t<%3<-e~2~qj*!=Zs0oL7voYr zYOgeB(8V=|B23v0*;iBosw?9`)hnTGlCggA@B79Ht9TH@-r?agNJM#6_1NQz==}oO zri_ZVUhqI`8FH9ew_e!UxG`Z6X>w5#jspV^AR)`U)(Bpl=XJ@w?{s*y%Drzh^4-eH z86KQ=-f)_Cl<^)3W;Av3L(N5Qq#B4@&T-C$nK!ZNQIbW6(~C13kaC`miD~_+8T&eO z4BT(GGI2teaASldpGkpKLpRgUo-fF9r+db|Oy47T@$L!}Klmo6 z!h^4aZ$c2LN*9*)7MER>9ckjNY64w5wm4uMiJXm*2`^4;OQAfzgtDQ&-TycT4cMN{6gE^j5M39}7HrV?27khi}#_CoMCl|qdxoi>{2 zYbU?H?Ah|t2K<0+L6(D>M{0_cjtfwG)S2+KX_p(e1(f}YfaPWtHDN)EqwCK;_4`ox zSzCbYi(T#;8~%RR@9jc>pge!4=rn0bPa=2=rEHdzc{j*u7%v(70L)#eX%#To)UCHT z@RXL>9IB*r`fm-08hmhkSDIpzzFk0RS{m;`BnMA})bx2>ZEIXJi#)A;5ZNbeIDinO z1}8c1^2P_U*%b&A_F-SAX4p9P2RqH-M}A-b%32vQy!GW<=W1Mfn5`3c46vmPY{H{(V?c0Sf;v- z8Fv=_LZW)Ou2Wkpx(jgid`=S`f(f2lRW=JcrKwNM(&%_=n*GM7njko5B%UQ~EFz5g z1elhjtLN5Usm&0#ae>U@FvY$*bZA((Z+b=gx6FnKUyceQzp#RB^1W!dO%ve(5yq2U zyEbRCl6q}Fr%j~2OHZEM;qsCmhx!K?|BamGGw50MNfWwl$?O0T(DWm?xZ|#CIM8ao zNG@-yp0aI)+7*9@JSCIhin$gN5%dX*S1G9X5hS7WA#}UeT6sC^guA-BvQVq`93+{5 z5`_CCKw}MdGqM8|NiU&h{pQVWq1{ab65&vd?S<8(Uc?F)gg1&BzEuLyQ2&p4b7V>|LpK2hMfsYzoUyI_o=p6fuPV9H)@4+lH0CV(3kYpd zbuh!{dn36F1rAb%Obg2fLQMrQ$DOn&6}khPs{uOOhNVNzcT*Gsd|AeeSYK@$S6{*q zka`j#SQ7w4J#V&eR+#PZoQcGUY3TlA!p0*XZishiZcSh7DyTM`-9e7kZJcYs`dgQ{ z;7P5CES`ZN=>T4(oz1hXEIG2Eyj37Y7m-etG0PZ;_IMUwbf3Q&GU(c`{oRXQI}yy>qtnCGj*KjRSOsoc^-X$^1~;z zFKq;GcQ`w{Fnz0N90M!taMWF6_7c$0D^v}v*^A6W&6s5a5_xT&r)Z=!Va?vg5*%7md) z^0V8sgPTJrJ#uxoRXVoRwz8>uYE2&Mm4t{D&L-5cTb1;o$O8m6bMl5QISoIGPo1s6 z5I_)B&fMNznEsU6tUbL5FR6-ZInpYa9n!He_}7;iTFcDd$bwTa+&SVyzKFl_n24R@ zCnfF8$$3Vg-3+QM3RFpY{S@>s%DdYraEg?4e?UGZg)~u5(?JocPP@DzfFg#For%Y0 zJpcs0%x5Wd9zwHDvO4%9W&L$_rQx>`K_nixX6~8y3lZUNP%Wc!!;TgjCoHsmYi{Oq z=y!|}x77dye!bO;4i5L(64K>423KLpkF7-qJ~Vo0l}CO(a0>W8Y0cx$ z@|`YJ*dJYU94u|^I&-a{$&8cnS|SbcH8H`)8o6VFMUUqeeQjyJMS_4qK?J_~;runa zv@->W&pr-!!!?{2??_acmYO<<6f(@*Tk!N(;SI4nN^0#t%M45Oa8tT)6O^Omivlb5 zfM|XGU8$`l&zDDI{xLT>M{A;JS)&YXiqlP98(X~R@utt7J&V5Rv;16Rq;pgD6gM@I zv2v8{x=Ha;EA()SQ@C>``cRAQpc%Zu829YiK3&(Kmd)XfQVaQ?(LTXnS4n=7NRHpF z`bS|fv$U>0eek=L|GmH%a`;R==UMHxTq~}hY{2)z6)01c933IfSOsic@cCDQ6BAe8 zha2U2*YnNldt>QOH~p{wyBh*>rqR_L=|87T|Jw~i&YlNva|kAqdi3X){^P0t^M5IM z1Cjt{2rul1J^Y)O|C`&Ky+w7NQ;$c>{zqz-x0C^UVzh7)A!HZzTb1_ z|MFF?XMs^Z-mbl$?Em2kKGFj(u;AN$;vap!V5LLU>dtf1;~IPa;R;e=El-iLnE&#k zf6)i{?TVPU-~`=R`RHo+4_9!M`U17-E1(tePwo(X1)LzwtYc4l{+t2*k1P290~4T4 zWhs}bHTjE8a8@!zJ-(E;T<4qr-!ITQlKv*yXT?nJ=&s*CLP(CF5(6nGAmG9;Gp2uk zn}1*85D`H1#>sQN=Eu~_@7Hm?+hbhU_6Zj=Q$AYzxA)p+rwQbzc%{nx?uDC`!7d+n zjlXd1&&Tu;mcMmyyx}Gq>H-1TM-@mRtBoHmtAm2&z%Z52?Kojea zxwhrMXua!f{A$o*ytcKoh`N-MKBt+^AK>C&_F1$YZNrvnz~D`R(sEx8g!_j;eq=_g z&KF8g6)sTV_miy@MjaUpgXZkp{imY_#uZnXcmGJrf8BW6F+1P^c{%yb`u}>T>nCZz zL~tZO><`@1ziel;6}|uCX1PJ!*p2d7p1Jsp{om{ptr%LL|E+1wxgMev1ksqlU%RjR z*(yWxrP#hbzdznX>dDd<9s2V~YxE)dg5dSr8d|j!T;Cg2PK&E4=Z`RdP-RR^6aBlt z(|m`k7@J=x;)Aawv?h|Tbnzk^+%dm@$OF1mBi?f37c#xG%pnw8f_?*#wkPa?a{X1p?$attIYf*f4o-M9IBO!* zoU0TwCWmmJou38&*b?V&dE-o&(xdidM#+1dLe5$?s!cx33Z3g|Tot|f=iT*V3w0ja zJx|DACDbyeGZ)Gs`hNf1TU6@}=ac_s9j?+l9tfEIq@JO0e)%HJ%7+sl{yZo8V-Jjc z+e^Pm?7P*BW6XlDdp#2W{obBb!vrNpzWn9;(}z@vBT$iysg;KW{+#swIE32TToyrQ z?8DfQyzy06=ilG#x=hGh2{%5kz>Xg+y}w(sUv~Mw9A`Z@m_XQ$5ph5CcOUD=oBg_x z!S@V_I|{Z{E@21m58jp^5B>dn|EF72odqA=?2wJdpIC~2^6P)|@KhfW-3_kKTVWsB z`VYVKpKg|T1sEgMk8L;pm#6)USJO5G*T>b-rE>nK*ZhkMfB$J0t-B@Fxe;SHXSH*5`|3Ca3 zm-NBq2kNSg*?#dV|I-0eDg$v)*U^H18U_}F%TM{cS4;fEQ)vfGaJHcSKMZ4cTY$?i zuTQ$!|HIYm0%!7?QSmE;p%~t7pyS!5KvD4z0vtgTmIY84LLx){E>@L;y+zIL2z>a z@8JK1f&L#X$D{u{`2TnC|L@@c6U)W*|Fy?gYMi?BH}M8n@6OYwTd&8yX&-LwbrQrQ z3tt!(nb{`j@Tg0uZvPiE%@qfRteA75&EaN;0Bc5H(GpE_XqVt`R zQYbb>!fBF)9ul&|CgDOiNru$-qjGJEkXfu#<#ripzcn%Cm5LXG4V?ca{K+{*edW&f zyKn#ei^lV`qoboS3IQZ~(OEQ9T6s>`W{el=8IN*?qf@g+J&?^{fShY?9!|NN9#bc* zL(_hdAgIHm2`B=1eDlAV5GyK`SA3%xCYh_EzbIfdexZN;{#}3H6H4bHu$CsL);RtoO}VFlIv#7|WqeGR$7n5r0L z+L0=A1|T|O!LV~{2;JuR_;Z%$GvT3sEa2Jb;y5S!>6YWaDkN}??6$gY-bf06-VcGe z)Gt0_WD%O2o|0qTxisE+AG7R_eKwXLhBZ@$q0LubqPv6`!QE{-(Wco-da73#%g}WPK=4{;ALyUa?|X`v+Uv zZws6Ah^l^;YkU%bEP}3vWWmyBG!P2*vIKyr184gm8U=c4hVma zUCz`R&EkQUtQCeVKLt!tcH4KAdcYIs$k3!IJpgoS%U#&UVGSu?rX1m0=P!xbw4DXu zZdG^W=iu*kkdSroxKWzV$bUXyT+!!u0?un*IucQ{bKqv203YBQ^N324^D5fH(GNU* z`m|NB5_7&iSvnE0{I+y+t6F`2cCZAX+bRnwA5x^8BP0))B3{oqZOkFftN|GVAaE76 z$7DS&OxU@MYh9XXMbAk|qt9+EO^BmNQM!O2B_2SwQ!JgGQT@%d@pl+j@VsCVJfpgf zv>)i(e*H8DX!&V_v0$0elhFG;Jgm~51prvllvjxU3Iu?L309vf0TOZ*3<65vIKPOs zFclg$zmUe9^ZED@;Fhhk#;AlNKilmd$;iU<^&&3tv))Q7pv6iQ10on;9NG%-QkGZ&IXasWrC3ps&czVpauXOo zB+e*p)3nathswo&ACMPDXdcT28cbJToKP(?uJ)fBFIPCD*|Gz)`5kT6bJkd}i^=cmEUj33A_P_z?LYif z0MQPm>cWAe#@YhT|HRjqXWm)pM^FU}u6xk3slkIN3NittxJQp4r(iokI~8!g_o4Y1 zzR$SbIC4Evu6AT2$MfUjuWK*6vm--Mm}HEjA&cfk*?M8N2#)FA>QWUM`nrhCkCo?0u+yd5)!~6YZ=qLcuE+)6lMeonU1=+RSbpo zGZy!odkgwv4P|M_@U68J#(R}70@t_wdCFrH3Kzfa;OkpO7tWM7#F zxCG>|bjqVyV+Gkd$=~)0e)_vT93pFe^^QoHc<~lG#OY*X1y8;O! zmb-mXbX)rT{4jjnoKk1lRFLs`8|EEmc8>1%04XF~D0(|9BLsN5f44KgZI5@imBgcW z?MX+D-aD{Tije0;%CLSe-V@`?m>x#0sQlhSBWd%6S`L;` zt7L+rdGOY_l{fR@ix8(hN6w$sNmU{%O*C12y33S~TuYXLqZ}a3>|VnMr(82?u)G@k zj$eelkoZIv!5QD++j~?f0{pm<2e6~#FG zxnTnmf7;!L;n9-Dr3dZbc($J>m?^9;T-M2DoyN%;w8AEoc|)s$?2$!jntecE&A%cP z-5K<%+i|X9>UjCog|ga(Z{gb6SD8wkDVIJ#ljSMQsHFwprnT9#>dBdp-%hRWe;b+U_d%} z`nzm=W%UCV5_V^@ohCeW#{$8|`#UZu3>Y zzQeBrw^_Y6SniN0lTrEF&;b@GzrJ^`Q05@+)ACg^eBt$FQ3^%4JSt<6 z8UphPng_|PR^ATMp~7W;+lfkVcY~VEd9N7!pJVwEF_z8(JVn5a0|)qi;gNdQU&4-P z_cIO@>6X7YxK~_SX{YU+pl@1F zDQGmZ{xbiRzbazZ6jWB`B>eUFw7)nMgJLO4&AeAO=X+B|% zS$@1UfKNJE!a)c`-EN9C>Ob$-OE{2WA47wMR$l6YCu>bnv8n5H`tbUyeK&e4ENB*`WjO@6&L z7eHGBV{HZG6MP^PaEJEp`$h#dReG4<9lHwFDBGJ5wAzB(Q13gQb>C|7TT0=Pnu<=& zH8-fLd~10PSio(~-xS5^g_l@{*~k+Uz?`ACv}Hl%ecEn7sXyP(d{RV7%BLhBA9=6u zef1_;Pa@mDX+Qh$3^mx8H7Ff+G8wFN$+$?IEpAhy;p@RmEb2j9f@_Aole)VJ$L))fHlScvZB*wkT zW8db_r$ANE9Gm6&?aB&8*lb4BRRJWFT!niFuv(ib$^DS0i$A(qVDv>E@oNv(xPsQ9 zzhIFuL2ozH8!Um|$4~X;X_evj=2)I;d`&lo5mS+yX4X#xB*Q3^=Z1l6gSIqL4!v(* zYLegI$+rT+w+bFLi-0q6qj#b$Nk@VuATtXI8=7u{+dT<%p$b}g_1Fdg^pygtW|4>u z+Uyl%?z91HbP7&lK8^Z4%?tB_d1?1C_i<^W3bI`dMpUIc^ojwe&1|-W4!) z>=hx^aC-|-jw-Z2psl}Xd%7XT1;)KvRI4o!4hO?%&HG7<2!De6f(qu9n2fADMMdEV z`p2vPW(D|8M@t%cx|_<~S5RSSxIxW?B!tX^F3-8#V}qZ3@?%FH52>fz-LwDumi@z% zMKjO`o)kOVaZAX!N~D7vLfg0+3|!Q8K=k@Wk-VZ4OM~$ouJLf#7$FneZGcpaW4S@# ze3`nV3?RI)V<0N!0$_qdU-B1uEg84fGoC*??_;;>HBM_5QHV9qF6TN>cUK>PA5wSMyr;Ys3oaUw-+MU+kZPZ;iKD;i2= zJa_eFS*lYIvZM*r5gtoHJv3^L%pbv}_J z#ju~5o&UYjcP@aF7e;J0k)i;Kr22%3J$dO9AW_7K3g{Or4FQK_pXb8o{r2)MpRL6v z?w}Cb`44yUbv=-=C1Tb~XQz)F@bH%dY-$IIp8dMzf2@qr&}-{+$qE|oVSd!} z^D+PJ)$CQwftx7#!t&V^s=@wl%<4p?^<1)~8_-pOCe5~5e0s96!a8jQxXjAlX{I^* zqv3E(G{{y1DtbOPmc7#ncrsY+Zkyo*?V5a(GM=rea9=Tbk$g7+C|6zwgPi^vua%dC z>sDfFw_5lodlpBZqRFxiSwZl??qX#+@rIA{UqMD<)%I%TkW;UVjM>gpOFpjW{$J{LT+#38W40mg?`GVN@B76p84J+@*4jiIIAEAo@=QKt z{Hw}t8>GM#LY`796SOuv7|F zG^=WGdA(qh946O@xqaT9F;`aHwHYp~Ho5lTm{?sRznN*^aj`2k3L80~T81>fbc{D2 z%20@sA~6JW5Ncx!67w*aEF7DNYi4Z^4C**kb_3uJ?|CYc1}w9b7b`%hr{%jgWg(q= z2j4$`p?nEsPLpF&*FOR(OqSdmJ#R;dJnAXUJ2bTdGM$}_C;^6?j#{rL)Cg(v=A#E_?A@;b^uAc-(vi89o{Z{=kueW2)kAhJ!_%AaYT;)_VY&cK~eKj?Omc51V!4(1JQ5 zKBwryUohic51`G{%<$Yb!8uUG`iU;yJ#ZDHP&)@FPo5yWF+g(R2f`>Di1oB<;z_(Y zc2_q%iCEziQjWX5U!}Wz`}|xxPgl?Y$fIed9LITz;dY(3y%<uSe18^115x{;V;Ljx3r*Oz=iz z)B~xcsaW6rv0WI(uazo@m(e4BekWCbvWz2cEN}HcJRJ7GrFB=`&u*RT7M@-;y;c6+ z7+Gvlulab-gz&U}jBiPCv53J6(QHzDF$x@XCE)AkJ<1%rPJd}Uh23$k_5Q_Wa?@Q-5QfxEQRZcmS?4Zz!;9N&@n=L)vcxxIGgkih=FeZ=avuPU3| zKtg?Ttn`!1Z^a%PQ0xix8&GqirDk^g@9&5wbx4kwm5u=!EVV7V0UcBoi+DO!l<^LZ zvvFAlSv$yRW44Yo1Lk`4^Mm*tOHl6QPBz)D51|u%xaQPkP-68`)??;6sIwW&Sv4U) zn1=afg)D=^6K?ZH)3F{JH0d+9T&`zYW>Wg|u#7fPHTHWUXe5<4aGa7VeND`^!?6Qf z;IkJHC7Ol3;EvP07%+6W8N{0fiEm@)yyh^1Am2^w$_@%EH@P=(kb^^rL|HUk@#(_x z2qu8#i)NF2pYj?$G$*;SitLqU9Rd8bvCfdXZ%Z?%tu+Fc;Ed0SXfqI_Vgsx@hO3>) z6II%^-i+>pd}QM1H81(P`)5}PUxb_d+9dzw$6Tu!t!jsbUg1@K9Rav>i^{?e3Y2A9 zwPnYVW%grNyEJbmnm=5V+)JJvEN#bWM|!o4-{|gQQG!r*II0$htlTodrEJiDOKDry z!2Vow-x0FDvj|?7d*ULbP|j=Sth{gC2}(%WbY96} z#Slwp^I=eD(h57wCjeN^ml)HL`5S=uyiH}==s3O~dVbD?>&zeEpJ#W#kdD6nz@Or- z-&69T!<|ZA?S}~MS6o7;0MeRDLst@rmUX{Bq#NF@kIk_c&u}Uo-FiI-O1Tcw27d}I zKc88sret} zKC_lF!G�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%0D8a&T9VV>XuD24A5F@`TQUDYuwR^ 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 z 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

`JK`&;I;uQZf3W(xqQku~f9L z_GJLi^G}ETcBNe#nEugPe8#VzarmCi_oYK=@?KiX#LYW?*^tKafQQ`)PShGPr{kaM z%|g+D;Z~#y1U_mmw<|J z4V@3%T4inoqN|qssy^F(zN4>n#sfxZm;Yp|!t4s0`u_C1prBTNzCP3kxNE_54-hPN zx6$_NKPD1?cw9zrueA}i(2k?u#3#ImEmuIQ?!Q@o&go_#g-nS9Z7?lxqK>=B%msr& z8Z@58M#^nt5E#StsdkZYdL*xP$7}YkR$LT0eQa-+X{v$9bC9zd&ZbDOh=NGXVd5Jp zWVFt!Z^H1#wLD-6+g7yQ0I)Iv9FPS)CLMQp%(wT2e~bz-u)3a1;Ic3^vj0{Rs)(YD z*fH{W3M;Nn-2ogrC)De|PR`I{Xa6L4<;6OFm-s7I{PPj$gc=kWqb>T%J~Q3^7Vjqa zQuyZk+ZQgH7N@nJ+|CDN!ihpFzh_ps@;>~24XYQY>k2CAvPXxVZNt+%(rBod-=dDP z8!l`j+Hb(E!EwHAN=cHl^lvIdg#PP6Y)d%SKXmf7a`4!_i?_0? z5u(*UiklnBrOGj*6MhtV7^#Me#(L?S8`*GuFi!slx(emHD0N_rN2F#yjBLwE2c+H-LM@19m(}_)jaGzQyo!az%17|HM$z zxI-&AC9M4jOKDN%e{JcX2c`p?z`g1SMSjti1@$ zCX#tqb2x*gL&6jqgkq<%=1i8rm5qClR4U}P_M^9pos8R^`L4l~10UI~mN(j6THm)* z2w#!DXN*?d9lTR!*Y}Xi7gBidRw^?Rpa&A}g91<#9uuSif+sW)Rb(m#ATnbh=42>m zk2!cRPlvN+_2Z`d+UH#B?_rPEK}A|+4i@rTBX~wtvGI^}4rp69@+x>Qy*?@Z0Ua`T zotf+FSxI|hj0(AASt@`$ahzc!WEUBLZx`W)#vi9g+LgWPsUl8EkotRGUC>^71RbB> zLRnOzij$Xl{NBdA14RYoM)cB1ZeeM!(=G@DakvH|CgUo_w@{xapv#2Pu_SA&w^=w_ z+XdOYJPyU#7}?Kkh$6fy<7lK@A#lx&DMyG|A2CkclD_V;=Uf{G`6W}O@j18T*A96Y zXbuG+A^Pcp$r84&z#16|`kH)=PM-7r+K&q>u@4%(Za=cwMP(D8bE&93VI~gRWQYL? z`uWAj+Zo42&F(d%NVO|;gV1*on9FW#o7z$LsfZKj?}^@i8zJ2v3~|@g?{f!tr6mRt96TD#^b25ufP%8zfBjd5M9RM>E$xK03qJsB+) z!!_i9hxo&aDAXUB0oQ&`Pv1zU&c|Memw>PoYCpiSrS#Ku}KlTyX2YW1_()S?-pq< zJ@BL^G0S4kr#M?+?`;#fped^BXs6yPnQB}^fRh4g60qDWw!l&J)eD7?rRs)!?M|=L z=_R|)5AMqJ9SBDLKkU6{Sd-h@Ei51?B4R@Xq}TwZDOEt4hz$@>inIi!*C4$n6cwc_ zAiYTMkzPZwfb>p)0HI0=y#)v%XR_a=+r3=-ob~R1-}UW(zy)DG^O^ImV~o3P1Vw5- zHtrpBAW(S7oP>+#YFTr7#IF6 z^16W)fk>e1pD2^Q6V*t@WC|ZT_!P0b(qQdSRo%PLDvDj*ob61m4CC{7TY4_fc7m3r ziru#L8KSor{VkEBh7F^^N^wOJ>X0Rk$vgY2~PbGP; zP%Tp8X0q5zi3a!Z4yhYPxq9l>@Aq8OK9XIv_ zVFutLrG+}--`EKyw0aIjtrs?r&<9HDB0`0)JO&r-<`#yz( zf=X(sml!UpI7-lg)tt)Z-xGPB2|U9ov)-)mFmBDhhg2PkMBw;>R?5IYx#eTTK?|6( zR`>7&S{YbxR%)wC!o|Ce5+7s;jE@ET zeUcez1z=2DGs$$8b_fh;zCC!)lTI-V1;AsMoTZ788{3niPm|aXoz6>I{Ng-OgPHbQOoBY zv2J$nPIUQ*5fZ%t;@DLYri$ z)Phco(%y7JMDq*&>f^LjbbJ+g`ypuM_Q$7e%^$!hMVr0S?zDj%{Frz9=Uh4|xMj1X z+wl4B>NxYlCX3N6&*>dZ!2H;zzu(nat7t;EGGrLqIqD!Pn`9j)eljl(!Iq0dnRlh+ zgWN+NBr#VQ1q_7}XizdP2m-+HIs1b{wlTNYG(TW>TY7JNMlE0;|}O-0b1BQ}i4GY~12ew*YKatv+U@}cx1|G3O-pp-bBZ+ZNSRaho+ucqzYCf~NsRL`G!y-(4KA`H; zY}--zH^yTmz-3!7Z*_;JKeTd5!cGW)=x-K{MAo>xLkkzWV5^B$6A(u&?)^}^^qg)Z z&}A=ufIWLWYksg8qobE;dl|`^mlV}^H|Q)M47Ks92!?&w^q$vXSjY!uO`{IJ1o$XW zSkw&8eN=Yu1hR35mbuE+GTd@t59jo~B}z$Sn@2XGTkHGA4Xr}sm1Fom9a!@>)npVQ zo7tY!6wa-HZP@wdy)E6SBsx4(jDC>*P|pxhg+|VHIf!3Lh7))C?lq_aCY^&r)q^tj zZ5!N#gALQq%|CpYafb2W|HHWbd=Z@og(%9XQY(`NFrVpLTNazrlwvGp@~LtxjCab; z3@cL$x^r%~7K(n{Me25;tT%_FTa8qvZqfc;S`wsJ_=Pwl!O zAsX@9*g^;)C2yv7LWS)Ve^<$Zup&Vd( z>{MJASG}bG&>2&2ec9e&MTv_>?*UIL%zn;2hD9z;V)*KYqVXPR;>_!i+q1FU{Vc_J zm6i!|6=dH%>d*O@c#vO}9-eoWYP0_*Z2o_1$vABY3&T|prI$zLY$umbzy{QXE;@lO zrBz2Im4k&%DV2tWO@;Az-+@ULd7l+9;lNy=7s}3b18D>pGD#rpU9JYjg(NR@-F^$7 zgX?CD*q*GI&8X+@@LzSxYh^RJ8AOty4DoEH6gk2^9=22+xNTO~trJmV1{KtU#}YR5Fjhll_p>x|lhiX| zEP$!&Wo_c9cCn)Mk~MhVB*;hc%grl`%D9Bp2^={DLC z-g+ZcP4pXxw6=L)&UyYCq5hZvn}uR4)B#r~b{4t)JexQp9;et@x-{E(M!Y=9ER

+ {errors?.permissions?.[type]?.[position]?.conditions?.message && ( +
+ + {errors?.permissions?.[type]?.[position]?.conditions?.message} +
+ )} +
{}
+
+ +
+
+ ); +}; diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx similarity index 93% rename from frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx rename to frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx index cdf0f5151..a85015508 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx @@ -8,7 +8,11 @@ import { Button, Checkbox, Tag } from "@app/components/v2"; import { ProjectPermissionSub } from "@app/context"; import { useToggle } from "@app/hooks"; -import { TFormSchema, TProjectPermissionObject } from "../ProjectRoleModifySection.utils"; +import { + isConditionalSubjects, + TFormSchema, + TProjectPermissionObject +} from "../ProjectRoleModifySection.utils"; type Props = { title: string; @@ -18,7 +22,7 @@ type Props = { isDisabled?: boolean; }; -export const GeneralPermissionOptions = >({ +export const GeneralPermissionPolicies = >({ subject, actions, children, @@ -98,10 +102,10 @@ export const GeneralPermissionOptions = - {!isDisabled && subject === ProjectPermissionSub.Secrets && ( + {!isDisabled && isConditionalSubjects(subject) && ( @@ -418,7 +422,7 @@ export const SecretDetailSidebar = ({ a={subject(ProjectPermissionSub.Secrets, { environment, secretPath, - secretName: secret.key, + secretName: secretKey, secretTags: selectTagSlugs })} > @@ -485,7 +489,7 @@ export const SecretDetailSidebar = ({ a={subject(ProjectPermissionSub.Secrets, { environment, secretPath, - secretName: secret.key, + secretName: secretKey, secretTags: selectTagSlugs })} > @@ -505,7 +509,7 @@ export const SecretDetailSidebar = ({ a={subject(ProjectPermissionSub.Secrets, { environment, secretPath, - secretName: secret.key, + secretName: secretKey, secretTags: selectTagSlugs })} > From fc5487396b75fd1440ae891e3610c693873eecd9 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 8 Oct 2024 01:51:10 +0530 Subject: [PATCH 32/54] feat: added helper text for operators and improved rendering of selective operators --- .../services/permission/permission-types.ts | 4 +- .../permissions/GlobPermissionInfo.tsx | 33 ++++++++++++ frontend/src/components/permissions/index.tsx | 1 + .../GeneralPermissionConditions.tsx | 52 ++++++++++++------- .../components/PermissionConditionHelpers.tsx | 32 ++++++++++++ .../components/SecretPermissionConditions.tsx | 51 +++++++++++------- 6 files changed, 135 insertions(+), 38 deletions(-) create mode 100644 frontend/src/components/permissions/GlobPermissionInfo.tsx create mode 100644 frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/PermissionConditionHelpers.tsx diff --git a/backend/src/ee/services/permission/permission-types.ts b/backend/src/ee/services/permission/permission-types.ts index 60fcbec85..8df85054d 100644 --- a/backend/src/ee/services/permission/permission-types.ts +++ b/backend/src/ee/services/permission/permission-types.ts @@ -11,8 +11,8 @@ export enum PermissionConditionOperators { } export const PermissionConditionSchema = { - [PermissionConditionOperators.$IN]: z.string().min(1).array(), - [PermissionConditionOperators.$ALL]: z.string().min(1).array(), + [PermissionConditionOperators.$IN]: z.string().trim().min(1).array(), + [PermissionConditionOperators.$ALL]: z.string().trim().min(1).array(), [PermissionConditionOperators.$REGEX]: z .string() .min(1) diff --git a/frontend/src/components/permissions/GlobPermissionInfo.tsx b/frontend/src/components/permissions/GlobPermissionInfo.tsx new file mode 100644 index 000000000..07ba42db3 --- /dev/null +++ b/frontend/src/components/permissions/GlobPermissionInfo.tsx @@ -0,0 +1,33 @@ +import { useState } from "react"; +import picomatch from "picomatch"; + +import { FormControl } from "../v2/FormControl"; +import { Input } from "../v2/Input"; + +export const GlobPermissionInfo = () => { + const [pattern, setPattern] = useState(""); + const [text, setText] = useState(""); + + return ( +
+
A glob pattern uses wildcards to match file names or paths.
+
+ + setPattern(e.target.value)} /> + +
+
+ + setText(e.target.value)} /> + +
+
+ ); +}; diff --git a/frontend/src/components/permissions/index.tsx b/frontend/src/components/permissions/index.tsx index 8d523c311..5103b0f73 100644 --- a/frontend/src/components/permissions/index.tsx +++ b/frontend/src/components/permissions/index.tsx @@ -1,3 +1,4 @@ +export { GlobPermissionInfo } from "./GlobPermissionInfo"; export { OrgPermissionCan } from "./OrgPermissionCan"; export { PermissionDeniedBanner } from "./PermissionDeniedBanner"; export { ProjectPermissionCan } from "./ProjectPermissionCan"; diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx index da4dd72eb..989b7c19b 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx @@ -1,14 +1,26 @@ import { Controller, useFieldArray, useFormContext } from "react-hook-form"; -import { faPlus, faTrash, faWarning } from "@fortawesome/free-solid-svg-icons"; +import { faInfoCircle, faPlus, faTrash, faWarning } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Button, FormControl, IconButton, Input, Select, SelectItem } from "@app/components/v2"; +import { + Button, + FormControl, + IconButton, + Input, + Select, + SelectItem, + Tooltip +} from "@app/components/v2"; import { PermissionConditionOperators, ProjectPermissionSub } from "@app/context/ProjectPermissionContext/types"; import { TFormSchema } from "../ProjectRoleModifySection.utils"; +import { + getConditionOperatorHelperInfo, + renderOperatorSelectItems +} from "./PermissionConditionHelpers"; type Props = { position?: number; @@ -19,12 +31,6 @@ type Props = { | ProjectPermissionSub.SecretImports; }; -const getValueLabel = (type: string) => { - if (type === "environment") return "Environment slug"; - if (type === "secretPath") return "Folder path"; - return ""; -}; - export const GeneralPermissionConditions = ({ position = 0, isDisabled, type }: Props) => { const { control, @@ -40,7 +46,11 @@ export const GeneralPermissionConditions = ({ position = 0, isDisabled, type }:
{items.fields.map((el, index) => { - const lhs = watch(`permissions.${type}.${position}.conditions.${index}.lhs`); + const condition = watch(`permissions.secrets.${position}.conditions.${index}`) as { + lhs: string; + rhs: string; + operator: string; + }; return (
-
+
( field.onChange(e)} className="w-full" > - Equal - Not Equal - - Glob Match - - Contains + {renderOperatorSelectItems(condition.lhs)} )} /> +
+ + + +
- + )} /> diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/PermissionConditionHelpers.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/PermissionConditionHelpers.tsx new file mode 100644 index 000000000..21fad117a --- /dev/null +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/PermissionConditionHelpers.tsx @@ -0,0 +1,32 @@ +import { GlobPermissionInfo } from "@app/components/permissions"; +import { SelectItem } from "@app/components/v2"; +import { PermissionConditionOperators } from "@app/context/ProjectPermissionContext/types"; + +export const getConditionOperatorHelperInfo = (type: PermissionConditionOperators) => { + switch (type) { + case PermissionConditionOperators.$EQ: + return "Value should equal specified value."; + case PermissionConditionOperators.$NEQ: + return "Value should not equal specified value."; + case PermissionConditionOperators.$IN: + return "List of comma-separated values that match a given value."; + case PermissionConditionOperators.$GLOB: + return ; + default: + return ""; + } +}; + +export const renderOperatorSelectItems = (type: string) => { + if (type === "secretTags") { + return Contains; + } + return ( + <> + Equal + Not Equal + Glob Match + Contains + + ); +}; diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx index a6f94de90..e0e5aa471 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx @@ -1,23 +1,29 @@ import { Controller, useFieldArray, useFormContext } from "react-hook-form"; -import { faPlus, faTrash, faWarning } from "@fortawesome/free-solid-svg-icons"; +import { faInfoCircle, faPlus, faTrash, faWarning } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Button, FormControl, IconButton, Input, Select, SelectItem } from "@app/components/v2"; +import { + Button, + FormControl, + IconButton, + Input, + Select, + SelectItem, + Tooltip +} from "@app/components/v2"; import { PermissionConditionOperators } from "@app/context/ProjectPermissionContext/types"; import { TFormSchema } from "../ProjectRoleModifySection.utils"; +import { + getConditionOperatorHelperInfo, + renderOperatorSelectItems +} from "./PermissionConditionHelpers"; type Props = { position?: number; isDisabled?: boolean; }; -const getValueLabel = (type: string) => { - if (type === "environment") return "Environment slug"; - if (type === "secretPath") return "Folder path"; - return ""; -}; - export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) => { const { control, @@ -33,7 +39,11 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props)
{items.fields.map((el, index) => { - const lhs = watch(`permissions.secrets.${position}.conditions.${index}.lhs`); + const condition = watch(`permissions.secrets.${position}.conditions.${index}`) as { + lhs: string; + rhs: string; + operator: string; + }; return (
-
+
field.onChange(e)} className="w-full" > - Equal - Not Equal - - Glob Match - - Contains + {renderOperatorSelectItems(condition.lhs)} )} /> +
+ + + +
- + )} /> @@ -126,7 +142,6 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) {errors?.permissions?.secrets?.[position]?.conditions?.message}
)} -
{}
+ + {(isAllowed) => ( + + )} + diff --git a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx index 001890b8f..160991f2a 100644 --- a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx +++ b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx @@ -18,7 +18,7 @@ import { Tag, Tooltip } from "@app/components/v2"; -import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context"; +import { ProjectPermissionDynamicSecretActions, ProjectPermissionSub } from "@app/context"; import { usePopUp } from "@app/hooks"; import { useDeleteDynamicSecret } from "@app/hooks/api"; import { @@ -132,17 +132,27 @@ export const DynamicSecretListView = ({ )}
- + {(isAllowed) => ( + + )} + + {secret.status === DynamicSecretStatus.FailedDeletion && (
diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx index 5a7a0fdef..58c403579 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx @@ -73,6 +73,44 @@ export const GeneralPermissionPolicies = {items.fields.map((el, rootIndex) => (
+ {isConditionalSubjects(subject) && ( +
+
Permission
+
+ ( + + )} + /> +
+
+ +

+ Whether to allow or forbid the selected actions when the following + conditions (if any) are met. +

+

Forbid rules must come after allow rules.

+ + } + > + +
+
+
+ )}
Actions
@@ -101,36 +139,6 @@ export const GeneralPermissionPolicies =
- {isConditionalSubjects(subject) && ( -
-
Effect
-
- ( - - )} - /> -
-
- - - -
-
- )} {children && cloneElement(children, { position: rootIndex diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx index e0e5aa471..b858545de 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx @@ -36,7 +36,11 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) }); return ( -
+
+

Conditions

+

+ When this policy should apply (always if no conditions are added). +

{items.fields.map((el, index) => { const condition = watch(`permissions.secrets.${position}.conditions.${index}`) as { @@ -157,7 +161,7 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) }) } > - New Condition + Add Condition
From c8410ac6f3b3207a66c93b650829921f4ee23e5e Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Fri, 11 Oct 2024 15:53:44 -0700 Subject: [PATCH 42/54] fix: keep main page filters enabled by default for UI and only disable query via permissions --- .../views/SecretMainPage/SecretMainPage.tsx | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/frontend/src/views/SecretMainPage/SecretMainPage.tsx b/frontend/src/views/SecretMainPage/SecretMainPage.tsx index 813e437e4..27df54e53 100644 --- a/frontend/src/views/SecretMainPage/SecretMainPage.tsx +++ b/frontend/src/views/SecretMainPage/SecretMainPage.tsx @@ -106,11 +106,12 @@ export const SecretMainPage = () => { const defaultFilterState = { tags: {}, searchFilter: (router.query.searchFilter as string) || "", + // these should always be on by default for the UI, they will be disabled for the query below based off permissions include: { [RowType.Folder]: true, - [RowType.Import]: canReadSecretImports, - [RowType.DynamicSecret]: canReadDynamicSecret, - [RowType.Secret]: canReadSecret + [RowType.Import]: true, + [RowType.DynamicSecret]: true, + [RowType.Secret]: true } }; @@ -118,19 +119,6 @@ export const SecretMainPage = () => { const [debouncedSearchFilter, setDebouncedSearchFilter] = useDebounce(filter.searchFilter); const [filterHistory, setFilterHistory] = useState>(new Map()); - // change filters if permissions change at different paths/env - useEffect(() => { - setFilter((prev) => ({ - ...prev, - include: { - [RowType.Folder]: true, - [RowType.Import]: canReadSecretImports, - [RowType.DynamicSecret]: canReadDynamicSecret, - [RowType.Secret]: canReadSecret - } - })); - }, [canReadSecret, canReadSecretImports, canReadDynamicSecret]); - useEffect(() => { if ( !isWorkspaceLoading && From 0c3024819c838694cddc821af4b8dd4e9c3b33a7 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 16 Oct 2024 11:14:21 +0530 Subject: [PATCH 43/54] feat: review comments over dynamic-secrets, folder read, neq removed in backend, contain in tag --- .../dynamic-secret/dynamic-secret-service.ts | 14 +++++++++----- backend/src/ee/services/license/license-fns.ts | 2 +- .../components/permissions/GlobPermissionInfo.tsx | 4 ++-- .../src/context/ProjectPermissionContext/types.ts | 4 ++-- .../ProjectRoleModifySection.utils.ts | 3 +-- .../components/GeneralPermissionConditions.tsx | 15 ++++++++------- .../components/SecretPermissionConditions.tsx | 11 +++++++++-- .../src/views/SecretMainPage/SecretMainPage.tsx | 2 +- 8 files changed, 33 insertions(+), 22 deletions(-) diff --git a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts index d207df4ce..99bf84aa3 100644 --- a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts +++ b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts @@ -228,7 +228,7 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Edit, + ProjectPermissionDynamicSecretActions.Delete, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); @@ -284,6 +284,10 @@ export const dynamicSecretServiceFactory = ({ actorAuthMethod, actorOrgId ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionDynamicSecretActions.Read, + subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionDynamicSecretActions.Edit, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) @@ -331,7 +335,7 @@ export const dynamicSecretServiceFactory = ({ // verify user has access to each env in request environmentSlugs.forEach((environmentSlug) => ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Lease, + ProjectPermissionDynamicSecretActions.Read, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ) ); @@ -367,7 +371,7 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Lease, + ProjectPermissionDynamicSecretActions.Read, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); @@ -413,7 +417,7 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Lease, + ProjectPermissionDynamicSecretActions.Read, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); @@ -455,7 +459,7 @@ export const dynamicSecretServiceFactory = ({ // verify user has access to each env in request environmentSlugs.forEach((environmentSlug) => ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Lease, + ProjectPermissionDynamicSecretActions.Read, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ) ); diff --git a/backend/src/ee/services/license/license-fns.ts b/backend/src/ee/services/license/license-fns.ts index fa67b72d1..7a1632f93 100644 --- a/backend/src/ee/services/license/license-fns.ts +++ b/backend/src/ee/services/license/license-fns.ts @@ -21,7 +21,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({ secretVersioning: true, pitRecovery: false, ipAllowlisting: false, - rbac: false, + rbac: true, customRateLimits: false, customAlerts: false, auditLogs: false, diff --git a/frontend/src/components/permissions/GlobPermissionInfo.tsx b/frontend/src/components/permissions/GlobPermissionInfo.tsx index 07ba42db3..b65b0c307 100644 --- a/frontend/src/components/permissions/GlobPermissionInfo.tsx +++ b/frontend/src/components/permissions/GlobPermissionInfo.tsx @@ -10,7 +10,7 @@ export const GlobPermissionInfo = () => { return (
-
A glob pattern uses wildcards to match file names or paths.
+
A glob pattern uses wildcards to match resources or paths.
setPattern(e.target.value)} /> @@ -19,7 +19,7 @@ export const GlobPermissionInfo = () => {
; export enum ProjectPermissionSub { diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts index 7c145fd08..ec5f7b5a9 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts @@ -370,7 +370,6 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = { [ProjectPermissionSub.SecretFolders]: { title: "Secret Folders", actions: [ - { label: "Read", value: "read" }, { label: "Create", value: "create" }, { label: "Modify", value: "edit" }, { label: "Remove", value: "delete" } @@ -392,7 +391,7 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = { { label: "Create", value: "create" }, { label: "Modify", value: "edit" }, { label: "Remove", value: "delete" }, - { label: "Lease", value: "lease" } + { label: "Manage Leases", value: "lease" } ] }, [ProjectPermissionSub.Cmek]: { diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx index 3d147c708..2ac518038 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx @@ -50,11 +50,12 @@ export const GeneralPermissionConditions = ({ position = 0, isDisabled, type }:

{items.fields.map((el, index) => { - const condition = watch(`permissions.secrets.${position}.conditions.${index}`) as { - lhs: string; - rhs: string; - operator: string; - }; + const condition = + (watch(`permissions.${type}.${position}.conditions.${index}`) as { + lhs: string; + rhs: string; + operator: string; + }) || {}; return (
( diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx index b858545de..b742b829d 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx @@ -28,6 +28,7 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) const { control, watch, + setValue, formState: { errors } } = useFormContext(); const items = useFieldArray({ @@ -66,7 +67,13 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) +
+
+ ******** +
-
- -
-
- ******** -
-
+ ))} ); diff --git a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretNoAccessOverviewTableRow.tsx b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretNoAccessOverviewTableRow.tsx index ef4ee2ce7..459c25ddc 100644 --- a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretNoAccessOverviewTableRow.tsx +++ b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretNoAccessOverviewTableRow.tsx @@ -2,7 +2,7 @@ import { faCircle } from "@fortawesome/free-regular-svg-icons"; import { faLock } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Td, Tr } from "@app/components/v2"; +import { Td, Tooltip, Tr } from "@app/components/v2"; type Props = { environments: { name: string; slug: string }[]; @@ -16,12 +16,18 @@ export const SecretNoAccessOverviewTableRow = ({ environments = [], count }: Pro
-
-
- + +
+
+ +
+
NO ACCESS
-
NO ACCESS
-
+
{environments.map(({ slug }, i) => { From 6f334e4cab60508b2809126a832ecf940761d661 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 16 Oct 2024 13:26:01 +0530 Subject: [PATCH 46/54] fix: resolved rebase and missing import module --- backend/src/ee/services/license/license-fns.ts | 2 +- .../src/services/external-migration/external-migration-fns.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/ee/services/license/license-fns.ts b/backend/src/ee/services/license/license-fns.ts index 7a1632f93..fa67b72d1 100644 --- a/backend/src/ee/services/license/license-fns.ts +++ b/backend/src/ee/services/license/license-fns.ts @@ -21,7 +21,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({ secretVersioning: true, pitRecovery: false, ipAllowlisting: false, - rbac: true, + rbac: false, customRateLimits: false, customAlerts: false, auditLogs: false, diff --git a/backend/src/services/external-migration/external-migration-fns.ts b/backend/src/services/external-migration/external-migration-fns.ts index 6d996022a..934c1c8e1 100644 --- a/backend/src/services/external-migration/external-migration-fns.ts +++ b/backend/src/services/external-migration/external-migration-fns.ts @@ -19,7 +19,7 @@ import { TProjectEnvServiceFactory } from "../project-env/project-env-service"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretTagDALFactory } from "../secret-tag/secret-tag-dal"; import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal"; -import { fnSecretBulkInsert, getAllNestedSecretReferences } from "../secret-v2-bridge/secret-v2-bridge-fns"; +import { fnSecretBulkInsert, getAllSecretReferences } from "../secret-v2-bridge/secret-v2-bridge-fns"; import type { TSecretV2BridgeServiceFactory } from "../secret-v2-bridge/secret-v2-bridge-service"; import { TSecretVersionV2DALFactory } from "../secret-v2-bridge/secret-version-dal"; import { TSecretVersionV2TagDALFactory } from "../secret-v2-bridge/secret-version-tag-dal"; @@ -242,7 +242,7 @@ export const importDataIntoInfisicalFn = async ({ } await fnSecretBulkInsert({ inputSecrets: secretBatch.map((el) => { - const references = getAllNestedSecretReferences(el.secretValue); + const references = getAllSecretReferences(el.secretValue).nestedReferences; return { version: 1, From d36a9e2000fddf44b5fd43315ddbb29555e95050 Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Wed, 16 Oct 2024 08:38:41 -0700 Subject: [PATCH 47/54] fix: correct dummy row display count --- backend/src/ee/services/license/license-fns.ts | 2 +- frontend/src/hooks/api/dashboard/queries.tsx | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/backend/src/ee/services/license/license-fns.ts b/backend/src/ee/services/license/license-fns.ts index fa67b72d1..7a1632f93 100644 --- a/backend/src/ee/services/license/license-fns.ts +++ b/backend/src/ee/services/license/license-fns.ts @@ -21,7 +21,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({ secretVersioning: true, pitRecovery: false, ipAllowlisting: false, - rbac: false, + rbac: true, customRateLimits: false, customAlerts: false, auditLogs: false, diff --git a/frontend/src/hooks/api/dashboard/queries.tsx b/frontend/src/hooks/api/dashboard/queries.tsx index ec018e953..3f959f905 100644 --- a/frontend/src/hooks/api/dashboard/queries.tsx +++ b/frontend/src/hooks/api/dashboard/queries.tsx @@ -155,16 +155,12 @@ export const useGetProjectSecretsOverview = ( }, select: useCallback((data: Awaited>) => { const { secrets, ...select } = data; - const uniqueSecrets = secrets - ? unique(secrets, (i) => `${i.secretKey}:${i.environment}`) - : []; + const uniqueSecrets = secrets ? unique(secrets, (i) => i.secretKey) : []; - const uniqueFolders = select.folders - ? unique(select.folders, (i) => `${i.name}:${i.environment}`) - : []; + const uniqueFolders = select.folders ? unique(select.folders, (i) => i.name) : []; const uniqueDynamicSecrets = select.dynamicSecrets - ? unique(select.dynamicSecrets, (i) => `${i.name}:${i.environment}`) + ? unique(select.dynamicSecrets, (i) => i.name) : []; return { From 154ea9e55d280aa586adf271890f31769f069d1b Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Wed, 16 Oct 2024 08:56:27 -0700 Subject: [PATCH 48/54] fix: correct delete secret UI permission check with path included --- backend/src/ee/services/license/license-fns.ts | 2 +- .../components/SecretOverviewTableRow/SecretEditRow.tsx | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/backend/src/ee/services/license/license-fns.ts b/backend/src/ee/services/license/license-fns.ts index 7a1632f93..fa67b72d1 100644 --- a/backend/src/ee/services/license/license-fns.ts +++ b/backend/src/ee/services/license/license-fns.ts @@ -21,7 +21,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({ secretVersioning: true, pitRecovery: false, ipAllowlisting: false, - rbac: true, + rbac: false, customRateLimits: false, customAlerts: false, auditLogs: false, diff --git a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretEditRow.tsx b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretEditRow.tsx index db468095e..62952b5fe 100644 --- a/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretEditRow.tsx +++ b/frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretEditRow.tsx @@ -205,7 +205,12 @@ export const SecretEditRow = ({
{(isAllowed) => (
From 2383c93139a0e8753288f55b3966468cb085a848 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 17 Oct 2024 23:15:57 +0530 Subject: [PATCH 49/54] feat: changed dynamic secret mapping to new one, made optional secretname and tag in permission --- .../dynamic-secret/dynamic-secret-service.ts | 18 +++--- .../services/permission/project-permission.ts | 61 ++++++++++++------- .../secret-approval-policy-service.ts | 15 +---- .../secret-approval-request-service.ts | 2 +- .../secret-rotation-service.ts | 2 +- .../secret-snapshot-service.ts | 8 +-- .../integration/integration-service.ts | 8 +-- .../secret-import/secret-import-service.ts | 16 ++--- backend/src/services/secret/secret-fns.ts | 4 +- backend/src/services/secret/secret-service.ts | 40 +++++------- .../service-token/service-token-service.ts | 2 +- .../context/ProjectPermissionContext/types.ts | 8 +-- .../ProjectRoleModifySection.utils.ts | 54 ++++++++++------ .../views/SecretMainPage/SecretMainPage.tsx | 2 +- .../components/ActionBar/ActionBar.tsx | 2 +- .../DynamicSecretListView.tsx | 4 +- 16 files changed, 122 insertions(+), 124 deletions(-) diff --git a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts index 99bf84aa3..c202b3eda 100644 --- a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts +++ b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts @@ -80,7 +80,7 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Create, + ProjectPermissionDynamicSecretActions.CreateRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); @@ -149,7 +149,7 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Edit, + ProjectPermissionDynamicSecretActions.EditRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); @@ -228,7 +228,7 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Delete, + ProjectPermissionDynamicSecretActions.DeleteRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); @@ -285,11 +285,11 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Read, + ProjectPermissionDynamicSecretActions.ReadRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Edit, + ProjectPermissionDynamicSecretActions.EditRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); @@ -335,7 +335,7 @@ export const dynamicSecretServiceFactory = ({ // verify user has access to each env in request environmentSlugs.forEach((environmentSlug) => ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Read, + ProjectPermissionDynamicSecretActions.ReadRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ) ); @@ -371,7 +371,7 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Read, + ProjectPermissionDynamicSecretActions.ReadRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); @@ -417,7 +417,7 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Read, + ProjectPermissionDynamicSecretActions.ReadRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ); @@ -459,7 +459,7 @@ export const dynamicSecretServiceFactory = ({ // verify user has access to each env in request environmentSlugs.forEach((environmentSlug) => ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Read, + ProjectPermissionDynamicSecretActions.ReadRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) ) ); diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index 3b477cd04..a3998206d 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -23,10 +23,10 @@ export enum ProjectPermissionCmekActions { } export enum ProjectPermissionDynamicSecretActions { - Read = "read", - Create = "create", - Edit = "edit", - Delete = "delete", + ReadRootCredential = "read-root-credential", + CreateRootCredential = "create-root-credential", + EditRootCredential = "edit-root-credential", + DeleteRootCredential = "delete-root-credential", Lease = "lease" } @@ -63,8 +63,8 @@ export enum ProjectPermissionSub { export type SecretSubjectFields = { environment: string; secretPath: string; - secretName: string; - secretTags: string[]; + secretName?: string; + secretTags?: string[]; }; export type SecretFolderSubjectFields = { @@ -461,10 +461,10 @@ const buildAdminPermissionRules = () => { can( [ - ProjectPermissionDynamicSecretActions.Read, - ProjectPermissionDynamicSecretActions.Edit, - ProjectPermissionDynamicSecretActions.Create, - ProjectPermissionDynamicSecretActions.Delete, + ProjectPermissionDynamicSecretActions.ReadRootCredential, + ProjectPermissionDynamicSecretActions.EditRootCredential, + ProjectPermissionDynamicSecretActions.CreateRootCredential, + ProjectPermissionDynamicSecretActions.DeleteRootCredential, ProjectPermissionDynamicSecretActions.Lease ], ProjectPermissionSub.DynamicSecrets @@ -512,10 +512,10 @@ const buildMemberPermissionRules = () => { ); can( [ - ProjectPermissionDynamicSecretActions.Read, - ProjectPermissionDynamicSecretActions.Edit, - ProjectPermissionDynamicSecretActions.Create, - ProjectPermissionDynamicSecretActions.Delete, + ProjectPermissionDynamicSecretActions.ReadRootCredential, + ProjectPermissionDynamicSecretActions.EditRootCredential, + ProjectPermissionDynamicSecretActions.CreateRootCredential, + ProjectPermissionDynamicSecretActions.DeleteRootCredential, ProjectPermissionDynamicSecretActions.Lease ], ProjectPermissionSub.DynamicSecrets @@ -653,7 +653,7 @@ const buildViewerPermissionRules = () => { can(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets); can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretFolders); - can(ProjectPermissionDynamicSecretActions.Read, ProjectPermissionSub.DynamicSecrets); + can(ProjectPermissionDynamicSecretActions.ReadRootCredential, ProjectPermissionSub.DynamicSecrets); can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretImports); can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval); can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); @@ -773,13 +773,30 @@ export const backfillPermissionV1SchemaToV2Schema = (data: z.infer ({ - ...el, - action: el.action.includes(ProjectPermissionActions.Edit) - ? [...el.action, ProjectPermissionDynamicSecretActions.Lease] - : el.action, - subject: ProjectPermissionSub.DynamicSecrets - })); + const dynamicSecretPolicies = secretSubjects.map(({ subject, ...el }) => { + const action = el.action.map((e) => { + switch (e) { + case ProjectPermissionActions.Edit: + return ProjectPermissionDynamicSecretActions.EditRootCredential; + case ProjectPermissionActions.Create: + return ProjectPermissionDynamicSecretActions.CreateRootCredential; + case ProjectPermissionActions.Delete: + return ProjectPermissionDynamicSecretActions.DeleteRootCredential; + case ProjectPermissionActions.Read: + return ProjectPermissionDynamicSecretActions.ReadRootCredential; + default: + return ProjectPermissionDynamicSecretActions.ReadRootCredential; + } + }); + + return { + ...el, + action: el.action.includes(ProjectPermissionActions.Edit) + ? [...action, ProjectPermissionDynamicSecretActions.Lease] + : action, + subject: ProjectPermissionSub.DynamicSecrets + }; + }); return formattedData.concat( // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts index bcff5bd3a..0abe15858 100644 --- a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts +++ b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts @@ -1,4 +1,4 @@ -import { ForbiddenError, subject } from "@casl/ability"; +import { ForbiddenError } from "@casl/ability"; import picomatch from "picomatch"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; @@ -344,17 +344,8 @@ export const secretApprovalPolicyServiceFactory = ({ environment, secretPath }: TGetBoardSapDTO) => { - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - projectId, - actorAuthMethod, - actorOrgId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { secretPath, environment, secretName: "", secretTags: [] }) - ); + await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId); + return getSecretApprovalPolicy(projectId, environment, secretPath); }; diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts index 1b960ab33..e321039b2 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts @@ -853,7 +853,7 @@ export const secretApprovalRequestServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { environment, secretPath, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); await projectDAL.checkProjectUpgradeStatus(projectId); diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts index 9eadca32b..1dfe276a3 100644 --- a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts +++ b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts @@ -97,7 +97,7 @@ export const secretRotationServiceFactory = ({ if (!folder) throw new NotFoundError({ message: "Secret path not found" }); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { environment, secretPath, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); const project = await projectDAL.findById(projectId); diff --git a/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts b/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts index f4795447f..de285a0f2 100644 --- a/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts +++ b/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts @@ -95,7 +95,7 @@ export const secretSnapshotServiceFactory = ({ // We need to check if the user has access to the secrets in the folder. If we don't do this, a user could theoretically access snapshot secret values even if they don't have read access to the secrets in the folder. ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, path); @@ -127,7 +127,7 @@ export const secretSnapshotServiceFactory = ({ // We need to check if the user has access to the secrets in the folder. If we don't do this, a user could theoretically access snapshot secret values even if they don't have read access to the secrets in the folder. ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, path); @@ -214,9 +214,7 @@ export const secretSnapshotServiceFactory = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment: snapshotDetails.environment.slug, - secretPath: fullFolderPath, - secretName: "", - secretTags: [] + secretPath: fullFolderPath }) ); diff --git a/backend/src/services/integration/integration-service.ts b/backend/src/services/integration/integration-service.ts index 16b5f9936..d511f9689 100644 --- a/backend/src/services/integration/integration-service.ts +++ b/backend/src/services/integration/integration-service.ts @@ -91,9 +91,7 @@ export const integrationServiceFactory = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment: sourceEnvironment, - secretPath, - secretName: "", - secretTags: [] + secretPath }) ); @@ -169,9 +167,7 @@ export const integrationServiceFactory = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment: newEnvironment, - secretPath: newSecretPath, - secretName: "", - secretTags: [] + secretPath: newSecretPath }) ); } diff --git a/backend/src/services/secret-import/secret-import-service.ts b/backend/src/services/secret-import/secret-import-service.ts index 6069693de..e1d0291f6 100644 --- a/backend/src/services/secret-import/secret-import-service.ts +++ b/backend/src/services/secret-import/secret-import-service.ts @@ -92,9 +92,7 @@ export const secretImportServiceFactory = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment: data.environment, - secretPath: data.path, - secretName: "", - secretTags: [] + secretPath: data.path }) ); if (isReplication) { @@ -371,9 +369,7 @@ export const secretImportServiceFactory = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment: secretImportDoc.importEnv.slug, - secretPath: secretImportDoc.importPath, - secretName: "", - secretTags: [] + secretPath: secretImportDoc.importPath }) ); @@ -548,9 +544,7 @@ export const secretImportServiceFactory = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment: el.importEnv.slug, - secretPath: el.importPath, - secretName: "", - secretTags: [] + secretPath: el.importPath }) ) ); @@ -620,9 +614,7 @@ export const secretImportServiceFactory = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment: el.importEnv.slug, - secretPath: el.importPath, - secretName: "", - secretTags: [] + secretPath: el.importPath }) ) ); diff --git a/backend/src/services/secret/secret-fns.ts b/backend/src/services/secret/secret-fns.ts index 5d3a6ef46..4b17bdf92 100644 --- a/backend/src/services/secret/secret-fns.ts +++ b/backend/src/services/secret/secret-fns.ts @@ -185,9 +185,7 @@ export const recursivelyGetSecretPaths = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment, - secretPath: folder.path, - secretName: "", - secretTags: [] + secretPath: folder.path }) ) && folder.path.startsWith(currentPath === "/" ? "" : currentPath) ); diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index e2636a0a9..0b0f627ef 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -187,7 +187,7 @@ export const secretServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); await projectDAL.checkProjectUpgradeStatus(projectId); @@ -296,7 +296,7 @@ export const secretServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); await projectDAL.checkProjectUpgradeStatus(projectId); @@ -433,7 +433,7 @@ export const secretServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); await projectDAL.checkProjectUpgradeStatus(projectId); @@ -538,7 +538,7 @@ export const secretServiceFactory = ({ } else { ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, path); @@ -565,9 +565,7 @@ export const secretServiceFactory = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment: importEnv.slug, - secretPath: importPath, - secretName: "", - secretTags: [] + secretPath: importPath }) ) ); @@ -621,7 +619,7 @@ export const secretServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, path); if (!folder) @@ -673,9 +671,7 @@ export const secretServiceFactory = ({ ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment: importEnv.slug, - secretPath: importPath, - secretName: "", - secretTags: [] + secretPath: importPath }) ) ); @@ -722,7 +718,7 @@ export const secretServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); await projectDAL.checkProjectUpgradeStatus(projectId); @@ -807,7 +803,7 @@ export const secretServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); await projectDAL.checkProjectUpgradeStatus(projectId); @@ -913,7 +909,7 @@ export const secretServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, - subject(ProjectPermissionSub.Secrets, { environment, secretPath: path, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) ); await projectDAL.checkProjectUpgradeStatus(projectId); @@ -2122,7 +2118,7 @@ export const secretServiceFactory = ({ ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { environment, secretPath, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); await projectDAL.checkProjectUpgradeStatus(project.id); @@ -2224,7 +2220,7 @@ export const secretServiceFactory = ({ ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { environment, secretPath, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); await projectDAL.checkProjectUpgradeStatus(project.id); @@ -2413,9 +2409,7 @@ export const secretServiceFactory = ({ ProjectPermissionActions.Delete, subject(ProjectPermissionSub.Secrets, { environment: sourceEnvironment, - secretPath: sourceSecretPath, - secretName: "", - secretTags: [] + secretPath: sourceSecretPath }) ); @@ -2423,9 +2417,7 @@ export const secretServiceFactory = ({ ProjectPermissionActions.Create, subject(ProjectPermissionSub.Secrets, { environment: destinationEnvironment, - secretPath: destinationSecretPath, - secretName: "", - secretTags: [] + secretPath: destinationSecretPath }) ); @@ -2433,9 +2425,7 @@ export const secretServiceFactory = ({ ProjectPermissionActions.Edit, subject(ProjectPermissionSub.Secrets, { environment: destinationEnvironment, - secretPath: destinationSecretPath, - secretName: "", - secretTags: [] + secretPath: destinationSecretPath }) ); diff --git a/backend/src/services/service-token/service-token-service.ts b/backend/src/services/service-token/service-token-service.ts index 480cb438a..5ecbcf54d 100644 --- a/backend/src/services/service-token/service-token-service.ts +++ b/backend/src/services/service-token/service-token-service.ts @@ -66,7 +66,7 @@ export const serviceTokenServiceFactory = ({ scopes.forEach(({ environment, secretPath }) => { ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, - subject(ProjectPermissionSub.Secrets, { environment, secretPath, secretName: "", secretTags: [] }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); }); diff --git a/frontend/src/context/ProjectPermissionContext/types.ts b/frontend/src/context/ProjectPermissionContext/types.ts index 412e768a2..307ef74af 100644 --- a/frontend/src/context/ProjectPermissionContext/types.ts +++ b/frontend/src/context/ProjectPermissionContext/types.ts @@ -8,10 +8,10 @@ export enum ProjectPermissionActions { } export enum ProjectPermissionDynamicSecretActions { - Read = "read", - Create = "create", - Edit = "edit", - Delete = "delete", + ReadRootCredential = "read-root-credential", + CreateRootCredential = "create-root-credential", + EditRootCredential = "edit-root-credential", + DeleteRootCredential = "delete-root-credential", Lease = "lease" } diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts index ec5f7b5a9..463fce6d8 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts @@ -30,11 +30,11 @@ const CmekPolicyActionSchema = z.object({ }); const DynamicSecretPolicyActionSchema = z.object({ - read: z.boolean().optional(), - edit: z.boolean().optional(), - delete: z.boolean().optional(), - create: z.boolean().optional(), - lease: z.boolean().optional() + [ProjectPermissionDynamicSecretActions.ReadRootCredential]: z.boolean().optional(), + [ProjectPermissionDynamicSecretActions.EditRootCredential]: z.boolean().optional(), + [ProjectPermissionDynamicSecretActions.DeleteRootCredential]: z.boolean().optional(), + [ProjectPermissionDynamicSecretActions.CreateRootCredential]: z.boolean().optional(), + [ProjectPermissionDynamicSecretActions.Lease]: z.boolean().optional() }); const SecretRollbackPolicyActionSchema = z.object({ @@ -213,21 +213,25 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { if (!formVal[subject]) formVal[subject] = []; if (subject === ProjectPermissionSub.DynamicSecrets) { - const canRead = action.includes(ProjectPermissionDynamicSecretActions.Read); - const canEdit = action.includes(ProjectPermissionDynamicSecretActions.Edit); - const canDelete = action.includes(ProjectPermissionDynamicSecretActions.Delete); - const canCreate = action.includes(ProjectPermissionDynamicSecretActions.Create); + const canRead = action.includes(ProjectPermissionDynamicSecretActions.ReadRootCredential); + const canEdit = action.includes(ProjectPermissionDynamicSecretActions.EditRootCredential); + const canDelete = action.includes( + ProjectPermissionDynamicSecretActions.DeleteRootCredential + ); + const canCreate = action.includes( + ProjectPermissionDynamicSecretActions.CreateRootCredential + ); const canLease = action.includes(ProjectPermissionDynamicSecretActions.Lease); // from above statement we are sure it won't be undefined formVal[subject]!.push({ - read: canRead, - create: canCreate, - edit: canEdit, - delete: canDelete, + [ProjectPermissionDynamicSecretActions.ReadRootCredential]: canRead, + [ProjectPermissionDynamicSecretActions.CreateRootCredential]: canCreate, + [ProjectPermissionDynamicSecretActions.EditRootCredential]: canEdit, + [ProjectPermissionDynamicSecretActions.EditRootCredential]: canDelete, conditions: conditions ? convertCaslConditionToFormOperator(conditions) : [], inverted, - lease: canLease + [ProjectPermissionDynamicSecretActions.Lease]: canLease }); } else { // for other subjects @@ -387,11 +391,23 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = { [ProjectPermissionSub.DynamicSecrets]: { title: "Dynamic Secrets", actions: [ - { label: "Read", value: "read" }, - { label: "Create", value: "create" }, - { label: "Modify", value: "edit" }, - { label: "Remove", value: "delete" }, - { label: "Manage Leases", value: "lease" } + { + label: "Read root credentials", + value: ProjectPermissionDynamicSecretActions.ReadRootCredential + }, + { + label: "Create root credentials", + value: ProjectPermissionDynamicSecretActions.CreateRootCredential + }, + { + label: "Modify root credentials", + value: ProjectPermissionDynamicSecretActions.EditRootCredential + }, + { + label: "Remove root credentials", + value: ProjectPermissionDynamicSecretActions.DeleteRootCredential + }, + { label: "Manage Leases", value: ProjectPermissionDynamicSecretActions.Lease } ] }, [ProjectPermissionSub.Cmek]: { diff --git a/frontend/src/views/SecretMainPage/SecretMainPage.tsx b/frontend/src/views/SecretMainPage/SecretMainPage.tsx index 7e34da254..58d8d34d9 100644 --- a/frontend/src/views/SecretMainPage/SecretMainPage.tsx +++ b/frontend/src/views/SecretMainPage/SecretMainPage.tsx @@ -94,7 +94,7 @@ export const SecretMainPage = () => { ); const canReadDynamicSecret = permission.can( - ProjectPermissionDynamicSecretActions.Read, + ProjectPermissionDynamicSecretActions.ReadRootCredential, subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath }) ); diff --git a/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx b/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx index 3c1424ada..353ae3b65 100644 --- a/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx +++ b/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx @@ -487,7 +487,7 @@ export const ActionBar = ({ )}
Date: Fri, 18 Oct 2024 01:01:31 +0530 Subject: [PATCH 50/54] feat: small fix in ui for delete root cred --- .../RolePermissionsSection/ProjectRoleModifySection.utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts index 463fce6d8..5832e5a14 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts @@ -228,7 +228,7 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { [ProjectPermissionDynamicSecretActions.ReadRootCredential]: canRead, [ProjectPermissionDynamicSecretActions.CreateRootCredential]: canCreate, [ProjectPermissionDynamicSecretActions.EditRootCredential]: canEdit, - [ProjectPermissionDynamicSecretActions.EditRootCredential]: canDelete, + [ProjectPermissionDynamicSecretActions.DeleteRootCredential]: canDelete, conditions: conditions ? convertCaslConditionToFormOperator(conditions) : [], inverted, [ProjectPermissionDynamicSecretActions.Lease]: canLease From 99e65f7b5916e550b955aa62367248b59bf0cef6 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 18 Oct 2024 01:35:15 +0530 Subject: [PATCH 51/54] feat: added filter folder to remove read only in migration --- .../ee/services/permission/project-permission.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index a3998206d..2210867f0 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -798,11 +798,13 @@ export const backfillPermissionV1SchemaToV2Schema = (data: z.infer i.subject !== ProjectPermissionSub.SecretFolders) + .concat( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-error this is valid ts + secretImportPolicies, + dynamicSecretPolicies, + hasReadOnlyFolder.length ? [] : secretFolderPolicies + ); }; From 78f668bd7fb5c288422ea0aa5c618baa15cc3f9c Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Thu, 17 Oct 2024 17:36:25 -0400 Subject: [PATCH 52/54] Revert "feat: added filter folder to remove read only in migration" --- .../ee/services/permission/project-permission.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index 2210867f0..a3998206d 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -798,13 +798,11 @@ export const backfillPermissionV1SchemaToV2Schema = (data: z.infer i.subject !== ProjectPermissionSub.SecretFolders) - .concat( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error this is valid ts - secretImportPolicies, - dynamicSecretPolicies, - hasReadOnlyFolder.length ? [] : secretFolderPolicies - ); + return formattedData.concat( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-error this is valid ts + secretImportPolicies, + dynamicSecretPolicies, + hasReadOnlyFolder.length ? [] : secretFolderPolicies + ); }; From 8b9244b079592ded3ce46f1c92faa68fd81eebe0 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Thu, 17 Oct 2024 17:37:41 -0400 Subject: [PATCH 53/54] Revert "Permission phase 2" --- .../routes/v3/secret-reference.spec.ts | 22 +- backend/package-lock.json | 614 ++++++-------- .../20240925100349_managed-secret-sharing.ts | 25 +- ...20241003220151_kms-key-cmek-alterations.ts | 12 +- ...20241008172622_project-permission-split.ts | 101 --- ...ity-project-additional-privilege-router.ts | 15 +- .../src/ee/routes/v1/project-role-router.ts | 15 +- .../v1/user-additional-privilege-router.ts | 53 +- backend/src/ee/routes/v2/index.ts | 11 - .../src/ee/routes/v2/project-role-router.ts | 272 ------ .../access-approval-policy-dal.ts | 2 +- .../access-approval-policy-fns.ts | 36 + .../access-approval-policy-service.ts | 68 ++ .../access-approval-request-service.ts | 18 + .../dynamic-secret-lease-service.ts | 25 +- .../dynamic-secret/dynamic-secret-service.ts | 41 +- ...ty-project-additional-privilege-service.ts | 14 +- .../services/permission/permission-service.ts | 4 +- .../services/permission/permission-types.ts | 4 +- .../services/permission/project-permission.ts | 285 +------ ...oject-user-additional-privilege-service.ts | 47 +- .../secret-approval-policy-dal.ts | 2 +- .../secret-approval-policy-service.ts | 15 +- .../secret-approval-request-service.ts | 31 +- .../secret-replication-service.ts | 16 +- .../secret-rotation-service.ts | 5 +- backend/src/lib/casl/knex.ts | 111 +++ backend/src/lib/fn/array.ts | 22 - backend/src/lib/knex/dynamic.ts | 52 +- backend/src/lib/knex/index.ts | 7 +- backend/src/server/plugins/error-handler.ts | 2 +- backend/src/server/routes/index.ts | 9 +- backend/src/server/routes/sanitizedSchemas.ts | 3 +- .../routes/santizedSchemas/permission.ts | 11 - .../src/server/routes/v1/dashboard-router.ts | 25 +- .../external-migration-fns.ts | 4 +- .../integration-delete-secret.ts | 3 +- .../integration/integration-service.ts | 10 +- .../project-role/project-role-service.ts | 2 +- .../secret-folder/secret-folder-fns.ts | 6 + .../secret-folder/secret-folder-service.ts | 73 +- .../secret-import/secret-import-fns.ts | 178 ++-- .../secret-import/secret-import-service.ts | 71 +- .../secret-v2-bridge/secret-v2-bridge-dal.ts | 104 +-- .../secret-v2-bridge/secret-v2-bridge-fns.ts | 61 +- .../secret-v2-bridge-service.ts | 784 ++++++------------ .../secret-v2-bridge-types.ts | 6 - backend/src/services/secret/secret-fns.ts | 6 +- backend/src/services/secret/secret-queue.ts | 7 +- backend/src/services/secret/secret-service.ts | 15 +- .../permissions/GlobPermissionInfo.tsx | 33 - .../permissions/ProjectPermissionCan.tsx | 26 +- frontend/src/components/permissions/index.tsx | 1 - frontend/src/components/v2/Select/Select.tsx | 4 +- .../ProjectPermissionContext/index.tsx | 1 - .../context/ProjectPermissionContext/types.ts | 66 +- frontend/src/context/index.tsx | 1 - .../withProjectPermission.tsx | 30 +- frontend/src/hooks/api/dashboard/queries.tsx | 13 +- frontend/src/hooks/api/dashboard/types.ts | 3 - .../mutation.tsx | 8 +- .../queries.tsx | 8 +- .../projectUserAdditionalPrivilege/types.tsx | 17 +- frontend/src/hooks/api/roles/mutation.tsx | 6 +- frontend/src/hooks/api/roles/queries.tsx | 34 +- frontend/src/hooks/api/roles/types.ts | 1 - frontend/src/lib/fn/array.ts | 19 - frontend/src/lib/fn/object.ts | 20 - .../SpecificPrivilegeSection.tsx | 30 +- .../ProjectRoleModifySection.utils.ts | 208 ++--- .../RolePermissionsSection.tsx | 23 +- .../GeneralPermissionConditions.tsx | 176 ---- ...icies.tsx => GeneralPermissionOptions.tsx} | 60 +- .../components/NewPermissionRule.tsx | 3 +- .../components/PermissionConditionHelpers.tsx | 32 - .../components/SecretPermissionConditions.tsx | 70 +- .../views/SecretMainPage/SecretMainPage.tsx | 74 +- .../components/ActionBar/ActionBar.tsx | 50 +- .../DynamicSecretLease.tsx | 34 +- .../DynamicSecretListView.tsx | 40 +- .../FolderListView/FolderListView.tsx | 21 +- .../SecretDropzone/CopySecretsFromBoard.tsx | 7 +- .../SecretDropzone/SecretDropzone.tsx | 14 +- .../SecretImportListView/SecretImportItem.tsx | 11 +- .../SecretListView/SecretDetaiSidebar.tsx | 76 +- .../components/SecretListView/SecretItem.tsx | 61 +- .../SecretListView/SecretListView.tsx | 11 + .../SecretListView/SecretListView.utils.ts | 7 +- .../SecretListView/SecretNoAccessListView.tsx | 49 -- .../components/SecretListView/index.tsx | 1 - .../SecretOverviewPage/SecretOverviewPage.tsx | 45 +- .../CreateSecretForm/CreateSecretForm.tsx | 29 +- .../SecretOverviewTableRow/SecretEditRow.tsx | 25 +- .../SecretNoAccessOverviewTableRow.tsx | 51 -- .../SecretRenameRow.tsx | 19 +- .../SecretOverviewTableRow/index.tsx | 1 - .../SelectionPanel/SelectionPanel.tsx | 62 +- .../DeleteProjectSection.tsx | 5 +- .../EncryptionTab/EncryptionTab.tsx | 5 +- .../ProjectNameChangeSection.tsx | 5 +- 100 files changed, 1568 insertions(+), 3353 deletions(-) delete mode 100644 backend/src/db/migrations/20241008172622_project-permission-split.ts delete mode 100644 backend/src/ee/routes/v2/index.ts delete mode 100644 backend/src/ee/routes/v2/project-role-router.ts create mode 100644 backend/src/ee/services/access-approval-policy/access-approval-policy-fns.ts create mode 100644 backend/src/lib/casl/knex.ts delete mode 100644 backend/src/server/routes/santizedSchemas/permission.ts create mode 100644 backend/src/services/secret-folder/secret-folder-fns.ts delete mode 100644 frontend/src/components/permissions/GlobPermissionInfo.tsx delete mode 100644 frontend/src/lib/fn/object.ts delete mode 100644 frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx rename frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/{GeneralPermissionPolicies.tsx => GeneralPermissionOptions.tsx} (66%) delete mode 100644 frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/PermissionConditionHelpers.tsx delete mode 100644 frontend/src/views/SecretMainPage/components/SecretListView/SecretNoAccessListView.tsx delete mode 100644 frontend/src/views/SecretOverviewPage/components/SecretOverviewTableRow/SecretNoAccessOverviewTableRow.tsx diff --git a/backend/e2e-test/routes/v3/secret-reference.spec.ts b/backend/e2e-test/routes/v3/secret-reference.spec.ts index 560565342..fb23cdc25 100644 --- a/backend/e2e-test/routes/v3/secret-reference.spec.ts +++ b/backend/e2e-test/routes/v3/secret-reference.spec.ts @@ -56,10 +56,7 @@ describe("Secret expansion", () => { } ]; - for (const secret of secrets) { - // eslint-disable-next-line no-await-in-loop - await createSecretV2(secret); - } + await Promise.all(secrets.map((el) => createSecretV2(el))); const expandedSecret = await getSecretByNameV2({ environmentSlug: seedData1.environment.slug, @@ -126,10 +123,7 @@ describe("Secret expansion", () => { } ]; - for (const secret of secrets) { - // eslint-disable-next-line no-await-in-loop - await createSecretV2(secret); - } + await Promise.all(secrets.map((el) => createSecretV2(el))); const expandedSecret = await getSecretByNameV2({ environmentSlug: seedData1.environment.slug, @@ -196,11 +190,7 @@ describe("Secret expansion", () => { } ]; - for (const secret of secrets) { - // eslint-disable-next-line no-await-in-loop - await createSecretV2(secret); - } - + await Promise.all(secrets.map((el) => createSecretV2(el))); const secretImportFromProdToDev = await createSecretImport({ environmentSlug: seedData1.environment.slug, workspaceId: projectId, @@ -285,11 +275,7 @@ describe("Secret expansion", () => { } ]; - for (const secret of secrets) { - // eslint-disable-next-line no-await-in-loop - await createSecretV2(secret); - } - + await Promise.all(secrets.map((el) => createSecretV2(el))); const secretImportFromProdToDev = await createSecretImport({ environmentSlug: seedData1.environment.slug, workspaceId: projectId, diff --git a/backend/package-lock.json b/backend/package-lock.json index 7d1f95ad8..dbd8c8073 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -3827,14 +3827,13 @@ "license": "MIT" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "cpu": [ "ppc64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "aix" @@ -5852,10 +5851,9 @@ } }, "node_modules/@probot/pino": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@probot/pino/-/pino-2.4.0.tgz", - "integrity": "sha512-KUJ3eK2zLrPny7idWm9eQbBNhCJUjm1A1ttA6U4qiR2/ONWSffVlvr8oR26L59sVhoDkv1DOGmGPZS/bvSFisw==", - "license": "MIT", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@probot/pino/-/pino-2.3.5.tgz", + "integrity": "sha512-IiyiNZonMw1dHC4EAdD55y5owV733d9Gll/IKsrLikB7EJ54+eMCOtL/qo+OmgWN9XV3NTDfziEQF2og/OBKog==", "dependencies": { "@sentry/node": "^6.0.0", "pino-pretty": "^6.0.0", @@ -5924,224 +5922,208 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.3.tgz", + "integrity": "sha512-X9alQ3XM6I9IlSlmC8ddAvMSyG1WuHk5oUnXGw+yUBs3BFoTizmG1La/Gr8fVJvDWAq+zlYTZ9DBgrlKRVY06g==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.3.tgz", + "integrity": "sha512-eQK5JIi+POhFpzk+LnjKIy4Ks+pwJ+NXmPxOCSvOKSNRPONzKuUvWE+P9JxGZVxrtzm6BAYMaL50FFuPe0oWMQ==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.3.tgz", + "integrity": "sha512-Od4vE6f6CTT53yM1jgcLqNfItTsLt5zE46fdPaEmeFHvPs5SjZYlLpHrSiHEKR1+HdRfxuzXHjDOIxQyC3ptBA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.3.tgz", + "integrity": "sha512-0IMAO21axJeNIrvS9lSe/PGthc8ZUS+zC53O0VhF5gMxfmcKAP4ESkKOCwEi6u2asUrt4mQv2rjY8QseIEb1aw==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.3.tgz", + "integrity": "sha512-ge2DC7tHRHa3caVEoSbPRJpq7azhG+xYsd6u2MEnJ6XzPSzQsTKyXvh6iWjXRf7Rt9ykIUWHtl0Uz3T6yXPpKw==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.14.3.tgz", + "integrity": "sha512-ljcuiDI4V3ySuc7eSk4lQ9wU8J8r8KrOUvB2U+TtK0TiW6OFDmJ+DdIjjwZHIw9CNxzbmXY39wwpzYuFDwNXuw==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.3.tgz", + "integrity": "sha512-Eci2us9VTHm1eSyn5/eEpaC7eP/mp5n46gTRB3Aar3BgSvDQGJZuicyq6TsH4HngNBgVqC5sDYxOzTExSU+NjA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.3.tgz", + "integrity": "sha512-UrBoMLCq4E92/LCqlh+blpqMz5h1tJttPIniwUgOFJyjWI1qrtrDhhpHPuFxULlUmjFHfloWdixtDhSxJt5iKw==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.3.tgz", + "integrity": "sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==", "cpu": [ "ppc64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.3.tgz", + "integrity": "sha512-sk/Qh1j2/RJSX7FhEpJn8n0ndxy/uf0kI/9Zc4b1ELhqULVdTfN6HL31CDaTChiBAOgLcsJ1sgVZjWv8XNEsAQ==", "cpu": [ "riscv64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.3.tgz", + "integrity": "sha512-jOO/PEaDitOmY9TgkxF/TQIjXySQe5KVYB57H/8LRP/ux0ZoO8cSHCX17asMSv3ruwslXW/TLBcxyaUzGRHcqg==", "cpu": [ "s390x" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.3.tgz", + "integrity": "sha512-8ybV4Xjy59xLMyWo3GCfEGqtKV5M5gCSrZlxkPGvEPCGDLNla7v48S662HSGwRd6/2cSneMQWiv+QzcttLrrOA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.3.tgz", + "integrity": "sha512-s+xf1I46trOY10OqAtZ5Rm6lzHre/UiLA1J2uOhCFXWkbZrJRkYBPO6FhvGfHmdtQ3Bx793MNa7LvoWFAm93bg==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.3.tgz", + "integrity": "sha512-+4h2WrGOYsOumDQ5S2sYNyhVfrue+9tc9XcLWLh+Kw3UOxAvrfOrSMFon60KspcDdytkNDh7K2Vs6eMaYImAZg==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.3.tgz", + "integrity": "sha512-T1l7y/bCeL/kUwh9OD4PQT4aM7Bq43vX05htPJJ46RTI4r5KNt6qJRzAfNfM+OYMNEVBWQzR2Gyk+FXLZfogGw==", "cpu": [ "ia32" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.3.tgz", + "integrity": "sha512-/BypzV0H1y1HzgYpxqRaXGBRqfodgoBBCcsrujT6QRcakDQdfU+Lq9PENPh5jB4I44YWq+0C2eHsHya+nZY1sA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -7299,11 +7281,10 @@ } }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true }, "node_modules/@types/express": { "version": "4.17.21", @@ -8552,6 +8533,11 @@ "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==" + }, "node_modules/are-we-there-yet": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", @@ -8861,15 +8847,36 @@ } }, "node_modules/avvio": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.4.0.tgz", - "integrity": "sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==", - "license": "MIT", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.2.1.tgz", + "integrity": "sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==", "dependencies": { - "@fastify/error": "^3.3.0", - "fastq": "^1.17.1" + "archy": "^1.0.0", + "debug": "^4.0.0", + "fastq": "^1.6.1" } }, + "node_modules/avvio/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/avvio/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/aws-sdk": { "version": "2.1553.0", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1553.0.tgz", @@ -9728,10 +9735,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "license": "MIT", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } @@ -10923,6 +10929,15 @@ "node": ">= 0.8.0" } }, + "node_modules/express-session/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express-session/node_modules/cookie-signature": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", @@ -10944,6 +10959,15 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "peer": true }, + "node_modules/express/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express/node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -11095,9 +11119,9 @@ } }, "node_modules/fastify": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.28.1.tgz", - "integrity": "sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.26.0.tgz", + "integrity": "sha512-Fq/7ziWKc6pYLYLIlCRaqJqEVTIZ5tZYfcW/mDK2AQ9v/sqjGFpj0On0/7hU50kbPVjLO4de+larPA1WwPZSfw==", "funding": [ { "type": "github", @@ -11108,18 +11132,17 @@ "url": "https://opencollective.com/fastify" } ], - "license": "MIT", "dependencies": { "@fastify/ajv-compiler": "^3.5.0", "@fastify/error": "^3.4.0", "@fastify/fast-json-stringify-compiler": "^4.3.0", "abstract-logging": "^2.0.1", - "avvio": "^8.3.0", + "avvio": "^8.2.1", "fast-content-type-parse": "^1.1.0", "fast-json-stringify": "^5.8.0", "find-my-way": "^8.0.0", "light-my-request": "^5.11.0", - "pino": "^9.0.0", + "pino": "^8.17.0", "process-warning": "^3.0.0", "proxy-addr": "^2.0.7", "rfdc": "^1.3.0", @@ -11133,78 +11156,15 @@ "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", "integrity": "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==" }, - "node_modules/fastify/node_modules/pino": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-9.4.0.tgz", - "integrity": "sha512-nbkQb5+9YPhQRz/BeQmrWpEknAaqjpAqRK8NwJpmrX/JHu7JuZC5G1CeAwJDJfGes4h+YihC6in3Q2nGb+Y09w==", - "license": "MIT", - "dependencies": { - "atomic-sleep": "^1.0.0", - "fast-redact": "^3.1.1", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "^1.2.0", - "pino-std-serializers": "^7.0.0", - "process-warning": "^4.0.0", - "quick-format-unescaped": "^4.0.3", - "real-require": "^0.2.0", - "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^4.0.1", - "thread-stream": "^3.0.0" - }, - "bin": { - "pino": "bin.js" - } - }, - "node_modules/fastify/node_modules/pino-abstract-transport": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", - "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", - "license": "MIT", - "dependencies": { - "readable-stream": "^4.0.0", - "split2": "^4.0.0" - } - }, - "node_modules/fastify/node_modules/pino-std-serializers": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", - "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", - "license": "MIT" - }, - "node_modules/fastify/node_modules/pino/node_modules/process-warning": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.0.tgz", - "integrity": "sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==", - "license": "MIT" - }, "node_modules/fastify/node_modules/process-warning": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" }, - "node_modules/fastify/node_modules/sonic-boom": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.1.0.tgz", - "integrity": "sha512-NGipjjRicyJJ03rPiZCJYjwlsuP2d1/5QUviozRXC7S3WdVWNK5e3Ojieb9CCyfhq2UC+3+SRd9nG3I2lPRvUw==", - "license": "MIT", - "dependencies": { - "atomic-sleep": "^1.0.0" - } - }, - "node_modules/fastify/node_modules/thread-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", - "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", - "license": "MIT", - "dependencies": { - "real-require": "^0.2.0" - } - }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "license": "ISC", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dependencies": { "reusify": "^1.0.4" } @@ -11267,14 +11227,13 @@ "license": "MIT" }, "node_modules/find-my-way": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.2.tgz", - "integrity": "sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==", - "license": "MIT", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.1.0.tgz", + "integrity": "sha512-41QwjCGcVTODUmLLqTMeoHeiozbMXYMAE1CKFiDyi9zVZ2Vjh0yz3MF0WQZoIb+cmzP/XlbFjlF2NtJmvZHznA==", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-querystring": "^1.0.0", - "safe-regex2": "^3.1.0" + "safe-regex2": "^2.0.0" }, "engines": { "node": ">=14" @@ -13421,22 +13380,15 @@ } }, "node_modules/light-my-request": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.13.0.tgz", - "integrity": "sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ==", - "license": "BSD-3-Clause", + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.11.0.tgz", + "integrity": "sha512-qkFCeloXCOMpmEdZ/MV91P8AT4fjwFXWaAFz3lUeStM8RcoM1ks4J/F8r1b3r6y/H4u3ACEJ1T+Gv5bopj7oDA==", "dependencies": { - "cookie": "^0.6.0", - "process-warning": "^3.0.0", + "cookie": "^0.5.0", + "process-warning": "^2.0.0", "set-cookie-parser": "^2.4.1" } }, - "node_modules/light-my-request/node_modules/process-warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", - "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", - "license": "MIT" - }, "node_modules/lilconfig": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", @@ -15261,11 +15213,10 @@ } }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "dev": true, - "license": "ISC" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true }, "node_modules/picomatch": { "version": "3.0.1", @@ -15542,9 +15493,9 @@ } }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -15560,11 +15511,10 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -16390,12 +16340,11 @@ } }, "node_modules/ret": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.4.3.tgz", - "integrity": "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==", - "license": "MIT", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", "engines": { - "node": ">=10" + "node": ">=4" } }, "node_modules/retry": { @@ -16494,13 +16443,12 @@ } }, "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.3.tgz", + "integrity": "sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==", "dev": true, - "license": "MIT", "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.5" }, "bin": { "rollup": "dist/bin/rollup" @@ -16510,22 +16458,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", + "@rollup/rollup-android-arm-eabi": "4.14.3", + "@rollup/rollup-android-arm64": "4.14.3", + "@rollup/rollup-darwin-arm64": "4.14.3", + "@rollup/rollup-darwin-x64": "4.14.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.14.3", + "@rollup/rollup-linux-arm-musleabihf": "4.14.3", + "@rollup/rollup-linux-arm64-gnu": "4.14.3", + "@rollup/rollup-linux-arm64-musl": "4.14.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.14.3", + "@rollup/rollup-linux-riscv64-gnu": "4.14.3", + "@rollup/rollup-linux-s390x-gnu": "4.14.3", + "@rollup/rollup-linux-x64-gnu": "4.14.3", + "@rollup/rollup-linux-x64-musl": "4.14.3", + "@rollup/rollup-win32-arm64-msvc": "4.14.3", + "@rollup/rollup-win32-ia32-msvc": "4.14.3", + "@rollup/rollup-win32-x64-msvc": "4.14.3", "fsevents": "~2.3.2" } }, @@ -16617,12 +16565,11 @@ } }, "node_modules/safe-regex2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-3.1.0.tgz", - "integrity": "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==", - "license": "MIT", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz", + "integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==", "dependencies": { - "ret": "~0.4.0" + "ret": "~0.2.0" } }, "node_modules/safe-stable-stringify": { @@ -16991,11 +16938,10 @@ } }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -18865,15 +18811,14 @@ } }, "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", + "version": "5.2.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.9.tgz", + "integrity": "sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==", "dev": true, - "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" @@ -18892,7 +18837,6 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", - "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -18910,9 +18854,6 @@ "sass": { "optional": true }, - "sass-embedded": { - "optional": true - }, "stylus": { "optional": true }, @@ -18970,14 +18911,13 @@ "dev": true }, "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" @@ -18987,14 +18927,13 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" @@ -19004,14 +18943,13 @@ } }, "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "android" @@ -19021,14 +18959,13 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -19038,14 +18975,13 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -19055,14 +18991,13 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "freebsd" @@ -19072,14 +19007,13 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "freebsd" @@ -19089,14 +19023,13 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "cpu": [ "arm" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -19106,14 +19039,13 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -19123,14 +19055,13 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "cpu": [ "ia32" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -19140,14 +19071,13 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "cpu": [ "loong64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -19157,14 +19087,13 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "cpu": [ "mips64el" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -19174,14 +19103,13 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "cpu": [ "ppc64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -19191,14 +19119,13 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "cpu": [ "riscv64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -19208,14 +19135,13 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "cpu": [ "s390x" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -19225,14 +19151,13 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -19242,14 +19167,13 @@ } }, "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "netbsd" @@ -19259,14 +19183,13 @@ } }, "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "openbsd" @@ -19276,14 +19199,13 @@ } }, "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "sunos" @@ -19293,14 +19215,13 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -19310,14 +19231,13 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "cpu": [ "ia32" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -19327,14 +19247,13 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "win32" @@ -19344,12 +19263,11 @@ } }, "node_modules/vite/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -19357,29 +19275,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "node_modules/vitest": { diff --git a/backend/src/db/migrations/20240925100349_managed-secret-sharing.ts b/backend/src/db/migrations/20240925100349_managed-secret-sharing.ts index f64d7f858..56784d314 100644 --- a/backend/src/db/migrations/20240925100349_managed-secret-sharing.ts +++ b/backend/src/db/migrations/20240925100349_managed-secret-sharing.ts @@ -4,40 +4,27 @@ import { TableName } from "../schemas"; export async function up(knex: Knex): Promise { if (await knex.schema.hasTable(TableName.SecretSharing)) { - const hasEncryptedSecret = await knex.schema.hasColumn(TableName.SecretSharing, "encryptedSecret"); - const hasIdentifier = await knex.schema.hasColumn(TableName.SecretSharing, "identifier"); - await knex.schema.alterTable(TableName.SecretSharing, (t) => { t.string("iv").nullable().alter(); t.string("tag").nullable().alter(); t.string("encryptedValue").nullable().alter(); - if (!hasEncryptedSecret) { - t.binary("encryptedSecret").nullable(); - } + t.binary("encryptedSecret").nullable(); t.string("hashedHex").nullable().alter(); - if (!hasIdentifier) { - t.string("identifier", 64).nullable(); - t.unique("identifier"); - t.index("identifier"); - } + t.string("identifier", 64).nullable(); + t.unique("identifier"); + t.index("identifier"); }); } } export async function down(knex: Knex): Promise { - const hasEncryptedSecret = await knex.schema.hasColumn(TableName.SecretSharing, "encryptedSecret"); - const hasIdentifier = await knex.schema.hasColumn(TableName.SecretSharing, "identifier"); if (await knex.schema.hasTable(TableName.SecretSharing)) { await knex.schema.alterTable(TableName.SecretSharing, (t) => { - if (hasEncryptedSecret) { - t.dropColumn("encryptedSecret"); - } + t.dropColumn("encryptedSecret"); - if (hasIdentifier) { - t.dropColumn("identifier"); - } + t.dropColumn("identifier"); }); } } diff --git a/backend/src/db/migrations/20241003220151_kms-key-cmek-alterations.ts b/backend/src/db/migrations/20241003220151_kms-key-cmek-alterations.ts index bdad443c9..6b701eea4 100644 --- a/backend/src/db/migrations/20241003220151_kms-key-cmek-alterations.ts +++ b/backend/src/db/migrations/20241003220151_kms-key-cmek-alterations.ts @@ -7,18 +7,15 @@ export async function up(knex: Knex): Promise { if (await knex.schema.hasTable(TableName.KmsKey)) { const hasOrgId = await knex.schema.hasColumn(TableName.KmsKey, "orgId"); const hasSlug = await knex.schema.hasColumn(TableName.KmsKey, "slug"); - const hasProjectId = await knex.schema.hasColumn(TableName.KmsKey, "projectId"); // drop constraint if exists (won't exist if rolled back, see below) await dropConstraintIfExists(TableName.KmsKey, "kms_keys_orgid_slug_unique", knex); // projectId for CMEK functionality await knex.schema.alterTable(TableName.KmsKey, (table) => { - if (!hasProjectId) { - table.string("projectId").nullable().references("id").inTable(TableName.Project).onDelete("CASCADE"); - } + table.string("projectId").nullable().references("id").inTable(TableName.Project).onDelete("CASCADE"); - if (hasOrgId && hasSlug) { + if (hasOrgId) { table.unique(["orgId", "projectId", "slug"]); } @@ -33,7 +30,6 @@ export async function down(knex: Knex): Promise { if (await knex.schema.hasTable(TableName.KmsKey)) { const hasOrgId = await knex.schema.hasColumn(TableName.KmsKey, "orgId"); const hasName = await knex.schema.hasColumn(TableName.KmsKey, "name"); - const hasProjectId = await knex.schema.hasColumn(TableName.KmsKey, "projectId"); // remove projectId for CMEK functionality await knex.schema.alterTable(TableName.KmsKey, (table) => { @@ -44,9 +40,7 @@ export async function down(knex: Knex): Promise { if (hasOrgId) { table.dropUnique(["orgId", "projectId", "slug"]); } - if (hasProjectId) { - table.dropColumn("projectId"); - } + table.dropColumn("projectId"); }); } } diff --git a/backend/src/db/migrations/20241008172622_project-permission-split.ts b/backend/src/db/migrations/20241008172622_project-permission-split.ts deleted file mode 100644 index 3b322b18f..000000000 --- a/backend/src/db/migrations/20241008172622_project-permission-split.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* eslint-disable no-await-in-loop */ -import { packRules, unpackRules } from "@casl/ability/extra"; -import { Knex } from "knex"; - -import { - backfillPermissionV1SchemaToV2Schema, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; - -import { TableName } from "../schemas"; - -const CHUNK_SIZE = 1000; -export async function up(knex: Knex): Promise { - const hasVersion = await knex.schema.hasColumn(TableName.ProjectRoles, "version"); - if (!hasVersion) { - await knex.schema.alterTable(TableName.ProjectRoles, (t) => { - t.integer("version").defaultTo(1).notNullable(); - }); - - const docs = await knex(TableName.ProjectRoles).select("*"); - const updatedDocs = docs - .filter((i) => { - const permissionString = JSON.stringify(i.permissions || []); - return ( - !permissionString.includes(ProjectPermissionSub.SecretImports) && - !permissionString.includes(ProjectPermissionSub.DynamicSecrets) - ); - }) - .map((el) => ({ - ...el, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error this is valid ts - permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(unpackRules(el.permissions)))) - })); - if (updatedDocs.length) { - for (let i = 0; i < updatedDocs.length; i += CHUNK_SIZE) { - const chunk = updatedDocs.slice(i, i + CHUNK_SIZE); - await knex(TableName.ProjectRoles).insert(chunk).onConflict("id").merge(); - } - } - - // secret permission is split into multiple ones like secrets, folders, imports and dynamic-secrets - // so we just find all the privileges with respective mapping and map it as needed - const identityPrivileges = await knex(TableName.IdentityProjectAdditionalPrivilege).select("*"); - const updatedIdentityPrivilegesDocs = identityPrivileges - .filter((i) => { - const permissionString = JSON.stringify(i.permissions || []); - return ( - !permissionString.includes(ProjectPermissionSub.SecretImports) && - !permissionString.includes(ProjectPermissionSub.DynamicSecrets) && - !permissionString.includes(ProjectPermissionSub.SecretFolders) - ); - }) - .map((el) => ({ - ...el, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error this is valid ts - permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(unpackRules(el.permissions)))) - })); - if (updatedIdentityPrivilegesDocs.length) { - for (let i = 0; i < updatedIdentityPrivilegesDocs.length; i += CHUNK_SIZE) { - const chunk = updatedIdentityPrivilegesDocs.slice(i, i + CHUNK_SIZE); - await knex(TableName.IdentityProjectAdditionalPrivilege).insert(chunk).onConflict("id").merge(); - } - } - - const userPrivileges = await knex(TableName.ProjectUserAdditionalPrivilege).select("*"); - const updatedUserPrivilegeDocs = userPrivileges - .filter((i) => { - const permissionString = JSON.stringify(i.permissions || []); - return ( - !permissionString.includes(ProjectPermissionSub.SecretImports) && - !permissionString.includes(ProjectPermissionSub.DynamicSecrets) && - !permissionString.includes(ProjectPermissionSub.SecretFolders) - ); - }) - .map((el) => ({ - ...el, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error this is valid ts - permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(unpackRules(el.permissions)))) - })); - if (docs.length) { - for (let i = 0; i < updatedUserPrivilegeDocs.length; i += CHUNK_SIZE) { - const chunk = updatedUserPrivilegeDocs.slice(i, i + CHUNK_SIZE); - await knex(TableName.ProjectUserAdditionalPrivilege).insert(chunk).onConflict("id").merge(); - } - } - } -} - -export async function down(knex: Knex): Promise { - const hasVersion = await knex.schema.hasColumn(TableName.ProjectRoles, "version"); - if (hasVersion) { - await knex.schema.alterTable(TableName.ProjectRoles, (t) => { - t.dropColumn("version"); - }); - - // permission change can be ignored - } -} diff --git a/backend/src/ee/routes/v1/identity-project-additional-privilege-router.ts b/backend/src/ee/routes/v1/identity-project-additional-privilege-router.ts index 91a4402fb..2e7fd60d3 100644 --- a/backend/src/ee/routes/v1/identity-project-additional-privilege-router.ts +++ b/backend/src/ee/routes/v1/identity-project-additional-privilege-router.ts @@ -4,7 +4,6 @@ import ms from "ms"; import { z } from "zod"; import { IdentityProjectAdditionalPrivilegeTemporaryMode } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-types"; -import { backfillPermissionV1SchemaToV2Schema } from "@app/ee/services/permission/project-permission"; import { IDENTITY_ADDITIONAL_PRIVILEGE } from "@app/lib/api-docs"; import { UnauthorizedError } from "@app/lib/errors"; import { alphaNumericNanoId } from "@app/lib/nanoid"; @@ -80,9 +79,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F ...req.body, slug: req.body.slug ? slugify(req.body.slug) : slugify(alphaNumericNanoId(12)), isTemporary: false, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error this is valid ts - permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(permission))) + permissions: JSON.stringify(packRules(permission)) }); return { privilege }; } @@ -162,9 +159,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F ...req.body, slug: req.body.slug ? slugify(req.body.slug) : slugify(alphaNumericNanoId(12)), isTemporary: true, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error this is valid ts - permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(permission))) + permissions: JSON.stringify(packRules(permission)) }); return { privilege }; } @@ -249,11 +244,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F projectSlug: req.body.projectSlug, data: { ...updatedInfo, - permissions: permission - ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error this is valid ts - JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(permission))) - : undefined + permissions: permission ? JSON.stringify(packRules(permission)) : undefined } }); return { privilege }; diff --git a/backend/src/ee/routes/v1/project-role-router.ts b/backend/src/ee/routes/v1/project-role-router.ts index 9edd29030..392046757 100644 --- a/backend/src/ee/routes/v1/project-role-router.ts +++ b/backend/src/ee/routes/v1/project-role-router.ts @@ -3,10 +3,7 @@ import slugify from "@sindresorhus/slugify"; import { z } from "zod"; import { ProjectMembershipRole, ProjectMembershipsSchema, ProjectRolesSchema } from "@app/db/schemas"; -import { - backfillPermissionV1SchemaToV2Schema, - ProjectPermissionV1Schema -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionSchema } from "@app/ee/services/permission/project-permission"; import { PROJECT_ROLE } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -46,7 +43,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { .describe(PROJECT_ROLE.CREATE.slug), name: z.string().min(1).trim().describe(PROJECT_ROLE.CREATE.name), description: z.string().trim().optional().describe(PROJECT_ROLE.CREATE.description), - permissions: ProjectPermissionV1Schema.array().describe(PROJECT_ROLE.CREATE.permissions) + permissions: ProjectPermissionSchema.array().describe(PROJECT_ROLE.CREATE.permissions) }), response: { 200: z.object({ @@ -64,7 +61,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { projectSlug: req.params.projectSlug, data: { ...req.body, - permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions))) + permissions: JSON.stringify(packRules(req.body.permissions)) } }); return { role }; @@ -106,7 +103,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { }), name: z.string().trim().optional().describe(PROJECT_ROLE.UPDATE.name), description: z.string().trim().optional().describe(PROJECT_ROLE.UPDATE.description), - permissions: ProjectPermissionV1Schema.array().describe(PROJECT_ROLE.UPDATE.permissions).optional() + permissions: ProjectPermissionSchema.array().describe(PROJECT_ROLE.UPDATE.permissions).optional() }), response: { 200: z.object({ @@ -125,9 +122,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { roleId: req.params.roleId, data: { ...req.body, - permissions: req.body.permissions - ? JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions))) - : undefined + permissions: req.body.permissions ? JSON.stringify(packRules(req.body.permissions)) : undefined } }); return { role }; diff --git a/backend/src/ee/routes/v1/user-additional-privilege-router.ts b/backend/src/ee/routes/v1/user-additional-privilege-router.ts index 1ba7e0e33..7225caecf 100644 --- a/backend/src/ee/routes/v1/user-additional-privilege-router.ts +++ b/backend/src/ee/routes/v1/user-additional-privilege-router.ts @@ -1,16 +1,13 @@ -import { packRules } from "@casl/ability/extra"; import slugify from "@sindresorhus/slugify"; import ms from "ms"; import { z } from "zod"; import { ProjectUserAdditionalPrivilegeSchema } from "@app/db/schemas"; -import { backfillPermissionV1SchemaToV2Schema } from "@app/ee/services/permission/project-permission"; import { ProjectUserAdditionalPrivilegeTemporaryMode } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-types"; import { PROJECT_USER_ADDITIONAL_PRIVILEGE } from "@app/lib/api-docs"; import { alphaNumericNanoId } from "@app/lib/nanoid"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; -import { ProjectSpecificPrivilegePermissionSchema } from "@app/server/routes/sanitizedSchemas"; import { AuthMode } from "@app/services/auth/auth-type"; export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodProvider) => { @@ -34,9 +31,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr }) .optional() .describe(PROJECT_USER_ADDITIONAL_PRIVILEGE.CREATE.slug), - permissions: ProjectSpecificPrivilegePermissionSchema.describe( - PROJECT_USER_ADDITIONAL_PRIVILEGE.CREATE.permissions - ) + permissions: z.any().array().describe(PROJECT_USER_ADDITIONAL_PRIVILEGE.CREATE.permissions) }), response: { 200: z.object({ @@ -54,17 +49,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr ...req.body, slug: req.body.slug ? slugify(req.body.slug) : slugify(alphaNumericNanoId(12)), isTemporary: false, - permissions: JSON.stringify( - packRules( - backfillPermissionV1SchemaToV2Schema( - req.body.permissions.actions.map((action) => ({ - action, - subject: req.body.permissions.subject, - conditions: req.body.permissions.conditions - })) - ) - ) - ) + permissions: JSON.stringify(req.body.permissions) }); return { privilege }; } @@ -90,9 +75,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr }) .optional() .describe(PROJECT_USER_ADDITIONAL_PRIVILEGE.CREATE.slug), - permissions: ProjectSpecificPrivilegePermissionSchema.describe( - PROJECT_USER_ADDITIONAL_PRIVILEGE.CREATE.permissions - ), + permissions: z.any().array().describe(PROJECT_USER_ADDITIONAL_PRIVILEGE.CREATE.permissions), temporaryMode: z .nativeEnum(ProjectUserAdditionalPrivilegeTemporaryMode) .describe(PROJECT_USER_ADDITIONAL_PRIVILEGE.CREATE.temporaryMode), @@ -121,17 +104,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr ...req.body, slug: req.body.slug ? slugify(req.body.slug) : `privilege-${slugify(alphaNumericNanoId(12))}`, isTemporary: true, - permissions: JSON.stringify( - packRules( - backfillPermissionV1SchemaToV2Schema( - req.body.permissions.actions.map((action) => ({ - action, - subject: req.body.permissions.subject, - conditions: req.body.permissions.conditions - })) - ) - ) - ) + permissions: JSON.stringify(req.body.permissions) }); return { privilege }; } @@ -158,9 +131,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr message: "Slug must be a valid slug" }) .describe(PROJECT_USER_ADDITIONAL_PRIVILEGE.UPDATE.slug), - permissions: ProjectSpecificPrivilegePermissionSchema.describe( - PROJECT_USER_ADDITIONAL_PRIVILEGE.UPDATE.permissions - ).optional(), + permissions: z.any().array().describe(PROJECT_USER_ADDITIONAL_PRIVILEGE.UPDATE.permissions), isTemporary: z.boolean().describe(PROJECT_USER_ADDITIONAL_PRIVILEGE.UPDATE.isTemporary), temporaryMode: z .nativeEnum(ProjectUserAdditionalPrivilegeTemporaryMode) @@ -189,19 +160,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr actorOrgId: req.permission.orgId, actorAuthMethod: req.permission.authMethod, ...req.body, - permissions: req.body.permissions - ? JSON.stringify( - packRules( - backfillPermissionV1SchemaToV2Schema( - req.body.permissions.actions.map((action) => ({ - action, - subject: req.body.permissions!.subject, - conditions: req.body.permissions!.conditions - })) - ) - ) - ) - : undefined, + permissions: req.body.permissions ? JSON.stringify(req.body.permissions) : undefined, privilegeId: req.params.privilegeId }); return { privilege }; diff --git a/backend/src/ee/routes/v2/index.ts b/backend/src/ee/routes/v2/index.ts deleted file mode 100644 index 980e4777b..000000000 --- a/backend/src/ee/routes/v2/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { registerProjectRoleRouter } from "./project-role-router"; - -export const registerV2EERoutes = async (server: FastifyZodProvider) => { - // org role starts with organization - await server.register( - async (projectRouter) => { - await projectRouter.register(registerProjectRoleRouter); - }, - { prefix: "/workspace" } - ); -}; diff --git a/backend/src/ee/routes/v2/project-role-router.ts b/backend/src/ee/routes/v2/project-role-router.ts deleted file mode 100644 index 86d64141d..000000000 --- a/backend/src/ee/routes/v2/project-role-router.ts +++ /dev/null @@ -1,272 +0,0 @@ -import { packRules } from "@casl/ability/extra"; -import slugify from "@sindresorhus/slugify"; -import { z } from "zod"; - -import { ProjectMembershipRole, ProjectMembershipsSchema, ProjectRolesSchema } from "@app/db/schemas"; -import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; -import { PROJECT_ROLE } from "@app/lib/api-docs"; -import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; -import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; -import { SanitizedRoleSchema } from "@app/server/routes/sanitizedSchemas"; -import { AuthMode } from "@app/services/auth/auth-type"; - -export const registerProjectRoleRouter = async (server: FastifyZodProvider) => { - server.route({ - method: "POST", - url: "/:projectSlug/roles", - config: { - rateLimit: writeLimit - }, - schema: { - description: "Create a project role", - security: [ - { - bearerAuth: [] - } - ], - params: z.object({ - projectSlug: z.string().trim().describe(PROJECT_ROLE.CREATE.projectSlug) - }), - body: z.object({ - slug: z - .string() - .toLowerCase() - .trim() - .min(1) - .refine( - (val) => !Object.values(ProjectMembershipRole).includes(val as ProjectMembershipRole), - "Please choose a different slug, the slug you have entered is reserved" - ) - .refine((v) => slugify(v) === v, { - message: "Slug must be a valid" - }) - .describe(PROJECT_ROLE.CREATE.slug), - name: z.string().min(1).trim().describe(PROJECT_ROLE.CREATE.name), - description: z.string().trim().optional().describe(PROJECT_ROLE.CREATE.description), - permissions: ProjectPermissionV2Schema.array().describe(PROJECT_ROLE.CREATE.permissions) - }), - response: { - 200: z.object({ - role: SanitizedRoleSchema - }) - } - }, - onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), - handler: async (req) => { - const role = await server.services.projectRole.createRole({ - actorAuthMethod: req.permission.authMethod, - actorId: req.permission.id, - actorOrgId: req.permission.orgId, - actor: req.permission.type, - projectSlug: req.params.projectSlug, - data: { - ...req.body, - permissions: JSON.stringify(packRules(req.body.permissions)) - } - }); - return { role }; - } - }); - - server.route({ - method: "PATCH", - url: "/:projectSlug/roles/:roleId", - config: { - rateLimit: writeLimit - }, - schema: { - description: "Update a project role", - security: [ - { - bearerAuth: [] - } - ], - params: z.object({ - projectSlug: z.string().trim().describe(PROJECT_ROLE.UPDATE.projectSlug), - roleId: z.string().trim().describe(PROJECT_ROLE.UPDATE.roleId) - }), - body: z.object({ - slug: z - .string() - .toLowerCase() - .trim() - .optional() - .describe(PROJECT_ROLE.UPDATE.slug) - .refine( - (val) => - typeof val === "undefined" || - !Object.values(ProjectMembershipRole).includes(val as ProjectMembershipRole), - "Please choose a different slug, the slug you have entered is reserved" - ) - .refine((val) => typeof val === "undefined" || slugify(val) === val, { - message: "Slug must be a valid" - }), - name: z.string().trim().optional().describe(PROJECT_ROLE.UPDATE.name), - description: z.string().trim().optional().describe(PROJECT_ROLE.UPDATE.description), - permissions: ProjectPermissionV2Schema.array().describe(PROJECT_ROLE.UPDATE.permissions).optional() - }), - response: { - 200: z.object({ - role: SanitizedRoleSchema - }) - } - }, - onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), - handler: async (req) => { - const role = await server.services.projectRole.updateRole({ - actorAuthMethod: req.permission.authMethod, - actorId: req.permission.id, - actorOrgId: req.permission.orgId, - actor: req.permission.type, - projectSlug: req.params.projectSlug, - roleId: req.params.roleId, - data: { - ...req.body, - permissions: req.body.permissions ? JSON.stringify(packRules(req.body.permissions)) : undefined - } - }); - return { role }; - } - }); - - server.route({ - method: "DELETE", - url: "/:projectSlug/roles/:roleId", - config: { - rateLimit: writeLimit - }, - schema: { - description: "Delete a project role", - security: [ - { - bearerAuth: [] - } - ], - params: z.object({ - projectSlug: z.string().trim().describe(PROJECT_ROLE.DELETE.projectSlug), - roleId: z.string().trim().describe(PROJECT_ROLE.DELETE.roleId) - }), - response: { - 200: z.object({ - role: SanitizedRoleSchema - }) - } - }, - onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), - handler: async (req) => { - const role = await server.services.projectRole.deleteRole({ - actorAuthMethod: req.permission.authMethod, - actorId: req.permission.id, - actorOrgId: req.permission.orgId, - actor: req.permission.type, - projectSlug: req.params.projectSlug, - roleId: req.params.roleId - }); - return { role }; - } - }); - - server.route({ - method: "GET", - url: "/:projectSlug/roles", - config: { - rateLimit: readLimit - }, - schema: { - description: "List project role", - security: [ - { - bearerAuth: [] - } - ], - params: z.object({ - projectSlug: z.string().trim().describe(PROJECT_ROLE.LIST.projectSlug) - }), - response: { - 200: z.object({ - roles: ProjectRolesSchema.omit({ permissions: true }).array() - }) - } - }, - onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), - handler: async (req) => { - const roles = await server.services.projectRole.listRoles({ - actorAuthMethod: req.permission.authMethod, - actorId: req.permission.id, - actorOrgId: req.permission.orgId, - actor: req.permission.type, - projectSlug: req.params.projectSlug - }); - return { roles }; - } - }); - - server.route({ - method: "GET", - url: "/:projectSlug/roles/slug/:roleSlug", - config: { - rateLimit: readLimit - }, - schema: { - params: z.object({ - projectSlug: z.string().trim().describe(PROJECT_ROLE.GET_ROLE_BY_SLUG.projectSlug), - roleSlug: z.string().trim().describe(PROJECT_ROLE.GET_ROLE_BY_SLUG.roleSlug) - }), - response: { - 200: z.object({ - role: SanitizedRoleSchema - }) - } - }, - onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), - handler: async (req) => { - const role = await server.services.projectRole.getRoleBySlug({ - actorAuthMethod: req.permission.authMethod, - actorId: req.permission.id, - actorOrgId: req.permission.orgId, - actor: req.permission.type, - projectSlug: req.params.projectSlug, - roleSlug: req.params.roleSlug - }); - return { role }; - } - }); - - server.route({ - method: "GET", - url: "/:projectId/permissions", - config: { - rateLimit: readLimit - }, - schema: { - params: z.object({ - projectId: z.string().trim() - }), - response: { - 200: z.object({ - data: z.object({ - membership: ProjectMembershipsSchema.extend({ - roles: z - .object({ - role: z.string() - }) - .array() - }), - permissions: z.any().array() - }) - }) - } - }, - onRequest: verifyAuth([AuthMode.JWT]), - handler: async (req) => { - const { permissions, membership } = await server.services.projectRole.getUserPermission( - req.permission.id, - req.params.projectId, - req.permission.authMethod, - req.permission.orgId - ); - - return { data: { permissions, membership } }; - } - }); -}; diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts index 220701410..569580507 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts @@ -14,7 +14,7 @@ export const accessApprovalPolicyDALFactory = (db: TDbClient) => { const accessApprovalPolicyFindQuery = async ( tx: Knex, - filter: TFindFilter, + filter: TFindFilter, customFilter?: { policyId?: string; } diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-fns.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-fns.ts new file mode 100644 index 000000000..0e242f04c --- /dev/null +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-fns.ts @@ -0,0 +1,36 @@ +import { ForbiddenError, subject } from "@casl/ability"; + +import { ActorType } from "@app/services/auth/auth-type"; + +import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission"; +import { TIsApproversValid } from "./access-approval-policy-types"; + +export const isApproversValid = async ({ + userIds, + projectId, + orgId, + envSlug, + actorAuthMethod, + secretPath, + permissionService +}: TIsApproversValid) => { + try { + for await (const userId of userIds) { + const { permission: approverPermission } = await permissionService.getProjectPermission( + ActorType.USER, + userId, + projectId, + actorAuthMethod, + orgId + ); + + ForbiddenError.from(approverPermission).throwUnlessCan( + ProjectPermissionActions.Create, + subject(ProjectPermissionSub.Secrets, { environment: envSlug, secretPath }) + ); + } + } catch { + return false; + } + return true; +}; diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts index f5151b0b7..2633a026f 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts @@ -11,6 +11,7 @@ import { TUserDALFactory } from "@app/services/user/user-dal"; import { TGroupDALFactory } from "../group/group-dal"; import { TAccessApprovalPolicyApproverDALFactory } from "./access-approval-policy-approver-dal"; import { TAccessApprovalPolicyDALFactory } from "./access-approval-policy-dal"; +import { isApproversValid } from "./access-approval-policy-fns"; import { ApproverType, TCreateAccessApprovalPolicy, @@ -131,6 +132,22 @@ export const accessApprovalPolicyServiceFactory = ({ .map((user) => user.id); verifyAllApprovers.push(...verifyGroupApprovers); + const approversValid = await isApproversValid({ + projectId: project.id, + orgId: actorOrgId, + envSlug: environment, + secretPath, + actorAuthMethod, + permissionService, + userIds: verifyAllApprovers + }); + + if (!approversValid) { + throw new BadRequestError({ + message: "One or more approvers doesn't have access to be specified secret path" + }); + } + const accessApproval = await accessApprovalPolicyDAL.transaction(async (tx) => { const doc = await accessApprovalPolicyDAL.create( { @@ -272,6 +289,22 @@ export const accessApprovalPolicyServiceFactory = ({ userApproverIds = userApproverIds.concat(approverUsers.map((user) => user.id)); } + const approversValid = await isApproversValid({ + projectId: accessApprovalPolicy.projectId, + orgId: actorOrgId, + envSlug: accessApprovalPolicy.environment.slug, + secretPath: doc.secretPath!, + actorAuthMethod, + permissionService, + userIds: userApproverIds + }); + + if (!approversValid) { + throw new BadRequestError({ + message: "One or more approvers doesn't have access to be specified secret path" + }); + } + await accessApprovalPolicyApproverDAL.insertMany( userApproverIds.map((userId) => ({ approverUserId: userId, @@ -282,6 +315,41 @@ export const accessApprovalPolicyServiceFactory = ({ } if (groupApprovers) { + const usersPromises: Promise< + { + id: string; + email: string | null | undefined; + username: string; + firstName: string | null | undefined; + lastName: string | null | undefined; + isPartOfGroup: boolean; + }[] + >[] = []; + + for (const groupId of groupApprovers) { + usersPromises.push(groupDAL.findAllGroupPossibleMembers({ orgId: actorOrgId, groupId, offset: 0 })); + } + const verifyGroupApprovers = (await Promise.all(usersPromises)) + .flat() + .filter((user) => user.isPartOfGroup) + .map((user) => user.id); + + const approversValid = await isApproversValid({ + projectId: accessApprovalPolicy.projectId, + orgId: actorOrgId, + envSlug: accessApprovalPolicy.environment.slug, + secretPath: doc.secretPath!, + actorAuthMethod, + permissionService, + userIds: verifyGroupApprovers + }); + + if (!approversValid) { + throw new BadRequestError({ + message: "One or more approvers doesn't have access to be specified secret path" + }); + } + await accessApprovalPolicyApproverDAL.insertMany( groupApprovers.map((groupId) => ({ approverGroupId: groupId, diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts index 1e2c67f02..7c1f00a37 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts @@ -17,6 +17,7 @@ import { TUserDALFactory } from "@app/services/user/user-dal"; import { TAccessApprovalPolicyApproverDALFactory } from "../access-approval-policy/access-approval-policy-approver-dal"; import { TAccessApprovalPolicyDALFactory } from "../access-approval-policy/access-approval-policy-dal"; +import { isApproversValid } from "../access-approval-policy/access-approval-policy-fns"; import { TGroupDALFactory } from "../group/group-dal"; import { TPermissionServiceFactory } from "../permission/permission-service"; import { TProjectUserAdditionalPrivilegeDALFactory } from "../project-user-additional-privilege/project-user-additional-privilege-dal"; @@ -77,6 +78,7 @@ export const accessApprovalRequestServiceFactory = ({ permissionService, accessApprovalRequestDAL, accessApprovalRequestReviewerDAL, + projectMembershipDAL, accessApprovalPolicyDAL, accessApprovalPolicyApproverDAL, additionalPrivilegeDAL, @@ -321,6 +323,22 @@ export const accessApprovalRequestServiceFactory = ({ throw new ForbiddenRequestError({ message: "You are not authorized to approve this request" }); } + const reviewerProjectMembership = await projectMembershipDAL.findById(membership.id); + + const approversValid = await isApproversValid({ + projectId: accessApprovalRequest.projectId, + orgId: actorOrgId, + envSlug: accessApprovalRequest.environment, + secretPath: accessApprovalRequest.policy.secretPath!, + actorAuthMethod, + permissionService, + userIds: [reviewerProjectMembership.userId] + }); + + if (!approversValid) { + throw new ForbiddenRequestError({ message: "You don't have access to approve this request" }); + } + const existingReviews = await accessApprovalRequestReviewerDAL.find({ requestId: accessApprovalRequest.id }); if (existingReviews.some((review) => review.status === ApprovalStatus.REJECTED)) { throw new BadRequestError({ message: "The request has already been rejected by another reviewer" }); diff --git a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts index 77dc0d9d3..306c7ca26 100644 --- a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts +++ b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts @@ -4,10 +4,7 @@ import ms from "ms"; import { SecretKeyEncoding } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionDynamicSecretActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; import { infisicalSymmetricDecrypt } from "@app/lib/crypto/encryption"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; @@ -75,8 +72,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Lease, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const plan = await licenseService.getPlan(actorOrgId); @@ -148,8 +145,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Lease, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const plan = await licenseService.getPlan(actorOrgId); @@ -222,8 +219,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Lease, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Delete, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -287,8 +284,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Lease, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -323,8 +320,8 @@ export const dynamicSecretLeaseServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.Lease, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); diff --git a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts index c202b3eda..eec9094cb 100644 --- a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts +++ b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts @@ -3,10 +3,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import { SecretKeyEncoding } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionDynamicSecretActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { infisicalSymmetricDecrypt, infisicalSymmetricEncypt } from "@app/lib/crypto/encryption"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { OrderByDirection } from "@app/lib/types"; @@ -80,8 +77,8 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.CreateRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Create, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const plan = await licenseService.getPlan(actorOrgId); @@ -149,8 +146,8 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.EditRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const plan = await licenseService.getPlan(actorOrgId); @@ -228,8 +225,8 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.DeleteRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -285,12 +282,8 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.ReadRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.EditRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -335,8 +328,8 @@ export const dynamicSecretServiceFactory = ({ // verify user has access to each env in request environmentSlugs.forEach((environmentSlug) => ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.ReadRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ) ); } @@ -371,8 +364,8 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.ReadRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -417,8 +410,8 @@ export const dynamicSecretServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.ReadRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ); const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path); @@ -459,8 +452,8 @@ export const dynamicSecretServiceFactory = ({ // verify user has access to each env in request environmentSlugs.forEach((environmentSlug) => ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionDynamicSecretActions.ReadRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path }) ) ); } diff --git a/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts b/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts index 0e47b2160..f5c1c857a 100644 --- a/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts +++ b/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts @@ -1,10 +1,10 @@ import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability"; import { PackRule, unpackRules } from "@casl/ability/extra"; import ms from "ms"; +import { z } from "zod"; import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; -import { UnpackedPermissionSchema } from "@app/server/routes/santizedSchemas/permission"; import { ActorType } from "@app/services/auth/auth-type"; import { TIdentityProjectDALFactory } from "@app/services/identity-project/identity-project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal"; @@ -32,6 +32,16 @@ export type TIdentityProjectAdditionalPrivilegeServiceFactory = ReturnType< typeof identityProjectAdditionalPrivilegeServiceFactory >; +// TODO(akhilmhdh): move this to more centralized +export const UnpackedPermissionSchema = z.object({ + subject: z + .union([z.string().min(1), z.string().array()]) + .transform((el) => (typeof el !== "string" ? el[0] : el)) + .optional(), + action: z.union([z.string().min(1), z.string().array()]).transform((el) => (typeof el === "string" ? [el] : el)), + conditions: z.unknown().optional() +}); + const unpackPermissions = (permissions: unknown) => UnpackedPermissionSchema.array().parse( unpackRules((permissions || []) as PackRule>>[]) @@ -193,6 +203,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ }); return { ...additionalPrivilege, + permissions: unpackPermissions(additionalPrivilege.permissions) }; }; @@ -313,6 +324,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ }); return identityPrivileges.map((el) => ({ ...el, + permissions: unpackPermissions(el.permissions) })); }; diff --git a/backend/src/ee/services/permission/permission-service.ts b/backend/src/ee/services/permission/permission-service.ts index ccd896775..ea0289ab0 100644 --- a/backend/src/ee/services/permission/permission-service.ts +++ b/backend/src/ee/services/permission/permission-service.ts @@ -67,7 +67,7 @@ export const permissionServiceFactory = ({ throw new NotFoundError({ name: "OrgRoleInvalid", message: "Organization role not found" }); } }) - .reduce((prev, curr) => prev.concat(curr), []); + .reduce((curr, prev) => prev.concat(curr), []); return createMongoAbility(rules, { conditionsMatcher @@ -98,7 +98,7 @@ export const permissionServiceFactory = ({ }); } }) - .reduce((prev, curr) => prev.concat(curr), []); + .reduce((curr, prev) => prev.concat(curr), []); return rules; }; diff --git a/backend/src/ee/services/permission/permission-types.ts b/backend/src/ee/services/permission/permission-types.ts index 8df85054d..60fcbec85 100644 --- a/backend/src/ee/services/permission/permission-types.ts +++ b/backend/src/ee/services/permission/permission-types.ts @@ -11,8 +11,8 @@ export enum PermissionConditionOperators { } export const PermissionConditionSchema = { - [PermissionConditionOperators.$IN]: z.string().trim().min(1).array(), - [PermissionConditionOperators.$ALL]: z.string().trim().min(1).array(), + [PermissionConditionOperators.$IN]: z.string().min(1).array(), + [PermissionConditionOperators.$ALL]: z.string().min(1).array(), [PermissionConditionOperators.$REGEX]: z .string() .min(1) diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index a3998206d..b2b34e488 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -1,8 +1,9 @@ import { AbilityBuilder, createMongoAbility, ForcedSubject, MongoAbility } from "@casl/ability"; import { z } from "zod"; +import { TableName } from "@app/db/schemas"; import { conditionsMatcher } from "@app/lib/casl"; -import { UnpackedPermissionSchema } from "@app/server/routes/santizedSchemas/permission"; +import { BadRequestError } from "@app/lib/errors"; import { PermissionConditionOperators, PermissionConditionSchema } from "./permission-types"; @@ -22,14 +23,6 @@ export enum ProjectPermissionCmekActions { Decrypt = "decrypt" } -export enum ProjectPermissionDynamicSecretActions { - ReadRootCredential = "read-root-credential", - CreateRootCredential = "create-root-credential", - EditRootCredential = "edit-root-credential", - DeleteRootCredential = "delete-root-credential", - Lease = "lease" -} - export enum ProjectPermissionSub { Role = "role", Member = "member", @@ -45,8 +38,6 @@ export enum ProjectPermissionSub { Project = "workspace", Secrets = "secrets", SecretFolders = "secret-folders", - SecretImports = "secret-imports", - DynamicSecrets = "dynamic-secrets", SecretRollback = "secret-rollback", SecretApproval = "secret-approval", SecretRotation = "secret-rotation", @@ -63,8 +54,19 @@ export enum ProjectPermissionSub { export type SecretSubjectFields = { environment: string; secretPath: string; - secretName?: string; - secretTags?: string[]; + // secretName: string; + // secretTags: string[]; +}; + +export const CaslSecretsV2SubjectKnexMapper = (field: string) => { + switch (field) { + case "secretName": + return `${TableName.SecretV2}.key`; + case "secretTags": + return `${TableName.SecretTag}.slug`; + default: + break; + } }; export type SecretFolderSubjectFields = { @@ -72,16 +74,6 @@ export type SecretFolderSubjectFields = { secretPath: string; }; -export type DynamicSecretSubjectFields = { - environment: string; - secretPath: string; -}; - -export type SecretImportSubjectFields = { - environment: string; - secretPath: string; -}; - export type ProjectPermissionSet = | [ ProjectPermissionActions, @@ -94,20 +86,6 @@ export type ProjectPermissionSet = | (ForcedSubject & SecretFolderSubjectFields) ) ] - | [ - ProjectPermissionDynamicSecretActions, - ( - | ProjectPermissionSub.DynamicSecrets - | (ForcedSubject & DynamicSecretSubjectFields) - ) - ] - | [ - ProjectPermissionActions, - ( - | ProjectPermissionSub.SecretImports - | (ForcedSubject & SecretImportSubjectFields) - ) - ] | [ProjectPermissionActions, ProjectPermissionSub.Role] | [ProjectPermissionActions, ProjectPermissionSub.Tags] | [ProjectPermissionActions, ProjectPermissionSub.Member] @@ -142,9 +120,7 @@ const CASL_ACTION_SCHEMA_NATIVE_ENUM = (actions: ACTI const CASL_ACTION_SCHEMA_ENUM = (actions: ACTION) => z.union([z.enum(actions), z.enum(actions).array().min(1)]).transform((el) => (typeof el === "string" ? [el] : el)); -// akhilmhdh: don't modify this for v2 -// if you want to update create a new schema -const SecretConditionV1Schema = z +const SecretConditionSchema = z .object({ environment: z.union([ z.string(), @@ -170,50 +146,16 @@ const SecretConditionV1Schema = z }) .partial(); -const SecretConditionV2Schema = z - .object({ - environment: z.union([ - z.string(), - z - .object({ - [PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ], - [PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ], - [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN], - [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB] - }) - .partial() - ]), - secretPath: z.union([ - z.string(), - z - .object({ - [PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ], - [PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ], - [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN], - [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB] - }) - .partial() - ]), - secretName: z.union([ - z.string(), - z - .object({ - [PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ], - [PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ], - [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN], - [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB] - }) - .partial() - ]), - secretTags: z - .object({ - [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN] - }) - .partial() - }) - .partial(); - -const GeneralPermissionSchema = [ +export const ProjectPermissionSchema = z.discriminatedUnion("subject", [ + z.object({ + subject: z.literal(ProjectPermissionSub.Secrets).describe("The entity this permission pertains to."), + action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( + "Describe what action an entity can take." + ), + conditions: SecretConditionSchema.describe( + "When specified, only matching conditions will be allowed to access given resource." + ).optional() + }), z.object({ subject: z.literal(ProjectPermissionSub.SecretApproval).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( @@ -317,7 +259,7 @@ const GeneralPermissionSchema = [ ) }), z.object({ - subject: z.literal(ProjectPermissionSub.CertificateTemplates).describe("The entity this permission pertains to."), + subject: z.literal(ProjectPermissionSub.CertificateTemplates).describe("The entity this permission pertains to. "), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) @@ -346,78 +288,18 @@ const GeneralPermissionSchema = [ "Describe what action an entity can take." ) }), - z.object({ - subject: z.literal(ProjectPermissionSub.Cmek).describe("The entity this permission pertains to."), - inverted: z.boolean().optional().describe("Whether rule allows or forbids."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionCmekActions).describe( - "Describe what action an entity can take." - ) - }) -]; - -export const ProjectPermissionV1Schema = z.discriminatedUnion("subject", [ - z.object({ - subject: z.literal(ProjectPermissionSub.Secrets).describe("The entity this permission pertains to."), - inverted: z.boolean().optional().describe("Whether rule allows or forbids."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( - "Describe what action an entity can take." - ), - conditions: SecretConditionV1Schema.describe( - "When specified, only matching conditions will be allowed to access given resource." - ).optional() - }), z.object({ subject: z.literal(ProjectPermissionSub.SecretFolders).describe("The entity this permission pertains to."), - inverted: z.boolean().optional().describe("Whether rule allows or forbids."), action: CASL_ACTION_SCHEMA_ENUM([ProjectPermissionActions.Read]).describe( "Describe what action an entity can take." ) }), - ...GeneralPermissionSchema -]); - -export const ProjectPermissionV2Schema = z.discriminatedUnion("subject", [ z.object({ - subject: z.literal(ProjectPermissionSub.Secrets).describe("The entity this permission pertains to."), - inverted: z.boolean().optional().describe("Whether rule allows or forbids."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( + subject: z.literal(ProjectPermissionSub.Cmek).describe("The entity this permission pertains to."), + action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionCmekActions).describe( "Describe what action an entity can take." - ), - conditions: SecretConditionV2Schema.describe( - "When specified, only matching conditions will be allowed to access given resource." - ).optional() - }), - z.object({ - subject: z.literal(ProjectPermissionSub.SecretFolders).describe("The entity this permission pertains to."), - inverted: z.boolean().optional().describe("Whether rule allows or forbids."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( - "Describe what action an entity can take." - ), - conditions: SecretConditionV1Schema.describe( - "When specified, only matching conditions will be allowed to access given resource." - ).optional() - }), - z.object({ - subject: z.literal(ProjectPermissionSub.SecretImports).describe("The entity this permission pertains to."), - inverted: z.boolean().optional().describe("Whether rule allows or forbids."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( - "Describe what action an entity can take." - ), - conditions: SecretConditionV1Schema.describe( - "When specified, only matching conditions will be allowed to access given resource." - ).optional() - }), - z.object({ - subject: z.literal(ProjectPermissionSub.DynamicSecrets).describe("The entity this permission pertains to."), - inverted: z.boolean().optional().describe("Whether rule allows or forbids."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionDynamicSecretActions).describe( - "Describe what action an entity can take." - ), - conditions: SecretConditionV1Schema.describe( - "When specified, only matching conditions will be allowed to access given resource." - ).optional() - }), - ...GeneralPermissionSchema + ) + }) ]); const buildAdminPermissionRules = () => { @@ -426,8 +308,6 @@ const buildAdminPermissionRules = () => { // Admins get full access to everything [ ProjectPermissionSub.Secrets, - ProjectPermissionSub.SecretFolders, - ProjectPermissionSub.SecretImports, ProjectPermissionSub.SecretApproval, ProjectPermissionSub.SecretRotation, ProjectPermissionSub.Member, @@ -459,17 +339,6 @@ const buildAdminPermissionRules = () => { ); }); - can( - [ - ProjectPermissionDynamicSecretActions.ReadRootCredential, - ProjectPermissionDynamicSecretActions.EditRootCredential, - ProjectPermissionDynamicSecretActions.CreateRootCredential, - ProjectPermissionDynamicSecretActions.DeleteRootCredential, - ProjectPermissionDynamicSecretActions.Lease - ], - ProjectPermissionSub.DynamicSecrets - ); - can([ProjectPermissionActions.Edit, ProjectPermissionActions.Delete], ProjectPermissionSub.Project); can([ProjectPermissionActions.Read, ProjectPermissionActions.Create], ProjectPermissionSub.SecretRollback); can([ProjectPermissionActions.Edit], ProjectPermissionSub.Kms); @@ -501,34 +370,6 @@ const buildMemberPermissionRules = () => { ], ProjectPermissionSub.Secrets ); - can( - [ - ProjectPermissionActions.Read, - ProjectPermissionActions.Edit, - ProjectPermissionActions.Create, - ProjectPermissionActions.Delete - ], - ProjectPermissionSub.SecretFolders - ); - can( - [ - ProjectPermissionDynamicSecretActions.ReadRootCredential, - ProjectPermissionDynamicSecretActions.EditRootCredential, - ProjectPermissionDynamicSecretActions.CreateRootCredential, - ProjectPermissionDynamicSecretActions.DeleteRootCredential, - ProjectPermissionDynamicSecretActions.Lease - ], - ProjectPermissionSub.DynamicSecrets - ); - can( - [ - ProjectPermissionActions.Read, - ProjectPermissionActions.Edit, - ProjectPermissionActions.Create, - ProjectPermissionActions.Delete - ], - ProjectPermissionSub.SecretImports - ); can([ProjectPermissionActions.Read], ProjectPermissionSub.SecretApproval); can([ProjectPermissionActions.Read], ProjectPermissionSub.SecretRotation); @@ -652,9 +493,6 @@ const buildViewerPermissionRules = () => { const { can, rules } = new AbilityBuilder>(createMongoAbility); can(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets); - can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretFolders); - can(ProjectPermissionDynamicSecretActions.ReadRootCredential, ProjectPermissionSub.DynamicSecrets); - can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretImports); can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval); can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation); @@ -757,52 +595,17 @@ export const isAtLeastAsPrivilegedWorkspace = ( }; /* eslint-enable */ -export const backfillPermissionV1SchemaToV2Schema = (data: z.infer[]) => { - const formattedData = UnpackedPermissionSchema.array().parse(data); - const secretSubjects = formattedData.filter((el) => el.subject === ProjectPermissionSub.Secrets); - - // this means the folder permission as readonly is set - const hasReadOnlyFolder = formattedData.filter((el) => el.subject === ProjectPermissionSub.SecretFolders); - const secretImportPolicies = secretSubjects.map(({ subject, ...el }) => ({ - ...el, - subject: ProjectPermissionSub.SecretImports as const - })); - - const secretFolderPolicies = secretSubjects.map(({ subject, ...el }) => ({ - ...el, - subject: ProjectPermissionSub.SecretFolders - })); - - const dynamicSecretPolicies = secretSubjects.map(({ subject, ...el }) => { - const action = el.action.map((e) => { - switch (e) { - case ProjectPermissionActions.Edit: - return ProjectPermissionDynamicSecretActions.EditRootCredential; - case ProjectPermissionActions.Create: - return ProjectPermissionDynamicSecretActions.CreateRootCredential; - case ProjectPermissionActions.Delete: - return ProjectPermissionDynamicSecretActions.DeleteRootCredential; - case ProjectPermissionActions.Read: - return ProjectPermissionDynamicSecretActions.ReadRootCredential; - default: - return ProjectPermissionDynamicSecretActions.ReadRootCredential; - } - }); - - return { - ...el, - action: el.action.includes(ProjectPermissionActions.Edit) - ? [...action, ProjectPermissionDynamicSecretActions.Lease] - : action, - subject: ProjectPermissionSub.DynamicSecrets - }; - }); - - return formattedData.concat( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error this is valid ts - secretImportPolicies, - dynamicSecretPolicies, - hasReadOnlyFolder.length ? [] : secretFolderPolicies - ); +export const SecretV2SubjectFieldMapper = (arg: string) => { + switch (arg) { + case "environment": + return null; + case "secretPath": + return null; + case "secretName": + return `${TableName.SecretV2}.key`; + case "secretTags": + return `${TableName.SecretTag}.slug`; + default: + throw new BadRequestError({ message: `Invalid dynamic knex operator field: ${arg}` }); + } }; diff --git a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts index 789c6d49a..ea46e132c 100644 --- a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts +++ b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts @@ -1,13 +1,11 @@ -import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability"; -import { PackRule, unpackRules } from "@casl/ability/extra"; +import { ForbiddenError } from "@casl/ability"; import ms from "ms"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; -import { UnpackedPermissionSchema } from "@app/server/routes/santizedSchemas/permission"; import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal"; import { TPermissionServiceFactory } from "../permission/permission-service"; -import { ProjectPermissionActions, ProjectPermissionSet, ProjectPermissionSub } from "../permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission"; import { TProjectUserAdditionalPrivilegeDALFactory } from "./project-user-additional-privilege-dal"; import { ProjectUserAdditionalPrivilegeTemporaryMode, @@ -28,11 +26,6 @@ export type TProjectUserAdditionalPrivilegeServiceFactory = ReturnType< typeof projectUserAdditionalPrivilegeServiceFactory >; -const unpackPermissions = (permissions: unknown) => - UnpackedPermissionSchema.array().parse( - unpackRules((permissions || []) as PackRule>>[]) - ); - export const projectUserAdditionalPrivilegeServiceFactory = ({ projectUserAdditionalPrivilegeDAL, projectMembershipDAL, @@ -74,10 +67,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ slug, permissions: customPermission }); - return { - ...additionalPrivilege, - permissions: unpackPermissions(additionalPrivilege.permissions) - }; + return additionalPrivilege; } const relativeTempAllocatedTimeInMs = ms(dto.temporaryRange); @@ -92,10 +82,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ temporaryAccessStartTime: new Date(dto.temporaryAccessStartTime), temporaryAccessEndTime: new Date(new Date(dto.temporaryAccessStartTime).getTime() + relativeTempAllocatedTimeInMs) }); - return { - ...additionalPrivilege, - permissions: unpackPermissions(additionalPrivilege.permissions) - }; + return additionalPrivilege; }; const updateById = async ({ @@ -144,11 +131,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ temporaryAccessStartTime: new Date(temporaryAccessStartTime || ""), temporaryAccessEndTime: new Date(new Date(temporaryAccessStartTime || "").getTime() + ms(temporaryRange || "")) }); - - return { - ...additionalPrivilege, - permissions: unpackPermissions(additionalPrivilege.permissions) - }; + return additionalPrivilege; } const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.updateById(userPrivilege.id, { @@ -159,10 +142,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ temporaryRange: null, temporaryMode: null }); - return { - ...additionalPrivilege, - permissions: unpackPermissions(additionalPrivilege.permissions) - }; + return additionalPrivilege; }; const deleteById = async ({ actorId, actor, actorOrgId, actorAuthMethod, privilegeId }: TDeleteUserPrivilegeDTO) => { @@ -185,10 +165,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member); const deletedPrivilege = await projectUserAdditionalPrivilegeDAL.deleteById(userPrivilege.id); - return { - ...deletedPrivilege, - permissions: unpackPermissions(deletedPrivilege.permissions) - }; + return deletedPrivilege; }; const getPrivilegeDetailsById = async ({ @@ -216,10 +193,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member); - return { - ...userPrivilege, - permissions: unpackPermissions(userPrivilege.permissions) - }; + return userPrivilege; }; const listPrivileges = async ({ @@ -245,10 +219,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ userId: projectMembership.userId, projectId: projectMembership.projectId }); - return userPrivileges.map((el) => ({ - ...el, - permissions: unpackPermissions(el.permissions) - })); + return userPrivileges; }; return { diff --git a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-dal.ts b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-dal.ts index bb77660aa..e3526b0e3 100644 --- a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-dal.ts +++ b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-dal.ts @@ -14,7 +14,7 @@ export const secretApprovalPolicyDALFactory = (db: TDbClient) => { const secretApprovalPolicyFindQuery = ( tx: Knex, - filter: TFindFilter, + filter: TFindFilter, customFilter?: { sapId?: string; } diff --git a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts index 0abe15858..1908e75af 100644 --- a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts +++ b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts @@ -1,4 +1,4 @@ -import { ForbiddenError } from "@casl/ability"; +import { ForbiddenError, subject } from "@casl/ability"; import picomatch from "picomatch"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; @@ -344,8 +344,17 @@ export const secretApprovalPolicyServiceFactory = ({ environment, secretPath }: TGetBoardSapDTO) => { - await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId); - + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { secretPath, environment }) + ); return getSecretApprovalPolicy(projectId, environment, secretPath); }; diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts index e321039b2..bbc099956 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts @@ -43,7 +43,7 @@ import { fnSecretBulkDelete as fnSecretV2BridgeBulkDelete, fnSecretBulkInsert as fnSecretV2BridgeBulkInsert, fnSecretBulkUpdate as fnSecretV2BridgeBulkUpdate, - getAllSecretReferences as getAllSecretReferencesV2Bridge + getAllNestedSecretReferences as getAllNestedSecretReferencesV2Bridge } from "@app/services/secret-v2-bridge/secret-v2-bridge-fns"; import { TSecretVersionV2DALFactory } from "@app/services/secret-v2-bridge/secret-version-dal"; import { TSecretVersionV2TagDALFactory } from "@app/services/secret-v2-bridge/secret-version-tag-dal"; @@ -523,11 +523,11 @@ export const secretApprovalRequestServiceFactory = ({ skipMultilineEncoding: el.skipMultilineEncoding, key: el.key, references: el.encryptedValue - ? getAllSecretReferencesV2Bridge( + ? getAllNestedSecretReferencesV2Bridge( secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString() - ).nestedReferences + ) : [], type: SecretType.Shared })), @@ -547,11 +547,11 @@ export const secretApprovalRequestServiceFactory = ({ ? { encryptedValue: el.encryptedValue as Buffer, references: el.encryptedValue - ? getAllSecretReferencesV2Bridge( + ? getAllNestedSecretReferencesV2Bridge( secretManagerDecryptor({ cipherTextBlob: el.encryptedValue }).toString() - ).nestedReferences + ) : [] } : {}; @@ -1125,6 +1125,10 @@ export const secretApprovalRequestServiceFactory = ({ actorAuthMethod, actorOrgId ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) @@ -1288,23 +1292,6 @@ export const secretApprovalRequestServiceFactory = ({ const tagIds = unique(Object.values(commitTagIds).flat()); const tags = tagIds.length ? await secretTagDAL.findManyTagsById(projectId, tagIds) : []; if (tagIds.length !== tags.length) throw new NotFoundError({ message: "Tag not found" }); - const tagsGroupById = groupBy(tags, (i) => i.id); - - commits.forEach((commit) => { - let action = ProjectPermissionActions.Create; - if (commit.op === SecretOperations.Update) action = ProjectPermissionActions.Edit; - if (commit.op === SecretOperations.Delete) action = ProjectPermissionActions.Delete; - - ForbiddenError.from(permission).throwUnlessCan( - action, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: commit.key, - secretTags: commitTagIds?.[commit.key]?.map((secretTagId) => tagsGroupById[secretTagId][0].slug) - }) - ); - }); const secretApprovalRequest = await secretApprovalRequestDAL.transaction(async (tx) => { const doc = await secretApprovalRequestDAL.create( diff --git a/backend/src/ee/services/secret-replication/secret-replication-service.ts b/backend/src/ee/services/secret-replication/secret-replication-service.ts index 8f9237833..8f74079f7 100644 --- a/backend/src/ee/services/secret-replication/secret-replication-service.ts +++ b/backend/src/ee/services/secret-replication/secret-replication-service.ts @@ -28,7 +28,8 @@ import { TSecretV2BridgeDALFactory } from "@app/services/secret-v2-bridge/secret import { fnSecretBulkInsert as fnSecretV2BridgeBulkInsert, fnSecretBulkUpdate as fnSecretV2BridgeBulkUpdate, - getAllSecretReferences + getAllNestedSecretReferences, + getAllNestedSecretReferences as getAllNestedSecretReferencesV2Bridge } from "@app/services/secret-v2-bridge/secret-v2-bridge-fns"; import { TSecretVersionV2DALFactory } from "@app/services/secret-v2-bridge/secret-version-dal"; import { TSecretVersionV2TagDALFactory } from "@app/services/secret-v2-bridge/secret-version-tag-dal"; @@ -252,12 +253,11 @@ export const secretReplicationServiceFactory = ({ const sourceLocalSecrets = await secretV2BridgeDAL.find({ folderId: folder.id, type: SecretType.Shared }); const sourceSecretImports = await secretImportDAL.find({ folderId: folder.id }); const sourceImportedSecrets = await fnSecretsV2FromImports({ - secretImports: sourceSecretImports, + allowedImports: sourceSecretImports, secretDAL: secretV2BridgeDAL, folderDAL, secretImportDAL, - decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : ""), - hasSecretAccess: () => true + decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : "") }); // secrets that gets replicated across imports const sourceDecryptedLocalSecrets = sourceLocalSecrets.map((el) => ({ @@ -416,7 +416,7 @@ export const secretReplicationServiceFactory = ({ encryptedValue: doc.encryptedValue, encryptedComment: doc.encryptedComment, skipMultilineEncoding: doc.skipMultilineEncoding, - references: doc.secretValue ? getAllSecretReferences(doc.secretValue).nestedReferences : [] + references: doc.secretValue ? getAllNestedSecretReferencesV2Bridge(doc.secretValue) : [] }; }) }); @@ -442,7 +442,7 @@ export const secretReplicationServiceFactory = ({ encryptedValue: doc.encryptedValue as Buffer, encryptedComment: doc.encryptedComment, skipMultilineEncoding: doc.skipMultilineEncoding, - references: doc.secretValue ? getAllSecretReferences(doc.secretValue).nestedReferences : [] + references: doc.secretValue ? getAllNestedSecretReferencesV2Bridge(doc.secretValue) : [] } }; }) @@ -687,7 +687,7 @@ export const secretReplicationServiceFactory = ({ secretCommentTag: doc.secretCommentTag, secretCommentCiphertext: doc.secretCommentCiphertext, skipMultilineEncoding: doc.skipMultilineEncoding, - references: getAllSecretReferences(doc.secretValue).nestedReferences + references: getAllNestedSecretReferences(doc.secretValue) }; }) }); @@ -723,7 +723,7 @@ export const secretReplicationServiceFactory = ({ secretCommentTag: doc.secretCommentTag, secretCommentCiphertext: doc.secretCommentCiphertext, skipMultilineEncoding: doc.skipMultilineEncoding, - references: getAllSecretReferences(doc.secretValue).nestedReferences + references: getAllNestedSecretReferences(doc.secretValue) } }; }) diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts index 1dfe276a3..8408463ef 100644 --- a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts +++ b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import Ajv from "ajv"; -import { ProjectVersion, TableName } from "@app/db/schemas"; +import { ProjectVersion } from "@app/db/schemas"; import { decryptSymmetric128BitHexKeyUTF8, infisicalSymmetricEncypt } from "@app/lib/crypto/encryption"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { TProjectPermission } from "@app/lib/types"; @@ -99,14 +99,13 @@ export const secretRotationServiceFactory = ({ ProjectPermissionActions.Edit, subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); - const project = await projectDAL.findById(projectId); const shouldUseBridge = project.version === ProjectVersion.V3; if (shouldUseBridge) { const selectedSecrets = await secretV2BridgeDAL.find({ folderId: folder.id, - $in: { [`${TableName.SecretV2}.id` as "id"]: Object.values(outputs) } + $in: { id: Object.values(outputs) } }); if (selectedSecrets.length !== Object.values(outputs).length) throw new NotFoundError({ message: "Secrets not found" }); diff --git a/backend/src/lib/casl/knex.ts b/backend/src/lib/casl/knex.ts new file mode 100644 index 000000000..cc9718fe0 --- /dev/null +++ b/backend/src/lib/casl/knex.ts @@ -0,0 +1,111 @@ +import { AnyAbility, ExtractSubjectType } from "@casl/ability"; +import { AbilityQuery, rulesToQuery } from "@casl/ability/extra"; +import { Tables } from "knex/types/tables"; + +import { BadRequestError, UnauthorizedError } from "../errors"; +import { TKnexDynamicOperator } from "../knex/dynamic"; + +type TBuildKnexQueryFromCaslDTO = { + ability: K; + subject: ExtractSubjectType[1]>; + action: Parameters[0]; +}; + +export const buildKnexQueryFromCaslOperators = ({ + ability, + subject, + action +}: TBuildKnexQueryFromCaslDTO) => { + const query = rulesToQuery(ability, action, subject, (rule) => { + if (!rule.ast) throw new Error("Ast not defined"); + return rule.ast; + }); + + if (query === null) throw new UnauthorizedError({ message: `You don't have permission to do ${action} ${subject}` }); + return query; +}; + +type TFieldMapper = { + [K in T]: `${K}.${Exclude}`; +}[T]; + +type TFormatCaslFieldsWithTableNames = { + // handle if any missing operator else throw error let the app break because this is executing again the db + missingOperatorCallback?: (operator: string) => void; + fieldMapping: (arg: string) => TFieldMapper | null; + dynamicQuery: TKnexDynamicOperator; +}; + +export const formatCaslOperatorFieldsWithTableNames = ({ + missingOperatorCallback = (arg) => { + throw new BadRequestError({ message: `Unknown permission operator: ${arg}` }); + }, + dynamicQuery: dynamicQueryAst, + fieldMapping +}: TFormatCaslFieldsWithTableNames) => { + const stack: [TKnexDynamicOperator, TKnexDynamicOperator | null][] = [[dynamicQueryAst, null]]; + + while (stack.length) { + const [filterAst, parentAst] = stack.pop()!; + + if (filterAst.operator === "and" || filterAst.operator === "or" || filterAst.operator === "not") { + filterAst.value.forEach((el) => { + stack.push([el, filterAst]); + }); + + // eslint-disable-next-line no-continue + continue; + } + + if ( + filterAst.operator === "eq" || + filterAst.operator === "ne" || + filterAst.operator === "in" || + filterAst.operator === "endsWith" || + filterAst.operator === "startsWith" + ) { + const attrPath = fieldMapping(filterAst.field); + if (attrPath) { + filterAst.field = attrPath; + } else if (parentAst && Array.isArray(parentAst.value)) { + parentAst.value = parentAst.value.filter((childAst) => childAst !== filterAst) as string[]; + } else throw new Error("Unknown casl field"); + // eslint-disable-next-line no-continue + continue; + } + + if (parentAst && Array.isArray(parentAst.value)) { + parentAst.value = parentAst.value.filter((childAst) => childAst !== filterAst) as string[]; + } else { + missingOperatorCallback?.(filterAst.operator); + } + } + return dynamicQueryAst; +}; + +export const convertCaslOperatorToKnexOperator = ( + caslKnexOperators: AbilityQuery, + fieldMapping: (arg: string) => TFieldMapper | null +) => { + const value = []; + if (caslKnexOperators.$and) { + value.push({ + operator: "not" as const, + value: caslKnexOperators.$and as TKnexDynamicOperator[] + }); + } + if (caslKnexOperators.$or) { + value.push({ + operator: "or" as const, + value: caslKnexOperators.$or as TKnexDynamicOperator[] + }); + } + + return formatCaslOperatorFieldsWithTableNames({ + dynamicQuery: { + operator: "and", + value + }, + fieldMapping + }); +}; diff --git a/backend/src/lib/fn/array.ts b/backend/src/lib/fn/array.ts index 760317bad..e7db061f3 100644 --- a/backend/src/lib/fn/array.ts +++ b/backend/src/lib/fn/array.ts @@ -81,25 +81,3 @@ export const chunkArray = (array: T[], chunkSize: number): T[][] => { } return chunks; }; - -/* - * Returns all items from the first list that - * do not exist in the second list. - */ -export const diff = ( - root: readonly T[], - other: readonly T[], - identity: (item: T) => string | number | symbol = (t: T) => t as unknown as string | number | symbol -): T[] => { - if (!root?.length && !other?.length) return []; - if (root?.length === undefined) return [...other]; - if (!other?.length) return [...root]; - const bKeys = other.reduce( - (acc, item) => { - acc[identity(item)] = true; - return acc; - }, - {} as Record - ); - return root.filter((a) => !bKeys[identity(a)]); -}; diff --git a/backend/src/lib/knex/dynamic.ts b/backend/src/lib/knex/dynamic.ts index b8bc8ab57..c336d7a9e 100644 --- a/backend/src/lib/knex/dynamic.ts +++ b/backend/src/lib/knex/dynamic.ts @@ -2,31 +2,32 @@ import { Knex } from "knex"; import { UnauthorizedError } from "../errors"; -type TKnexDynamicPrimitiveOperator = { +type TKnexDynamicPrimitiveOperator = { operator: "eq" | "ne" | "startsWith" | "endsWith"; value: string; - field: Extract; + field: string; }; -type TKnexDynamicInOperator = { +type TKnexDynamicInOperator = { operator: "in"; value: string[] | number[]; - field: Extract; + field: string; }; -type TKnexNonGroupOperator = TKnexDynamicInOperator | TKnexDynamicPrimitiveOperator; +type TKnexNonGroupOperator = TKnexDynamicInOperator | TKnexDynamicPrimitiveOperator; -type TKnexGroupOperator = { +type TKnexGroupOperator = { operator: "and" | "or" | "not"; - value: (TKnexNonGroupOperator | TKnexGroupOperator)[]; + value: (TKnexNonGroupOperator | TKnexGroupOperator)[]; }; -export type TKnexDynamicOperator = TKnexGroupOperator | TKnexNonGroupOperator; +// akhilmhdh: This is still in pending state and not yet ready. If you want to use it ping me. +// used when you need to write a complex query with the orm +// use it when you need complex or and and condition - most of the time not needed +// majorly used with casl permission to filter data based on permission +export type TKnexDynamicOperator = TKnexGroupOperator | TKnexNonGroupOperator; -export const buildDynamicKnexQuery = ( - rootQueryBuild: Knex.QueryBuilder, - dynamicQuery: TKnexDynamicOperator -) => { +export const buildDynamicKnexQuery = (dynamicQuery: TKnexDynamicOperator, rootQueryBuild: Knex.QueryBuilder) => { const stack = [{ filterAst: dynamicQuery, queryBuilder: rootQueryBuild }]; while (stack.length) { @@ -49,25 +50,34 @@ export const buildDynamicKnexQuery = ( break; } case "and": { - filterAst.value.forEach((el) => { - void queryBuilder.andWhere((subQueryBuilder) => { - buildDynamicKnexQuery(subQueryBuilder, el); + void queryBuilder.andWhere((subQueryBuilder) => { + filterAst.value.forEach((el) => { + stack.push({ + queryBuilder: subQueryBuilder, + filterAst: el + }); }); }); break; } case "or": { - filterAst.value.forEach((el) => { - void queryBuilder.orWhere((subQueryBuilder) => { - buildDynamicKnexQuery(subQueryBuilder, el); + void queryBuilder.orWhere((subQueryBuilder) => { + filterAst.value.forEach((el) => { + stack.push({ + queryBuilder: subQueryBuilder, + filterAst: el + }); }); }); break; } case "not": { - filterAst.value.forEach((el) => { - void queryBuilder.whereNot((subQueryBuilder) => { - buildDynamicKnexQuery(subQueryBuilder, el); + void queryBuilder.whereNot((subQueryBuilder) => { + filterAst.value.forEach((el) => { + stack.push({ + queryBuilder: subQueryBuilder, + filterAst: el + }); }); }); break; diff --git a/backend/src/lib/knex/index.ts b/backend/src/lib/knex/index.ts index f55d8e6e6..36d81ae34 100644 --- a/backend/src/lib/knex/index.ts +++ b/backend/src/lib/knex/index.ts @@ -3,7 +3,6 @@ import { Knex } from "knex"; import { Tables } from "knex/types/tables"; import { DatabaseError } from "../errors"; -import { buildDynamicKnexQuery, TKnexDynamicOperator } from "./dynamic"; export * from "./connection"; export * from "./join"; @@ -21,10 +20,9 @@ export const withTransaction = (db: Knex, dal: K) => ({ export type TFindFilter = Partial & { $in?: Partial<{ [k in keyof R]: R[k][] }>; $search?: Partial<{ [k in keyof R]: R[k] }>; - $complex?: TKnexDynamicOperator; }; export const buildFindFilter = - ({ $in, $search, $complex, ...filter }: TFindFilter) => + ({ $in, $search, ...filter }: TFindFilter) => (bd: Knex.QueryBuilder) => { void bd.where(filter); if ($in) { @@ -41,9 +39,6 @@ export const buildFindFilter = } }); } - if ($complex) { - return buildDynamicKnexQuery(bd, $complex); - } return bd; }; diff --git a/backend/src/server/plugins/error-handler.ts b/backend/src/server/plugins/error-handler.ts index 4113c0f2d..76bfa9023 100644 --- a/backend/src/server/plugins/error-handler.ts +++ b/backend/src/server/plugins/error-handler.ts @@ -61,7 +61,7 @@ export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider void res.status(HttpStatusCodes.Forbidden).send({ statusCode: HttpStatusCodes.Forbidden, error: "PermissionDenied", - message: `You are not allowed to ${error.action} on ${error.subjectType} - ${JSON.stringify(error.subject)}` + message: `You are not allowed to ${error.action} on ${error.subjectType}` }); } else if (error instanceof ForbiddenRequestError) { void res.status(HttpStatusCodes.Forbidden).send({ diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 914408879..326b283f5 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -5,7 +5,6 @@ import { z } from "zod"; import { registerCertificateEstRouter } from "@app/ee/routes/est/certificate-est-router"; import { registerV1EERoutes } from "@app/ee/routes/v1"; -import { registerV2EERoutes } from "@app/ee/routes/v2"; import { accessApprovalPolicyApproverDALFactory } from "@app/ee/services/access-approval-policy/access-approval-policy-approver-dal"; import { accessApprovalPolicyDALFactory } from "@app/ee/services/access-approval-policy/access-approval-policy-dal"; import { accessApprovalPolicyServiceFactory } from "@app/ee/services/access-approval-policy/access-approval-policy-service"; @@ -1425,13 +1424,7 @@ export const registerRoutes = async ( }, { prefix: "/api/v1" } ); - await server.register( - async (v2Server) => { - await v2Server.register(registerV2EERoutes); - await v2Server.register(registerV2Routes); - }, - { prefix: "/api/v2" } - ); + await server.register(registerV2Routes, { prefix: "/api/v2" }); await server.register(registerV3Routes, { prefix: "/api/v3" }); server.addHook("onClose", async () => { diff --git a/backend/src/server/routes/sanitizedSchemas.ts b/backend/src/server/routes/sanitizedSchemas.ts index 2bf170fc0..aa53ed50e 100644 --- a/backend/src/server/routes/sanitizedSchemas.ts +++ b/backend/src/server/routes/sanitizedSchemas.ts @@ -9,10 +9,9 @@ import { SecretApprovalPoliciesSchema, UsersSchema } from "@app/db/schemas"; +import { UnpackedPermissionSchema } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; -import { UnpackedPermissionSchema } from "./santizedSchemas/permission"; - // sometimes the return data must be santizied to avoid leaking important values // always prefer pick over omit in zod export const integrationAuthPubSchema = IntegrationAuthsSchema.pick({ diff --git a/backend/src/server/routes/santizedSchemas/permission.ts b/backend/src/server/routes/santizedSchemas/permission.ts deleted file mode 100644 index 94c1dc57c..000000000 --- a/backend/src/server/routes/santizedSchemas/permission.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { z } from "zod"; - -export const UnpackedPermissionSchema = z.object({ - subject: z - .union([z.string().min(1), z.string().array()]) - .transform((el) => (typeof el !== "string" ? el[0] : el)) - .optional(), - action: z.union([z.string().min(1), z.string().array()]).transform((el) => (typeof el === "string" ? [el] : el)), - conditions: z.unknown().optional(), - inverted: z.boolean().optional() -}); diff --git a/backend/src/server/routes/v1/dashboard-router.ts b/backend/src/server/routes/v1/dashboard-router.ts index 36f0df591..f8e02365a 100644 --- a/backend/src/server/routes/v1/dashboard-router.ts +++ b/backend/src/server/routes/v1/dashboard-router.ts @@ -3,10 +3,7 @@ import { z } from "zod"; import { SecretFoldersSchema, SecretImportsSchema, SecretTagsSchema } from "@app/db/schemas"; import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types"; -import { - ProjectPermissionDynamicSecretActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { DASHBOARD } from "@app/lib/api-docs"; import { BadRequestError } from "@app/lib/errors"; import { removeTrailingSlash } from "@app/lib/fn"; @@ -195,15 +192,15 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { req.permission.orgId ); - const allowedDynamicSecretEnvironments = // filter envs user has access to + const permissiveEnvs = // filter envs user has access to environments.filter((environment) => permission.can( - ProjectPermissionDynamicSecretActions.Lease, - subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath }) + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ) ); - if (includeDynamicSecrets && allowedDynamicSecretEnvironments.length) { + if (includeDynamicSecrets && permissiveEnvs.length) { // this is the unique count, ie duplicate secrets across envs only count as 1 totalDynamicSecretCount = await server.services.dynamicSecret.getCountMultiEnv({ actor: req.permission.type, @@ -212,7 +209,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { actorOrgId: req.permission.orgId, projectId, search, - environmentSlugs: allowedDynamicSecretEnvironments, + environmentSlugs: permissiveEnvs, path: secretPath, isInternal: true }); @@ -227,7 +224,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { search, orderBy, orderDirection, - environmentSlugs: allowedDynamicSecretEnvironments, + environmentSlugs: permissiveEnvs, path: secretPath, limit: remainingLimit, offset: adjustedOffset, @@ -244,13 +241,13 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { } } - if (includeSecrets) { + if (includeSecrets && permissiveEnvs.length) { // this is the unique count, ie duplicate secrets across envs only count as 1 totalSecretCount = await server.services.secret.getSecretsCountMultiEnv({ actorId: req.permission.id, actor: req.permission.type, actorOrgId: req.permission.orgId, - environments, + environments: permissiveEnvs, actorAuthMethod: req.permission.authMethod, projectId, path: secretPath, @@ -263,7 +260,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { actorId: req.permission.id, actor: req.permission.type, actorOrgId: req.permission.orgId, - environments, + environments: permissiveEnvs, actorAuthMethod: req.permission.authMethod, projectId, path: secretPath, @@ -275,7 +272,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { isInternal: true }); - for await (const environment of environments) { + for await (const environment of permissiveEnvs) { const secretCountFromEnv = secrets.filter((secret) => secret.environment === environment).length; if (secretCountFromEnv) { diff --git a/backend/src/services/external-migration/external-migration-fns.ts b/backend/src/services/external-migration/external-migration-fns.ts index 934c1c8e1..6d996022a 100644 --- a/backend/src/services/external-migration/external-migration-fns.ts +++ b/backend/src/services/external-migration/external-migration-fns.ts @@ -19,7 +19,7 @@ import { TProjectEnvServiceFactory } from "../project-env/project-env-service"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretTagDALFactory } from "../secret-tag/secret-tag-dal"; import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal"; -import { fnSecretBulkInsert, getAllSecretReferences } from "../secret-v2-bridge/secret-v2-bridge-fns"; +import { fnSecretBulkInsert, getAllNestedSecretReferences } from "../secret-v2-bridge/secret-v2-bridge-fns"; import type { TSecretV2BridgeServiceFactory } from "../secret-v2-bridge/secret-v2-bridge-service"; import { TSecretVersionV2DALFactory } from "../secret-v2-bridge/secret-version-dal"; import { TSecretVersionV2TagDALFactory } from "../secret-v2-bridge/secret-version-tag-dal"; @@ -242,7 +242,7 @@ export const importDataIntoInfisicalFn = async ({ } await fnSecretBulkInsert({ inputSecrets: secretBatch.map((el) => { - const references = getAllSecretReferences(el.secretValue).nestedReferences; + const references = getAllNestedSecretReferences(el.secretValue); return { version: 1, diff --git a/backend/src/services/integration-auth/integration-delete-secret.ts b/backend/src/services/integration-auth/integration-delete-secret.ts index 7002e1229..7cf77cb26 100644 --- a/backend/src/services/integration-auth/integration-delete-secret.ts +++ b/backend/src/services/integration-auth/integration-delete-secret.ts @@ -67,8 +67,7 @@ const getIntegrationSecretsV2 = async ( folderDAL, secretDAL: secretV2BridgeDAL, secretImportDAL, - secretImports, - hasSecretAccess: () => true + allowedImports: secretImports }); for (let i = importedSecrets.length - 1; i >= 0; i -= 1) { diff --git a/backend/src/services/integration/integration-service.ts b/backend/src/services/integration/integration-service.ts index d511f9689..47a92c384 100644 --- a/backend/src/services/integration/integration-service.ts +++ b/backend/src/services/integration/integration-service.ts @@ -89,10 +89,7 @@ export const integrationServiceFactory = ({ ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: sourceEnvironment, - secretPath - }) + subject(ProjectPermissionSub.Secrets, { environment: sourceEnvironment, secretPath }) ); const folder = await folderDAL.findBySecretPath(integrationAuth.projectId, sourceEnvironment, secretPath); @@ -165,10 +162,7 @@ export const integrationServiceFactory = ({ if (environment || secretPath) { ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: newEnvironment, - secretPath: newSecretPath - }) + subject(ProjectPermissionSub.Secrets, { environment: newEnvironment, secretPath: newSecretPath }) ); } diff --git a/backend/src/services/project-role/project-role-service.ts b/backend/src/services/project-role/project-role-service.ts index e9c8cb1da..49c4f81c9 100644 --- a/backend/src/services/project-role/project-role-service.ts +++ b/backend/src/services/project-role/project-role-service.ts @@ -2,6 +2,7 @@ import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability"; import { PackRule, packRules, unpackRules } from "@casl/ability/extra"; import { ProjectMembershipRole } from "@app/db/schemas"; +import { UnpackedPermissionSchema } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionActions, @@ -9,7 +10,6 @@ import { ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; -import { UnpackedPermissionSchema } from "@app/server/routes/santizedSchemas/permission"; import { ActorAuthMethod } from "../auth/auth-type"; import { TIdentityProjectMembershipRoleDALFactory } from "../identity-project/identity-project-membership-role-dal"; diff --git a/backend/src/services/secret-folder/secret-folder-fns.ts b/backend/src/services/secret-folder/secret-folder-fns.ts new file mode 100644 index 000000000..c8f7d885e --- /dev/null +++ b/backend/src/services/secret-folder/secret-folder-fns.ts @@ -0,0 +1,6 @@ +import { RawRule } from "@casl/ability"; + +import { ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; + +export const shouldCheckFolderPermission = (rules: RawRule[]) => + rules.some((rule) => (rule.subject as ProjectPermissionSub[]).includes(ProjectPermissionSub.SecretFolders)); diff --git a/backend/src/services/secret-folder/secret-folder-service.ts b/backend/src/services/secret-folder/secret-folder-service.ts index 6815aaa11..b16d90b6b 100644 --- a/backend/src/services/secret-folder/secret-folder-service.ts +++ b/backend/src/services/secret-folder/secret-folder-service.ts @@ -12,6 +12,7 @@ import { OrderByDirection } from "@app/lib/types"; import { TProjectDALFactory } from "../project/project-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TSecretFolderDALFactory } from "./secret-folder-dal"; +import { shouldCheckFolderPermission } from "./secret-folder-fns"; import { TCreateFolderDTO, TDeleteFolderDTO, @@ -59,10 +60,20 @@ export const secretFolderServiceFactory = ({ actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) - ); + // we do this because we've split Secret and SecretFolder resources + // previously, if one can create/update/read/delete secrets then they can do the same for folders + // for backwards compatibility, we handle authorization only when SecretFolders subject is used + if (shouldCheckFolderPermission(permission.rules)) { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Create, + subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) + ); + } else { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Create, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); + } const env = await projectEnvDAL.findOne({ projectId, slug: environment }); if (!env) throw new NotFoundError({ message: "Environment not found", name: "Create folder" }); @@ -150,10 +161,20 @@ export const secretFolderServiceFactory = ({ ); folders.forEach(({ environment, path: secretPath }) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) - ); + // we do this because we've split Secret and SecretFolder resources + // previously, if one can create/update/read/delete secrets then they can do the same for folders + // for backwards compatibility, we handle authorization only when SecretFolders subject is used + if (shouldCheckFolderPermission(permission.rules)) { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) + ); + } else { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); + } }); const result = await folderDAL.transaction(async (tx) => @@ -246,10 +267,20 @@ export const secretFolderServiceFactory = ({ actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) - ); + // we do this because we've split Secret and SecretFolder resources + // previously, if one can create/update/read/delete secrets then they can do the same for folders + // for backwards compatibility, we handle authorization differently only when SecretFolders subject is used + if (shouldCheckFolderPermission(permission.rules)) { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) + ); + } else { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); + } const parentFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!parentFolder) throw new NotFoundError({ message: "Secret path not found" }); @@ -320,10 +351,20 @@ export const secretFolderServiceFactory = ({ actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) - ); + // we do this because we've split Secret and SecretFolder resources + // previously, if one can create/update/read/delete secrets then they can do the same for folders + // for backwards compatibility, we handle authorization differently only when SecretFolders subject is used + if (shouldCheckFolderPermission(permission.rules)) { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Delete, + subject(ProjectPermissionSub.SecretFolders, { environment, secretPath }) + ); + } else { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Delete, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); + } const env = await projectEnvDAL.findOne({ projectId, slug: environment }); if (!env) throw new NotFoundError({ message: "Environment not found", name: "Create folder" }); diff --git a/backend/src/services/secret-import/secret-import-fns.ts b/backend/src/services/secret-import/secret-import-fns.ts index d75a25514..b21a6c3ce 100644 --- a/backend/src/services/secret-import/secret-import-fns.ts +++ b/backend/src/services/secret-import/secret-import-fns.ts @@ -27,7 +27,6 @@ type TSecretImportSecretsV2 = { slug: string; name: string; }; - id: string; folderId: string | undefined; importFolderId: string; secrets: (TSecretsV2 & { @@ -140,22 +139,24 @@ export const fnSecretsFromImports = async ({ return secrets; }; -/* eslint-disable no-await-in-loop, no-continue */ export const fnSecretsV2FromImports = async ({ - secretImports: rootSecretImports, + allowedImports: possibleCyclicImports, folderDAL, secretDAL, secretImportDAL, + depth = 0, + cyclicDetector = new Set(), decryptor, - expandSecretReferences, - hasSecretAccess + expandSecretReferences }: { - secretImports: (Omit & { + allowedImports: (Omit & { importEnv: { id: string; slug: string; name: string }; })[]; folderDAL: Pick; secretDAL: Pick; secretImportDAL: Pick; + depth?: number; + cyclicDetector?: Set; decryptor: (value?: Buffer | null) => string; expandSecretReferences?: (inputSecret: { value?: string; @@ -163,107 +164,92 @@ export const fnSecretsV2FromImports = async ({ secretPath: string; environment: string; }) => Promise; - hasSecretAccess: (environment: string, secretPath: string, secretName: string, secretTagSlugs: string[]) => boolean; }) => { - const cyclicDetector = new Set(); - const stack: { secretImports: typeof rootSecretImports; depth: number; parentImportedSecrets: TSecretsV2[] }[] = [ - { secretImports: rootSecretImports, depth: 0, parentImportedSecrets: [] } - ]; + // avoid going more than a depth + if (depth >= LEVEL_BREAK) return []; - const processedImports: TSecretImportSecretsV2[] = []; + const allowedImports = possibleCyclicImports.filter( + ({ importPath, importEnv }) => !cyclicDetector.has(getImportUniqKey(importEnv.slug, importPath)) + ); - while (stack.length) { - const { secretImports, depth, parentImportedSecrets } = stack.pop()!; - - if (depth > LEVEL_BREAK) continue; - const sanitizedImports = secretImports.filter( - ({ importPath, importEnv }) => !cyclicDetector.has(getImportUniqKey(importEnv.slug, importPath)) - ); - - if (!sanitizedImports.length) continue; - - const importedFolders = await folderDAL.findByManySecretPath( - sanitizedImports.map(({ importEnv, importPath }) => ({ + const importedFolders = ( + await folderDAL.findByManySecretPath( + allowedImports.map(({ importEnv, importPath }) => ({ envId: importEnv.id, secretPath: importPath })) - ); - if (!importedFolders.length) continue; + ) + ).filter(Boolean); // remove undefined ones + if (!importedFolders.length) { + return []; + } - const importedFolderIds = importedFolders.map((el) => el?.id) as string[]; - const importedFolderGroupBySourceImport = groupBy(importedFolders, (i) => `${i?.envId}-${i?.path}`); + const importedFolderIds = importedFolders.map((el) => el?.id) as string[]; + const importedFolderGroupBySourceImport = groupBy(importedFolders, (i) => `${i?.envId}-${i?.path}`); + const importedSecrets = await secretDAL.find( + { + $in: { folderId: importedFolderIds }, + type: SecretType.Shared + }, + { + sort: [["id", "asc"]] + } + ); - const importedSecrets = await secretDAL.find( - { - $in: { folderId: importedFolderIds }, - type: SecretType.Shared - }, - { - sort: [["id", "asc"]] - } - ); - const importedSecretsGroupByFolderId = groupBy(importedSecrets, (i) => i.folderId); + const importedSecretsGroupByFolderId = groupBy(importedSecrets, (i) => i.folderId); - sanitizedImports.forEach(({ importPath, importEnv }) => { - cyclicDetector.add(getImportUniqKey(importEnv.slug, importPath)); - }); - // now we need to check recursively deeper imports made inside other imports - // we go level wise meaning we take all imports of a tree level and then go deeper ones level by level - const deeperImports = await secretImportDAL.findByFolderIds(importedFolderIds); - const deeperImportsGroupByFolderId = groupBy(deeperImports, (i) => i.folderId); - - const isFirstIteration = !processedImports.length; - sanitizedImports.forEach(({ importPath, importEnv, id, folderId }, i) => { - const sourceImportFolder = importedFolderGroupBySourceImport[`${importEnv.id}-${importPath}`]?.[0]; - const secretsWithDuplicate = (importedSecretsGroupByFolderId?.[importedFolders?.[i]?.id as string] || []) - .filter((item) => - hasSecretAccess( - importEnv.slug, - importPath, - item.key, - item.tags.map((el) => el.slug) - ) - ) - .map((item) => ({ - ...item, - secretKey: item.key, - secretValue: decryptor(item.encryptedValue), - secretComment: decryptor(item.encryptedComment), - environment: importEnv.slug, - workspace: "", // This field should not be used, it's only here to keep the older Python SDK versions backwards compatible with the new Postgres backend. - _id: item.id // The old Python SDK depends on the _id field being returned. We return this to keep the older Python SDK versions backwards compatible with the new Postgres backend. - })); - - if (deeperImportsGroupByFolderId?.[sourceImportFolder?.id || ""]) { - stack.push({ - secretImports: deeperImportsGroupByFolderId[sourceImportFolder?.id || ""], - depth: depth + 1, - parentImportedSecrets: secretsWithDuplicate - }); - } - - if (isFirstIteration) { - processedImports.push({ - secretPath: importPath, - environment: importEnv.slug, - environmentInfo: importEnv, - folderId: importedFolders?.[i]?.id, - id, - importFolderId: folderId, - secrets: secretsWithDuplicate - }); - } else { - parentImportedSecrets.push(...secretsWithDuplicate); - } + allowedImports.forEach(({ importPath, importEnv }) => { + cyclicDetector.add(getImportUniqKey(importEnv.slug, importPath)); + }); + // now we need to check recursively deeper imports made inside other imports + // we go level wise meaning we take all imports of a tree level and then go deeper ones level by level + const deeperImports = await secretImportDAL.findByFolderIds(importedFolderIds); + let secretsFromDeeperImports: TSecretImportSecretsV2[] = []; + if (deeperImports.length) { + secretsFromDeeperImports = await fnSecretsV2FromImports({ + allowedImports: deeperImports.filter(({ isReplication }) => !isReplication), + secretImportDAL, + folderDAL, + secretDAL, + depth: depth + 1, + cyclicDetector, + decryptor, + expandSecretReferences }); } - /* eslint-enable */ + const secretsFromdeeperImportGroupedByFolderId = groupBy(secretsFromDeeperImports, (i) => i.importFolderId); + + const processedImports = allowedImports.map(({ importPath, importEnv, id, folderId }, i) => { + const sourceImportFolder = importedFolderGroupBySourceImport[`${importEnv.id}-${importPath}`]?.[0]; + const folderDeeperImportSecrets = + secretsFromdeeperImportGroupedByFolderId?.[sourceImportFolder?.id || ""]?.[0]?.secrets || []; + const secretsWithDuplicate = (importedSecretsGroupByFolderId?.[importedFolders?.[i]?.id as string] || []) + .map((item) => ({ + ...item, + secretKey: item.key, + secretValue: decryptor(item.encryptedValue), + secretComment: decryptor(item.encryptedComment), + environment: importEnv.slug, + workspace: "", // This field should not be used, it's only here to keep the older Python SDK versions backwards compatible with the new Postgres backend. + _id: item.id // The old Python SDK depends on the _id field being returned. We return this to keep the older Python SDK versions backwards compatible with the new Postgres backend. + })) + .concat(folderDeeperImportSecrets); + + return { + secretPath: importPath, + environment: importEnv.slug, + environmentInfo: importEnv, + folderId: importedFolders?.[i]?.id, + id, + importFolderId: folderId, + secrets: unique(secretsWithDuplicate, (el) => el.secretKey) + }; + }); + if (expandSecretReferences) { await Promise.allSettled( - processedImports.map((processedImport) => { - // eslint-disable-next-line - processedImport.secrets = unique(processedImport.secrets, (i) => i.key); - return Promise.allSettled( + processedImports.map((processedImport) => + Promise.allSettled( processedImport.secrets.map(async (decryptedSecret, index) => { const expandedSecretValue = await expandSecretReferences({ value: decryptedSecret.secretValue, @@ -274,8 +260,8 @@ export const fnSecretsV2FromImports = async ({ // eslint-disable-next-line no-param-reassign processedImport.secrets[index].secretValue = expandedSecretValue || ""; }) - ); - }) + ) + ) ); } diff --git a/backend/src/services/secret-import/secret-import-service.ts b/backend/src/services/secret-import/secret-import-service.ts index e1d0291f6..5551b0180 100644 --- a/backend/src/services/secret-import/secret-import-service.ts +++ b/backend/src/services/secret-import/secret-import-service.ts @@ -84,12 +84,12 @@ export const secretImportServiceFactory = ({ // check if user has permission to import into destination path ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, - subject(ProjectPermissionSub.SecretImports, { environment, secretPath }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); // check if user has permission to import from target path ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, + ProjectPermissionActions.Create, subject(ProjectPermissionSub.Secrets, { environment: data.environment, secretPath: data.path @@ -191,7 +191,7 @@ export const secretImportServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.SecretImports, { environment, secretPath }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); @@ -277,7 +277,7 @@ export const secretImportServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, - subject(ProjectPermissionSub.SecretImports, { environment, secretPath }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); @@ -342,8 +342,8 @@ export const secretImportServiceFactory = ({ // check if user has permission to import into destination path ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.SecretImports, { environment, secretPath }) + ProjectPermissionActions.Create, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); const plan = await licenseService.getPlan(actorOrgId); @@ -366,7 +366,7 @@ export const secretImportServiceFactory = ({ // check if user has permission to import from target path ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, + ProjectPermissionActions.Create, subject(ProjectPermissionSub.Secrets, { environment: secretImportDoc.importEnv.slug, secretPath: secretImportDoc.importPath @@ -414,7 +414,7 @@ export const secretImportServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.SecretImports, { environment, secretPath }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); @@ -446,7 +446,7 @@ export const secretImportServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.SecretImports, { environment, secretPath }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); @@ -489,7 +489,7 @@ export const secretImportServiceFactory = ({ ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.SecretImports, { + subject(ProjectPermissionSub.Secrets, { environment: folder.environment.envSlug, secretPath: folderWithPath.path }) @@ -532,19 +532,20 @@ export const secretImportServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.SecretImports, { environment, secretPath }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) return []; // this will already order by position // so anything based on this order will also be in right position const secretImports = await secretImportDAL.find({ folderId: folder.id, isReplication: false }); - const allowedImports = secretImports.filter((el) => + + const allowedImports = secretImports.filter(({ importEnv, importPath }) => permission.can( ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { - environment: el.importEnv.slug, - secretPath: el.importPath + environment: importEnv.slug, + secretPath: importPath }) ) ); @@ -569,7 +570,7 @@ export const secretImportServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.SecretImports, { environment, secretPath }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) return []; @@ -577,6 +578,16 @@ export const secretImportServiceFactory = ({ // so anything based on this order will also be in right position const secretImports = await secretImportDAL.find({ folderId: folder.id, isReplication: false }); + const allowedImports = secretImports.filter(({ importEnv, importPath }) => + permission.can( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { + environment: importEnv.slug, + secretPath: importPath + }) + ) + ); + const { botKey, shouldUseSecretV2Bridge } = await projectBotService.getBotKey(projectId); if (shouldUseSecretV2Bridge) { const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({ @@ -584,21 +595,11 @@ export const secretImportServiceFactory = ({ projectId }); const importedSecrets = await fnSecretsV2FromImports({ - secretImports, + allowedImports, folderDAL, secretDAL: secretV2BridgeDAL, secretImportDAL, - decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : ""), - hasSecretAccess: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => - permission.can( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: expandEnvironment, - secretPath: expandSecretPath, - secretName: expandSecretKey, - secretTags: expandSecretTags - }) - ) + decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : "") }); return importedSecrets; } @@ -609,21 +610,7 @@ export const secretImportServiceFactory = ({ name: "bot_not_found_error" }); - const allowedImports = secretImports.filter((el) => - permission.can( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: el.importEnv.slug, - secretPath: el.importPath - }) - ) - ); - const importedSecrets = await fnSecretsFromImports({ - allowedImports, - folderDAL, - secretDAL, - secretImportDAL - }); + const importedSecrets = await fnSecretsFromImports({ allowedImports, folderDAL, secretDAL, secretImportDAL }); return importedSecrets.map((el) => ({ ...el, secrets: el.secrets.map((encryptedSecret) => diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-dal.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-dal.ts index adbd935ee..1a9397e91 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-dal.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-dal.ts @@ -4,14 +4,7 @@ import { validate as uuidValidate } from "uuid"; import { TDbClient } from "@app/db"; import { SecretsV2Schema, SecretType, TableName, TSecretsV2, TSecretsV2Update } from "@app/db/schemas"; import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors"; -import { - buildFindFilter, - ormify, - selectAllTableCols, - sqlNestRelationships, - TFindFilter, - TFindOpt -} from "@app/lib/knex"; +import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex"; import { OrderByDirection } from "@app/lib/types"; import { SecretsOrderBy } from "@app/services/secret/secret-types"; @@ -20,97 +13,6 @@ export type TSecretV2BridgeDALFactory = ReturnType { const secretOrm = ormify(db, TableName.SecretV2); - const findOne = async (filter: Partial, tx?: Knex) => { - try { - const docs = await (tx || db)(TableName.SecretV2) - .where(filter) - .leftJoin( - TableName.SecretV2JnTag, - `${TableName.SecretV2}.id`, - `${TableName.SecretV2JnTag}.${TableName.SecretV2}Id` - ) - .leftJoin( - TableName.SecretTag, - `${TableName.SecretV2JnTag}.${TableName.SecretTag}Id`, - `${TableName.SecretTag}.id` - ) - .select(selectAllTableCols(TableName.SecretV2)) - .select(db.ref("id").withSchema(TableName.SecretTag).as("tagId")) - .select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor")) - .select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug")); - - const data = sqlNestRelationships({ - data: docs, - key: "id", - parentMapper: (el) => ({ _id: el.id, ...SecretsV2Schema.parse(el) }), - childrenMapper: [ - { - key: "tagId", - label: "tags" as const, - mapper: ({ tagId: id, tagColor: color, tagSlug: slug }) => ({ - id, - color, - slug, - name: slug - }) - } - ] - }); - return data?.[0]; - } catch (error) { - throw new DatabaseError({ error, name: `${TableName.SecretV2}: FindOne` }); - } - }; - - const find = async (filter: TFindFilter, { offset, limit, sort, tx }: TFindOpt = {}) => { - try { - const query = (tx || db)(TableName.SecretV2) - // eslint-disable-next-line @typescript-eslint/no-misused-promises - .where(buildFindFilter(filter)) - .leftJoin( - TableName.SecretV2JnTag, - `${TableName.SecretV2}.id`, - `${TableName.SecretV2JnTag}.${TableName.SecretV2}Id` - ) - .leftJoin( - TableName.SecretTag, - `${TableName.SecretV2JnTag}.${TableName.SecretTag}Id`, - `${TableName.SecretTag}.id` - ) - .select(selectAllTableCols(TableName.SecretV2)) - .select(db.ref("id").withSchema(TableName.SecretTag).as("tagId")) - .select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor")) - .select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug")); - if (limit) void query.limit(limit); - if (offset) void query.offset(offset); - if (sort) { - void query.orderBy(sort.map(([column, order, nulls]) => ({ column: column as string, order, nulls }))); - } - - const docs = await query; - const data = sqlNestRelationships({ - data: docs, - key: "id", - parentMapper: (el) => ({ _id: el.id, ...SecretsV2Schema.parse(el) }), - childrenMapper: [ - { - key: "tagId", - label: "tags" as const, - mapper: ({ tagId: id, tagColor: color, tagSlug: slug }) => ({ - id, - color, - slug, - name: slug - }) - } - ] - }); - return data; - } catch (error) { - throw new DatabaseError({ error, name: `${TableName.SecretV2}: Find` }); - } - }; - const update = async (filter: Partial, data: Omit, tx?: Knex) => { try { const sec = await (tx || db)(TableName.SecretV2) @@ -582,8 +484,6 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => { upsertSecretReferences, findReferencedSecretReferences, findAllProjectSecretValues, - countByFolderIds, - findOne, - find + countByFolderIds }; }; diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts index 13ae7ebba..1ae7ce6dc 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts @@ -30,10 +30,9 @@ export const shouldUseSecretV2Bridge = (version: number) => version === 3; * // { environment: 'prod', secretPath: '/anotherFolder' } * // ] */ -export const getAllSecretReferences = (maybeSecretReference: string) => { +export const getAllNestedSecretReferences = (maybeSecretReference: string) => { const references = Array.from(maybeSecretReference.matchAll(INTERPOLATION_SYNTAX_REG), (m) => m[1]); - - const nestedReferences = references + return references .filter((el) => el.includes(".")) .map((el) => { const [environment, ...secretPathList] = el.split("."); @@ -43,8 +42,6 @@ export const getAllSecretReferences = (maybeSecretReference: string) => { secretKey: secretPathList[secretPathList.length - 1] }; }); - const localReferences = references.filter((el) => !el.includes(".")); - return { nestedReferences, localReferences }; }; // these functions are special functions shared by a couple of resources @@ -328,13 +325,16 @@ type TRecursivelyFetchSecretsFromFoldersArg = { projectId: string; environment: string; currentPath: string; + hasAccess: (environment: string, secretPath: string) => boolean; }; export const recursivelyGetSecretPaths = async ({ folderDAL, projectEnvDAL, projectId, - environment + environment, + currentPath, + hasAccess }: TRecursivelyFetchSecretsFromFoldersArg) => { const env = await projectEnvDAL.findOne({ projectId, @@ -360,7 +360,12 @@ export const recursivelyGetSecretPaths = async ({ folderId: p.folderId })); - return paths; + // Filter out paths that the user does not have permission to access, and paths that are not in the current path + const allowedPaths = paths.filter( + (folder) => hasAccess(environment, folder.path) && folder.path.startsWith(currentPath === "/" ? "" : currentPath) + ); + + return allowedPaths; }; // used to convert multi line ones to quotes ones with \n const formatMultiValueEnv = (val?: string) => { @@ -374,7 +379,7 @@ type TInterpolateSecretArg = { decryptSecretValue: (encryptedValue?: Buffer | null) => string | undefined; secretDAL: Pick; folderDAL: Pick; - canExpandValue: (environment: string, secretPath: string, secretName: string, secretTagSlugs: string[]) => boolean; + canExpandValue: (environment: string, secretPath: string) => boolean; }; const MAX_SECRET_REFERENCE_DEPTH = 10; @@ -385,29 +390,29 @@ export const expandSecretReferencesFactory = ({ folderDAL, canExpandValue }: TInterpolateSecretArg) => { - const secretCache: Record> = {}; + const secretCache: Record> = {}; const getCacheUniqueKey = (environment: string, secretPath: string) => `${environment}-${secretPath}`; const fetchSecret = async (environment: string, secretPath: string, secretKey: string) => { const cacheKey = getCacheUniqueKey(environment, secretPath); if (secretCache?.[cacheKey]) { - return secretCache[cacheKey][secretKey] || { value: "", tags: [] }; + return secretCache[cacheKey][secretKey] || ""; } const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); - if (!folder) return { value: "", tags: [] }; + if (!folder) return ""; const secrets = await secretDAL.findByFolderId(folder.id); - const decryptedSecret = secrets.reduce>((prev, secret) => { + const decryptedSecret = secrets.reduce>((prev, secret) => { // eslint-disable-next-line no-param-reassign - prev[secret.key] = { value: decryptSecret(secret.encryptedValue) || "", tags: secret.tags?.map((el) => el.slug) }; + prev[secret.key] = decryptSecret(secret.encryptedValue) || ""; return prev; }, {}); secretCache[cacheKey] = decryptedSecret; - return secretCache[cacheKey][secretKey] || { value: "", tags: [] }; + return secretCache[cacheKey][secretKey] || ""; }; const recursivelyExpandSecret = async (dto: { value?: string; secretPath: string; environment: string }) => { @@ -433,43 +438,43 @@ export const expandSecretReferencesFactory = ({ if (entities.length === 1) { const [secretKey] = entities; - // eslint-disable-next-line no-continue,no-await-in-loop - const referredValue = await fetchSecret(environment, secretPath, secretKey); - if (!canExpandValue(environment, secretPath, secretKey, referredValue.tags)) + if (!canExpandValue(environment, secretPath)) throw new ForbiddenRequestError({ message: `You are attempting to reference secret named ${secretKey} from environment ${environment} in path ${secretPath} which you do not have access to.` }); + // eslint-disable-next-line no-continue,no-await-in-loop + const referedValue = await fetchSecret(environment, secretPath, secretKey); const cacheKey = getCacheUniqueKey(environment, secretPath); - secretCache[cacheKey][secretKey] = referredValue; - if (INTERPOLATION_SYNTAX_REG.test(referredValue.value)) { + secretCache[cacheKey][secretKey] = referedValue; + if (INTERPOLATION_SYNTAX_REG.test(referedValue)) { stack.push({ - value: referredValue.value, + value: referedValue, secretPath, environment, depth: depth + 1 }); } - if (referredValue) { - expandedValue = expandedValue.replaceAll(interpolationSyntax, referredValue.value); + if (referedValue) { + expandedValue = expandedValue.replaceAll(interpolationSyntax, referedValue); } } else { const secretReferenceEnvironment = entities[0]; const secretReferencePath = path.join("/", ...entities.slice(1, entities.length - 1)); const secretReferenceKey = entities[entities.length - 1]; - // eslint-disable-next-line no-await-in-loop - const referedValue = await fetchSecret(secretReferenceEnvironment, secretReferencePath, secretReferenceKey); - if (!canExpandValue(secretReferenceEnvironment, secretReferencePath, secretReferenceKey, referedValue.tags)) + if (!canExpandValue(secretReferenceEnvironment, secretReferencePath)) throw new ForbiddenRequestError({ message: `You are attempting to reference secret named ${secretReferenceKey} from environment ${secretReferenceEnvironment} in path ${secretReferencePath} which you do not have access to.` }); + // eslint-disable-next-line no-await-in-loop + const referedValue = await fetchSecret(secretReferenceEnvironment, secretReferencePath, secretReferenceKey); const cacheKey = getCacheUniqueKey(secretReferenceEnvironment, secretReferencePath); secretCache[cacheKey][secretReferenceKey] = referedValue; - if (INTERPOLATION_SYNTAX_REG.test(referedValue.value)) { + if (INTERPOLATION_SYNTAX_REG.test(referedValue)) { stack.push({ - value: referedValue.value, + value: referedValue, secretPath: secretReferencePath, environment: secretReferenceEnvironment, depth: depth + 1 @@ -477,7 +482,7 @@ export const expandSecretReferencesFactory = ({ } if (referedValue) { - expandedValue = expandedValue.replaceAll(interpolationSyntax, referedValue.value); + expandedValue = expandedValue.replaceAll(interpolationSyntax, referedValue); } } } diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts index 380bbec1f..0d2797800 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts @@ -1,7 +1,6 @@ -import { ForbiddenError, PureAbility, subject } from "@casl/ability"; -import { z } from "zod"; +import { ForbiddenError, subject } from "@casl/ability"; -import { ProjectMembershipRole, SecretsV2Schema, SecretType, TableName } from "@app/db/schemas"; +import { ProjectMembershipRole, SecretsV2Schema, SecretType } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service"; @@ -9,7 +8,7 @@ import { TSecretApprovalRequestDALFactory } from "@app/ee/services/secret-approv import { TSecretApprovalRequestSecretDALFactory } from "@app/ee/services/secret-approval-request/secret-approval-request-secret-dal"; import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; -import { diff, groupBy } from "@app/lib/fn"; +import { groupBy } from "@app/lib/fn"; import { setKnexStringValue } from "@app/lib/knex"; import { logger } from "@app/lib/logger"; import { alphaNumericNanoId } from "@app/lib/nanoid"; @@ -29,7 +28,7 @@ import { fnSecretBulkDelete, fnSecretBulkInsert, fnSecretBulkUpdate, - getAllSecretReferences, + getAllNestedSecretReferences, recursivelyGetSecretPaths, reshapeBridgeSecret } from "./secret-v2-bridge-fns"; @@ -44,7 +43,6 @@ import { TGetSecretsDTO, TGetSecretVersionsDTO, TMoveSecretsDTO, - TSecretReference, TUpdateManySecretDTO, TUpdateSecretDTO } from "./secret-v2-bridge-types"; @@ -58,7 +56,7 @@ type TSecretV2BridgeServiceFactoryDep = { secretVersionTagDAL: Pick; secretTagDAL: TSecretTagDALFactory; permissionService: Pick; - projectEnvDAL: Pick; + projectEnvDAL: Pick; folderDAL: Pick< TSecretFolderDALFactory, "findBySecretPath" | "updateById" | "findById" | "findByManySecretPath" | "find" | "findBySecretPathMultiEnv" @@ -95,83 +93,6 @@ export const secretV2BridgeServiceFactory = ({ secretApprovalRequestSecretDAL, kmsService }: TSecretV2BridgeServiceFactoryDep) => { - const $validateSecretReferences = async ( - projectId: string, - permission: PureAbility, - references: ReturnType["nestedReferences"] - ) => { - if (!references.length) return; - - const uniqueReferenceEnvironmentSlugs = Array.from(new Set(references.map((el) => el.environment))); - const referencesEnvironments = await projectEnvDAL.findBySlugs(projectId, uniqueReferenceEnvironmentSlugs); - if (referencesEnvironments.length !== uniqueReferenceEnvironmentSlugs.length) - throw new BadRequestError({ - message: `Referenced environment not found. Missing ${diff( - uniqueReferenceEnvironmentSlugs, - referencesEnvironments.map((el) => el.slug) - ).join(",")}` - }); - - const referencesEnvironmentGroupBySlug = groupBy(referencesEnvironments, (i) => i.slug); - const referredFolders = await folderDAL.findByManySecretPath( - references.map((el) => ({ - secretPath: el.secretPath, - envId: referencesEnvironmentGroupBySlug[el.environment][0].id - })) - ); - const referencesFolderGroupByPath = groupBy(referredFolders.filter(Boolean), (i) => `${i?.envId}-${i?.path}`); - const referredSecrets = await secretDAL.find({ - $complex: { - operator: "or", - value: references.map((el) => { - const folderId = - referencesFolderGroupByPath[`${referencesEnvironmentGroupBySlug[el.environment][0].id}-${el.secretPath}`][0] - ?.id; - if (!folderId) throw new BadRequestError({ message: `Referenced path ${el.secretPath} doesn't exist` }); - - return { - operator: "and", - value: [ - { - operator: "eq", - field: "folderId", - value: folderId - }, - { - operator: "eq", - field: "key", - value: el.secretKey - } - ] - }; - }) - } - }); - - if (referredSecrets.length !== references.length) - throw new BadRequestError({ - message: `Referenced secret not found. Found only ${diff( - references.map((el) => el.secretKey), - referredSecrets.map((el) => el.key) - ).join(",")}` - }); - - const referredSecretsGroupBySecretKey = groupBy(referredSecrets, (i) => i.key); - references.forEach((el) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: el.environment, - secretPath: el.secretPath, - secretName: el.secretKey, - tags: referredSecretsGroupBySecretKey[el.secretKey][0]?.tags?.map((i) => i.slug) - }) - ); - }); - - return referredSecrets; - }; - const createSecret = async ({ actor, actorId, @@ -189,6 +110,10 @@ export const secretV2BridgeServiceFactory = ({ actorAuthMethod, actorOrgId ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Create, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) @@ -209,7 +134,6 @@ export const secretV2BridgeServiceFactory = ({ }); if (inputSecret.type === SecretType.Shared && doesSecretExist) throw new BadRequestError({ message: "Secret already exist" }); - // if user creating personal check its shared also exist if (inputSecret.type === SecretType.Personal && !doesSecretExist) { throw new BadRequestError({ @@ -220,31 +144,24 @@ export const secretV2BridgeServiceFactory = ({ // validate tags // fetch all tags and if not same count throw error meaning one was invalid tags const tags = inputSecret.tagIds ? await secretTagDAL.find({ projectId, $in: { id: inputSecret.tagIds } }) : []; - if ((inputSecret.tagIds || []).length !== tags.length) - throw new NotFoundError({ message: `Tag not found. Found ${tags.map((el) => el.slug).join(",")}` }); - - const { secretName, type, ...inputSecretData } = inputSecret; - - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName, - secretTags: tags?.map((el) => el.slug) - }) - ); - - const { nestedReferences, localReferences } = getAllSecretReferences(inputSecret.secretValue); - const allSecretReferences = nestedReferences.concat( - localReferences.map((el) => ({ secretKey: el, secretPath, environment })) - ); - await $validateSecretReferences(projectId, permission, allSecretReferences); + if ((inputSecret.tagIds || []).length !== tags.length) throw new NotFoundError({ message: "Tag not found" }); + const { secretName, type, ...el } = inputSecret; + const references = getAllNestedSecretReferences(inputSecret.secretValue); const { encryptor: secretManagerEncryptor } = await kmsService.createCipherPairWithDataKey({ type: KmsDataKey.SecretManager, projectId }); + references.forEach((referredSecret) => { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { + environment: referredSecret.environment, + secretPath: referredSecret.secretPath + }) + ); + }); + const secret = await secretDAL.transaction((tx) => fnSecretBulkInsert({ folderId, @@ -252,20 +169,20 @@ export const secretV2BridgeServiceFactory = ({ { version: 1, type, - reminderRepeatDays: inputSecretData.secretReminderRepeatDays, + reminderRepeatDays: el.secretReminderRepeatDays, encryptedComment: setKnexStringValue( - inputSecretData.secretComment, + el.secretComment, (value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob ), - encryptedValue: inputSecretData.secretValue - ? secretManagerEncryptor({ plainText: Buffer.from(inputSecretData.secretValue) }).cipherTextBlob + encryptedValue: el.secretValue + ? secretManagerEncryptor({ plainText: Buffer.from(el.secretValue) }).cipherTextBlob : undefined, - reminderNote: inputSecretData.secretReminderNote, - skipMultilineEncoding: inputSecretData.skipMultilineEncoding, + reminderNote: el.secretReminderNote, + skipMultilineEncoding: el.skipMultilineEncoding, key: secretName, userId: inputSecret.type === SecretType.Personal ? actorId : null, tagIds: inputSecret.tagIds, - references: nestedReferences + references } ], secretDAL, @@ -311,6 +228,10 @@ export const secretV2BridgeServiceFactory = ({ actorAuthMethod, actorOrgId ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); if (inputSecret.newSecretName === "") { throw new BadRequestError({ message: "New secret name cannot be empty" }); @@ -355,33 +276,6 @@ export const secretV2BridgeServiceFactory = ({ secret = sharedSecretToModify; } - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: inputSecret.secretName, - secretTags: secret.tags.map((el) => el.slug) - }) - ); - - // validate tags - // fetch all tags and if not same count throw error meaning one was invalid tags - const tags = inputSecret.tagIds ? await secretTagDAL.find({ projectId, $in: { id: inputSecret.tagIds } }) : []; - if ((inputSecret.tagIds || []).length !== tags.length) - throw new NotFoundError({ message: `Tag not found. Found ${tags.map((el) => el.slug).join(",")}` }); - - // now check with new ids - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: inputSecret.secretName, - secretTags: tags?.map((el) => el.slug) - }) - ); - if (inputSecret.newSecretName) { const doesNewNameSecretExist = await secretDAL.findOne({ key: inputSecret.newSecretName, @@ -389,36 +283,36 @@ export const secretV2BridgeServiceFactory = ({ folderId }); if (doesNewNameSecretExist) throw new BadRequestError({ message: "Secret with the new name already exist" }); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: inputSecret.newSecretName, - secretTags: tags?.map((el) => el.slug) - }) - ); } + // validate tags + // fetch all tags and if not same count throw error meaning one was invalid tags + const tags = inputSecret.tagIds ? await secretTagDAL.find({ projectId, $in: { id: inputSecret.tagIds } }) : []; + if ((inputSecret.tagIds || []).length !== tags.length) throw new NotFoundError({ message: "Tag not found" }); + const { secretName, secretValue } = inputSecret; const { encryptor: secretManagerEncryptor } = await kmsService.createCipherPairWithDataKey({ type: KmsDataKey.SecretManager, projectId }); - const encryptedValue = secretValue - ? { - encryptedValue: secretManagerEncryptor({ plainText: Buffer.from(secretValue) }).cipherTextBlob, - references: getAllSecretReferences(secretValue).nestedReferences - } - : {}; - - if (secretValue) { - const { nestedReferences, localReferences } = getAllSecretReferences(secretValue); - const allSecretReferences = nestedReferences.concat( - localReferences.map((el) => ({ secretKey: el, secretPath, environment })) - ); - await $validateSecretReferences(projectId, permission, allSecretReferences); + const encryptedValue = + typeof secretValue !== "undefined" + ? { + encryptedValue: secretManagerEncryptor({ plainText: Buffer.from(secretValue) }).cipherTextBlob, + references: getAllNestedSecretReferences(secretValue) + } + : {}; + if (encryptedValue.references) { + encryptedValue.references.forEach((referredSecret) => { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { + environment: referredSecret.environment, + secretPath: referredSecret.secretPath + }) + ); + }); } const updatedSecret = await secretDAL.transaction(async (tx) => @@ -492,6 +386,10 @@ export const secretV2BridgeServiceFactory = ({ actorAuthMethod, actorOrgId ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Delete, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) @@ -516,15 +414,6 @@ export const secretV2BridgeServiceFactory = ({ }) }); if (!secretToDelete) throw new NotFoundError({ message: "Secret not found" }); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: secretToDelete.key, - secretTags: secretToDelete.tags?.map((el) => el.slug) - }) - ); const deletedSecret = await secretDAL.transaction(async (tx) => fnSecretBulkDelete({ @@ -593,7 +482,13 @@ export const secretV2BridgeServiceFactory = ({ actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets); + // verify user has access to all environments + environments.forEach((environment) => + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) + ) + ); } const folders = await folderDAL.findBySecretPathMultiEnv(projectId, environments, path); @@ -639,7 +534,10 @@ export const secretV2BridgeServiceFactory = ({ actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) + ); const folder = await folderDAL.findBySecretPath(projectId, environment, path); if (!folder) return 0; @@ -664,15 +562,22 @@ export const secretV2BridgeServiceFactory = ({ environments: string[]; isInternal?: boolean; }) => { - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - projectId, - actorAuthMethod, - actorOrgId - ); if (!isInternal) { - ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); + + // verify user has access to all environments + environments.forEach((environment) => + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) + ) + ); } let paths: { folderId: string; path: string; environment: string }[] = []; @@ -699,34 +604,22 @@ export const secretV2BridgeServiceFactory = ({ projectId }); - const decryptedSecrets = secrets - .filter((el) => - permission.can( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: groupedPaths[el.folderId][0].environment, - secretPath: groupedPaths[el.folderId][0].path, - secretName: el.key, - secretTags: el.tags.map((i) => i.slug) - }) - ) + const decryptedSecrets = secrets.map((secret) => + reshapeBridgeSecret( + projectId, + groupedPaths[secret.folderId][0].environment, + groupedPaths[secret.folderId][0].path, + { + ...secret, + value: secret.encryptedValue + ? secretManagerDecryptor({ cipherTextBlob: secret.encryptedValue }).toString() + : "", + comment: secret.encryptedComment + ? secretManagerDecryptor({ cipherTextBlob: secret.encryptedComment }).toString() + : "" + } ) - .map((secret) => - reshapeBridgeSecret( - projectId, - groupedPaths[secret.folderId][0].environment, - groupedPaths[secret.folderId][0].path, - { - ...secret, - value: secret.encryptedValue - ? secretManagerDecryptor({ cipherTextBlob: secret.encryptedValue }).toString() - : "", - comment: secret.encryptedComment - ? secretManagerDecryptor({ cipherTextBlob: secret.encryptedComment }).toString() - : "" - } - ) - ); + ); return decryptedSecrets; }; @@ -752,8 +645,6 @@ export const secretV2BridgeServiceFactory = ({ actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets); - let paths: { folderId: string; path: string }[] = []; if (recursive) { @@ -762,13 +653,26 @@ export const secretV2BridgeServiceFactory = ({ projectEnvDAL, projectId, environment, - currentPath: path + currentPath: path, + hasAccess: (permissionEnvironment, permissionSecretPath) => + permission.can( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { + environment: permissionEnvironment, + secretPath: permissionSecretPath + }) + ) }); if (!deepPaths) return { secrets: [], imports: [] }; paths = deepPaths.map(({ folderId, path: p }) => ({ folderId, path: p })); } else { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) + ); + const folder = await folderDAL.findBySecretPath(projectId, environment, path); if (!folder) return { secrets: [], imports: [] }; @@ -789,44 +693,27 @@ export const secretV2BridgeServiceFactory = ({ projectId }); - const decryptedSecrets = secrets - .filter((el) => - permission.can( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath: groupedPaths[el.folderId][0].path, - secretName: el.key, - secretTags: el.tags.map((i) => i.slug) - }) - ) - ) - .map((secret) => - reshapeBridgeSecret(projectId, environment, groupedPaths[secret.folderId][0].path, { - ...secret, - value: secret.encryptedValue - ? secretManagerDecryptor({ cipherTextBlob: secret.encryptedValue }).toString() - : "", - comment: secret.encryptedComment - ? secretManagerDecryptor({ cipherTextBlob: secret.encryptedComment }).toString() - : "" - }) - ); + const decryptedSecrets = secrets.map((secret) => + reshapeBridgeSecret(projectId, environment, groupedPaths[secret.folderId][0].path, { + ...secret, + value: secret.encryptedValue + ? secretManagerDecryptor({ cipherTextBlob: secret.encryptedValue }).toString() + : "", + comment: secret.encryptedComment + ? secretManagerDecryptor({ cipherTextBlob: secret.encryptedComment }).toString() + : "" + }) + ); const expandSecretReferences = expandSecretReferencesFactory({ projectId, folderDAL, secretDAL, decryptSecretValue: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : undefined), - canExpandValue: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => + canExpandValue: (expandEnvironment, expandSecretPath) => permission.can( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: expandEnvironment, - secretPath: expandSecretPath, - secretName: expandSecretKey, - secretTags: expandSecretTags - }) + subject(ProjectPermissionSub.Secrets, { environment: expandEnvironment, secretPath: expandSecretPath }) ) }); @@ -857,24 +744,26 @@ export const secretV2BridgeServiceFactory = ({ } const secretImports = await secretImportDAL.findByFolderIds(paths.map((p) => p.folderId)); - const allowedImports = secretImports.filter(({ isReplication }) => !isReplication); + const allowedImports = secretImports.filter(({ importEnv, importPath, isReplication }) => + !isReplication && + // if its service token allow full access over imported one + actor === ActorType.SERVICE + ? true + : permission.can( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { + environment: importEnv.slug, + secretPath: importPath + }) + ) + ); const importedSecrets = await fnSecretsV2FromImports({ - secretImports: allowedImports, + allowedImports, secretDAL, folderDAL, secretImportDAL, expandSecretReferences, - decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : ""), - hasSecretAccess: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => - permission.can( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: expandEnvironment, - secretPath: expandSecretPath, - secretName: expandSecretKey, - secretTags: expandSecretTags - }) - ) + decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : "") }); return { @@ -904,7 +793,10 @@ export const secretV2BridgeServiceFactory = ({ actorAuthMethod, actorOrgId ); - + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) + ); const folder = await folderDAL.findBySecretPath(projectId, environment, path); if (!folder) throw new NotFoundError({ @@ -940,43 +832,17 @@ export const secretV2BridgeServiceFactory = ({ userId: secretType === SecretType.Personal ? actorId : null, key: secretName }) - .then((el) => - SecretsV2Schema.extend({ - tags: z - .object({ slug: z.string(), name: z.string(), id: z.string(), color: z.string() }) - .array() - .default([]) - .optional() - }).parse({ - ...el, - id: el.secretId - }) - )); - - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath: path, - secretName, - secretTags: (secret?.tags || []).map((el) => el.slug) - }) - ); + .then((el) => SecretsV2Schema.parse({ ...el, id: el.secretId }))); const expandSecretReferences = expandSecretReferencesFactory({ projectId, folderDAL, secretDAL, decryptSecretValue: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : undefined), - canExpandValue: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => + canExpandValue: (expandEnvironment, expandSecretPath) => permission.can( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: expandEnvironment, - secretPath: expandSecretPath, - secretName: expandSecretKey, - secretTags: expandSecretTags - }) + subject(ProjectPermissionSub.Secrets, { environment: expandEnvironment, secretPath: expandSecretPath }) ) }); @@ -985,23 +851,25 @@ export const secretV2BridgeServiceFactory = ({ // here we consider the import order also thus starting from bottom if (!secret && includeImports) { const secretImports = await secretImportDAL.find({ folderId, isReplication: false }); + const allowedImports = secretImports.filter(({ importEnv, importPath }) => + // if its service token allow full access over imported one + actor === ActorType.SERVICE + ? true + : permission.can( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { + environment: importEnv.slug, + secretPath: importPath + }) + ) + ); const importedSecrets = await fnSecretsV2FromImports({ - secretImports, + allowedImports, secretDAL, folderDAL, secretImportDAL, decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : ""), - expandSecretReferences: shouldExpandSecretReferences ? expandSecretReferences : undefined, - hasSecretAccess: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => - permission.can( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment: expandEnvironment, - secretPath: expandSecretPath, - secretName: expandSecretKey, - secretTags: expandSecretTags - }) - ) + expandSecretReferences: shouldExpandSecretReferences ? expandSecretReferences : undefined }); for (let i = importedSecrets.length - 1; i >= 0; i -= 1) { @@ -1059,6 +927,10 @@ export const secretV2BridgeServiceFactory = ({ actorAuthMethod, actorOrgId ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Create, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) @@ -1068,68 +940,20 @@ export const secretV2BridgeServiceFactory = ({ }); const folderId = folder.id; - const secrets = await secretDAL.find({ + const secrets = await secretDAL.findBySecretKeys( folderId, - $complex: { - operator: "and", - value: [ - { - operator: "or", - value: inputSecrets.map((el) => ({ - operator: "and", - value: [ - { - operator: "eq", - field: "key", - value: el.secretKey - }, - { - operator: "eq", - field: "type", - value: SecretType.Shared - } - ] - })) - } - ] - } - }); + inputSecrets.map((el) => ({ + key: el.secretKey, + type: SecretType.Shared + })) + ); if (secrets.length) throw new BadRequestError({ message: `Secret already exist: ${secrets.map((el) => el.key).join(",")}` }); // get all tags const sanitizedTagIds = inputSecrets.flatMap(({ tagIds = [] }) => tagIds); const tags = sanitizedTagIds.length ? await secretTagDAL.findManyTagsById(projectId, sanitizedTagIds) : []; - if (tags.length !== sanitizedTagIds.length) - throw new NotFoundError({ message: `Tag not found. Found ${tags.map((el) => el.slug).join(",")}` }); - const tagsGroupByID = groupBy(tags, (i) => i.id); - - inputSecrets.forEach((el) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: el.secretKey, - secretTags: (el.tagIds || []).map((i) => tagsGroupByID[i][0].slug) - }) - ); - }); - - // now get all secret references made and validate the permission - const secretReferencesGroupByInputSecretKey: Record> = {}; - const secretReferences: TSecretReference[] = []; - inputSecrets.forEach((el) => { - if (el.secretValue) { - const references = getAllSecretReferences(el.secretValue); - secretReferencesGroupByInputSecretKey[el.secretKey] = references; - secretReferences.push(...references.nestedReferences); - references.localReferences.forEach((localRefKey) => { - secretReferences.push({ secretKey: localRefKey, secretPath, environment }); - }); - } - }); - await $validateSecretReferences(projectId, permission, secretReferences); + if (tags.length !== sanitizedTagIds.length) throw new NotFoundError({ message: "Tag not found" }); const { encryptor: secretManagerEncryptor, decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({ type: KmsDataKey.SecretManager, projectId }); @@ -1137,7 +961,16 @@ export const secretV2BridgeServiceFactory = ({ const newSecrets = await secretDAL.transaction(async (tx) => fnSecretBulkInsert({ inputSecrets: inputSecrets.map((el) => { - const references = secretReferencesGroupByInputSecretKey[el.secretKey].nestedReferences; + const references = getAllNestedSecretReferences(el.secretValue); + references.forEach((referredSecret) => { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { + environment: referredSecret.environment, + secretPath: referredSecret.secretPath + }) + ); + }); return { version: 1, @@ -1199,6 +1032,10 @@ export const secretV2BridgeServiceFactory = ({ actorAuthMethod, actorOrgId ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) @@ -1208,128 +1045,38 @@ export const secretV2BridgeServiceFactory = ({ }); const folderId = folder.id; - const secretsToUpdate = await secretDAL.find({ + const secretsToUpdate = await secretDAL.findBySecretKeys( folderId, - $complex: { - operator: "and", - value: [ - { - operator: "or", - value: inputSecrets.map((el) => ({ - operator: "and", - value: [ - { - operator: "eq", - field: "key", - value: el.secretKey - }, - { - operator: "eq", - field: "type", - value: SecretType.Shared - } - ] - })) - } - ] - } - }); + inputSecrets.map((el) => ({ + key: el.secretKey, + type: SecretType.Shared + })) + ); if (secretsToUpdate.length !== inputSecrets.length) throw new NotFoundError({ message: `Secret does not exist: ${secretsToUpdate.map((el) => el.key).join(",")}` }); const secretsToUpdateInDBGroupedByKey = groupBy(secretsToUpdate, (i) => i.key); - secretsToUpdate.forEach((el) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: el.key, - secretTags: el.tags.map((i) => i.slug) - }) - ); - }); - - // get all tags - const sanitizedTagIds = inputSecrets.flatMap(({ tagIds = [] }) => tagIds); - const tags = sanitizedTagIds.length ? await secretTagDAL.findManyTagsById(projectId, sanitizedTagIds) : []; - if (tags.length !== sanitizedTagIds.length) throw new NotFoundError({ message: "Tag not found" }); - const tagsGroupByID = groupBy(tags, (i) => i.id); - - // check again to avoid non authorized tags are removed - inputSecrets.forEach((el) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: el.secretKey, - secretTags: (el.tagIds || []).map((i) => tagsGroupByID[i][0].slug) - }) - ); - }); - // now find any secret that needs to update its name // same process as above const secretsWithNewName = inputSecrets.filter(({ newSecretName }) => Boolean(newSecretName)); if (secretsWithNewName.length) { - const secrets = await secretDAL.find({ + const secrets = await secretDAL.findBySecretKeys( folderId, - $complex: { - operator: "and", - value: [ - { - operator: "or", - value: secretsWithNewName.map((el) => ({ - operator: "and", - value: [ - { - operator: "eq", - field: "key", - value: el.secretKey - }, - { - operator: "eq", - field: "type", - value: SecretType.Shared - } - ] - })) - } - ] - } - }); + secretsWithNewName.map((el) => ({ + key: el.newSecretName as string, + type: SecretType.Shared + })) + ); if (secrets.length) throw new BadRequestError({ message: `Secret with new name already exists: ${secretsWithNewName.map((el) => el.newSecretName).join(",")}` }); - - secretsWithNewName.forEach((el) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: el.newSecretName as string, - secretTags: (el.tagIds || []).map((i) => tagsGroupByID[i][0].slug) - }) - ); - }); } - // now get all secret references made and validate the permission - const secretReferencesGroupByInputSecretKey: Record> = {}; - const secretReferences: TSecretReference[] = []; - inputSecrets.forEach((el) => { - if (el.secretValue) { - const references = getAllSecretReferences(el.secretValue); - secretReferencesGroupByInputSecretKey[el.secretKey] = references; - secretReferences.push(...references.nestedReferences); - references.localReferences.forEach((localRefKey) => { - secretReferences.push({ secretKey: localRefKey, secretPath, environment }); - }); - } - }); - await $validateSecretReferences(projectId, permission, secretReferences); + + // get all tags + const sanitizedTagIds = inputSecrets.flatMap(({ tagIds = [] }) => tagIds); + const tags = sanitizedTagIds.length ? await secretTagDAL.findManyTagsById(projectId, sanitizedTagIds) : []; + if (tags.length !== sanitizedTagIds.length) throw new NotFoundError({ message: "Tag not found" }); const { encryptor: secretManagerEncryptor, decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({ type: KmsDataKey.SecretManager, projectId }); @@ -1344,10 +1091,22 @@ export const secretV2BridgeServiceFactory = ({ typeof el.secretValue !== "undefined" ? { encryptedValue: secretManagerEncryptor({ plainText: Buffer.from(el.secretValue) }).cipherTextBlob, - references: secretReferencesGroupByInputSecretKey[el.secretKey].nestedReferences + references: getAllNestedSecretReferences(el.secretValue) } : {}; + if (encryptedValue.references) { + encryptedValue.references.forEach((referredSecret) => { + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Read, + subject(ProjectPermissionSub.Secrets, { + environment: referredSecret.environment, + secretPath: referredSecret.secretPath + }) + ); + }); + } + return { filter: { id: originalSecret.id, type: SecretType.Shared }, data: { @@ -1405,6 +1164,10 @@ export const secretV2BridgeServiceFactory = ({ actorAuthMethod, actorOrgId ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Delete, + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) + ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); if (!folder) @@ -1414,47 +1177,17 @@ export const secretV2BridgeServiceFactory = ({ }); const folderId = folder.id; - const secretsToDelete = await secretDAL.find({ + const secretsToDelete = await secretDAL.findBySecretKeys( folderId, - $complex: { - operator: "and", - value: [ - { - operator: "or", - value: inputSecrets.map((el) => ({ - operator: "and", - value: [ - { - operator: "eq", - field: "key", - value: el.secretKey - }, - { - operator: "eq", - field: "type", - value: SecretType.Shared - } - ] - })) - } - ] - } - }); + inputSecrets.map((el) => ({ + key: el.secretKey, + type: SecretType.Shared + })) + ); if (secretsToDelete.length !== inputSecrets.length) throw new NotFoundError({ message: `One or more secrets does not exist: ${secretsToDelete.map((el) => el.key).join(",")}` }); - secretsToDelete.forEach((el) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: el.key, - secretTags: el.tags?.map((i) => i.slug) - }) - ); - }); const secretsDeleted = await secretDAL.transaction(async (tx) => fnSecretBulkDelete({ @@ -1563,8 +1296,7 @@ export const secretV2BridgeServiceFactory = ({ .map(({ id, encryptedValue }) => ({ secretId: id, references: encryptedValue - ? getAllSecretReferences(secretManagerDecryptor({ cipherTextBlob: encryptedValue }).toString()) - .nestedReferences + ? getAllNestedSecretReferences(secretManagerDecryptor({ cipherTextBlob: encryptedValue }).toString()) : [] })), tx @@ -1595,6 +1327,21 @@ export const secretV2BridgeServiceFactory = ({ actorOrgId ); + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Delete, + subject(ProjectPermissionSub.Secrets, { environment: sourceEnvironment, secretPath: sourceSecretPath }) + ); + + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Create, + subject(ProjectPermissionSub.Secrets, { environment: destinationEnvironment, secretPath: destinationSecretPath }) + ); + + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionActions.Edit, + subject(ProjectPermissionSub.Secrets, { environment: destinationEnvironment, secretPath: destinationSecretPath }) + ); + const sourceFolder = await folderDAL.findBySecretPath(projectId, sourceEnvironment, sourceSecretPath); if (!sourceFolder) { throw new NotFoundError({ @@ -1617,20 +1364,9 @@ export const secretV2BridgeServiceFactory = ({ const sourceSecrets = await secretDAL.find({ type: SecretType.Shared, $in: { - [`${TableName.SecretV2}.id` as "id"]: secretIds + id: secretIds } }); - sourceSecrets.forEach((secret) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - subject(ProjectPermissionSub.Secrets, { - environment: sourceEnvironment, - secretPath: sourceSecretPath, - secretName: secret.key, - secretTags: secret.tags.map((el) => el.slug) - }) - ); - }); if (sourceSecrets.length !== secretIds.length) { throw new BadRequestError({ @@ -1701,32 +1437,6 @@ export const secretV2BridgeServiceFactory = ({ message: "Selected secrets already exist in the destination." }); } - - // permission check whether can create or edit the ones in the destination folder - locallyCreatedSecrets.forEach((secret) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - subject(ProjectPermissionSub.Secrets, { - environment: destinationEnvironment, - secretPath: destinationEnvironment, - secretName: secret.key, - secretTags: secret.tags.map((el) => el.slug) - }) - ); - }); - - locallyUpdatedSecrets.forEach((secret) => { - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { - environment: destinationEnvironment, - secretPath: destinationEnvironment, - secretName: secret.key, - secretTags: secret.tags.map((el) => el.slug) - }) - ); - }); - const destinationFolderPolicy = await secretApprovalPolicyService.getSecretApprovalPolicy( projectId, destinationFolder.environment.slug, @@ -1793,7 +1503,7 @@ export const secretV2BridgeServiceFactory = ({ skipMultilineEncoding: doc.skipMultilineEncoding, reminderNote: doc.reminderNote, reminderRepeatDays: doc.reminderRepeatDays, - references: doc.value ? getAllSecretReferences(doc.value).nestedReferences : [] + references: doc.value ? getAllNestedSecretReferences(doc.value) : [] }; }) }); @@ -1822,7 +1532,7 @@ export const secretV2BridgeServiceFactory = ({ ...(doc.encryptedValue ? { encryptedValue: doc.encryptedValue, - references: doc.value ? getAllSecretReferences(doc.value).nestedReferences : [] + references: doc.value ? getAllNestedSecretReferences(doc.value) : [] } : { encryptedValue: undefined, diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts index 0bb93198d..a76c57561 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-types.ts @@ -15,12 +15,6 @@ type TPartialSecret = Pick; -export type TSecretReferenceDTO = { - environment: string; - secretPath: string; - secretKey: string; -}; - export type TGetSecretsDTO = { expandSecretReferences?: boolean; path: string; diff --git a/backend/src/services/secret/secret-fns.ts b/backend/src/services/secret/secret-fns.ts index 4b17bdf92..1d0b89b46 100644 --- a/backend/src/services/secret/secret-fns.ts +++ b/backend/src/services/secret/secret-fns.ts @@ -25,7 +25,7 @@ import { logger } from "@app/lib/logger"; import { fnSecretBulkInsert as fnSecretV2BridgeBulkInsert, fnSecretBulkUpdate as fnSecretV2BridgeBulkUpdate, - getAllSecretReferences + getAllNestedSecretReferences as getAllNestedSecretReferencesV2Bridge } from "@app/services/secret-v2-bridge/secret-v2-bridge-fns"; import { ActorAuthMethod, ActorType } from "../auth/auth-type"; @@ -791,7 +791,7 @@ export const createManySecretsRawFnFactory = ({ : null, skipMultilineEncoding: secret.skipMultilineEncoding, tags: secret.tags, - references: getAllSecretReferences(secret.secretValue).nestedReferences + references: getAllNestedSecretReferencesV2Bridge(secret.secretValue) }; }); @@ -971,7 +971,7 @@ export const updateManySecretsRawFnFactory = ({ : null, skipMultilineEncoding: secret.skipMultilineEncoding, tags: secret.tags, - references: getAllSecretReferences(secret.secretValue).nestedReferences + references: getAllNestedSecretReferencesV2Bridge(secret.secretValue) }; }); diff --git a/backend/src/services/secret/secret-queue.ts b/backend/src/services/secret/secret-queue.ts index 3b949f553..4076b179f 100644 --- a/backend/src/services/secret/secret-queue.ts +++ b/backend/src/services/secret/secret-queue.ts @@ -50,7 +50,7 @@ import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretImportDALFactory } from "../secret-import/secret-import-dal"; import { fnSecretsV2FromImports } from "../secret-import/secret-import-fns"; import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal"; -import { expandSecretReferencesFactory, getAllSecretReferences } from "../secret-v2-bridge/secret-v2-bridge-fns"; +import { expandSecretReferencesFactory, getAllNestedSecretReferences } from "../secret-v2-bridge/secret-v2-bridge-fns"; import { TSecretVersionV2DALFactory } from "../secret-v2-bridge/secret-version-dal"; import { TSecretVersionV2TagDALFactory } from "../secret-v2-bridge/secret-version-tag-dal"; import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service"; @@ -342,8 +342,7 @@ export const secretQueueFactory = ({ secretDAL: secretV2BridgeDAL, expandSecretReferences, secretImportDAL, - secretImports, - hasSecretAccess: () => true + allowedImports: secretImports }); for (let i = importedSecrets.length - 1; i >= 0; i -= 1) { @@ -1148,7 +1147,7 @@ export const secretQueueFactory = ({ : ""; const encryptedValue = secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob; // create references - const references = getAllSecretReferences(value).nestedReferences; + const references = getAllNestedSecretReferences(value); secretReferences.push({ secretId: el.id, references }); const encryptedComment = comment diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index 0b0f627ef..9d3037ec0 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -2407,26 +2407,17 @@ export const secretServiceFactory = ({ ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, - subject(ProjectPermissionSub.Secrets, { - environment: sourceEnvironment, - secretPath: sourceSecretPath - }) + subject(ProjectPermissionSub.Secrets, { environment: sourceEnvironment, secretPath: sourceSecretPath }) ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, - subject(ProjectPermissionSub.Secrets, { - environment: destinationEnvironment, - secretPath: destinationSecretPath - }) + subject(ProjectPermissionSub.Secrets, { environment: destinationEnvironment, secretPath: destinationSecretPath }) ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Edit, - subject(ProjectPermissionSub.Secrets, { - environment: destinationEnvironment, - secretPath: destinationSecretPath - }) + subject(ProjectPermissionSub.Secrets, { environment: destinationEnvironment, secretPath: destinationSecretPath }) ); const { botKey } = await projectBotService.getBotKey(project.id); diff --git a/frontend/src/components/permissions/GlobPermissionInfo.tsx b/frontend/src/components/permissions/GlobPermissionInfo.tsx deleted file mode 100644 index b65b0c307..000000000 --- a/frontend/src/components/permissions/GlobPermissionInfo.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { useState } from "react"; -import picomatch from "picomatch"; - -import { FormControl } from "../v2/FormControl"; -import { Input } from "../v2/Input"; - -export const GlobPermissionInfo = () => { - const [pattern, setPattern] = useState(""); - const [text, setText] = useState(""); - - return ( -
-
A glob pattern uses wildcards to match resources or paths.
-
- - setPattern(e.target.value)} /> - -
-
- - setText(e.target.value)} /> - -
-
- ); -}; diff --git a/frontend/src/components/permissions/ProjectPermissionCan.tsx b/frontend/src/components/permissions/ProjectPermissionCan.tsx index 4fc5acde9..f1af141f2 100644 --- a/frontend/src/components/permissions/ProjectPermissionCan.tsx +++ b/frontend/src/components/permissions/ProjectPermissionCan.tsx @@ -1,25 +1,23 @@ import { FunctionComponent, ReactNode } from "react"; -import { AbilityTuple, MongoAbility } from "@casl/ability"; -import { Can } from "@casl/react"; +import { BoundCanProps, Can } from "@casl/react"; -import { ProjectPermissionSet, useProjectPermission } from "@app/context/ProjectPermissionContext"; +import { TProjectPermission, useProjectPermission } from "@app/context/ProjectPermissionContext"; -import { Tooltip } from "../v2/Tooltip"; +import { Tooltip } from "../v2"; -type Props = { +type Props = { label?: ReactNode; // this prop is used when there exist already a tooltip as helper text for users // so when permission is allowed same tooltip will be reused to show helpertext renderTooltip?: boolean; allowedLabel?: string; - children: ReactNode | ((isAllowed: boolean, ability: T) => ReactNode); - passThrough?: boolean; - I: T[0]; - a: T[1]; - ability?: MongoAbility; -}; + // BUG(akhilmhdh): As a workaround for now i put any but this should be TProjectPermission + // For some reason when i put TProjectPermission in a wrapper component it just wont work causes a weird ts error + // tried a lot combinations + // REF: https://github.com/stalniy/casl/blob/ac081a34f56366a7eaaed05d21689d27041ef005/packages/casl-react/src/factory.ts#L15 +} & BoundCanProps; -export const ProjectPermissionCan: FunctionComponent> = ({ +export const ProjectPermissionCan: FunctionComponent = ({ label = "Access restricted", children, passThrough = true, @@ -33,7 +31,9 @@ export const ProjectPermissionCan: FunctionComponent {(isAllowed, ability) => { // akhilmhdh: This is set as type due to error in casl react type. const finalChild = - typeof children === "function" ? children(isAllowed, ability as any) : children; + typeof children === "function" + ? children(isAllowed, ability as TProjectPermission) + : children; if (!isAllowed && passThrough) { return {finalChild}; diff --git a/frontend/src/components/permissions/index.tsx b/frontend/src/components/permissions/index.tsx index 5103b0f73..8d523c311 100644 --- a/frontend/src/components/permissions/index.tsx +++ b/frontend/src/components/permissions/index.tsx @@ -1,4 +1,3 @@ -export { GlobPermissionInfo } from "./GlobPermissionInfo"; export { OrgPermissionCan } from "./OrgPermissionCan"; export { PermissionDeniedBanner } from "./PermissionDeniedBanner"; export { ProjectPermissionCan } from "./ProjectPermissionCan"; diff --git a/frontend/src/components/v2/Select/Select.tsx b/frontend/src/components/v2/Select/Select.tsx index ce3f03d01..dcc7da62c 100644 --- a/frontend/src/components/v2/Select/Select.tsx +++ b/frontend/src/components/v2/Select/Select.tsx @@ -12,7 +12,6 @@ type Props = { placeholder?: string; className?: string; dropdownContainerClassName?: string; - containerClassName?: string; isLoading?: boolean; position?: "item-aligned" | "popper"; isDisabled?: boolean; @@ -32,13 +31,12 @@ export const Select = forwardRef( isDisabled, dropdownContainerClassName, position, - containerClassName, ...props }, ref ): JSX.Element => { return ( -
+
{ diff --git a/frontend/src/context/ProjectPermissionContext/index.tsx b/frontend/src/context/ProjectPermissionContext/index.tsx index 4b04f5cb8..afad2cd86 100644 --- a/frontend/src/context/ProjectPermissionContext/index.tsx +++ b/frontend/src/context/ProjectPermissionContext/index.tsx @@ -3,6 +3,5 @@ export type { ProjectPermissionSet, TProjectPermission } from "./types"; export { ProjectPermissionActions, ProjectPermissionCmekActions, - ProjectPermissionDynamicSecretActions, ProjectPermissionSub } from "./types"; diff --git a/frontend/src/context/ProjectPermissionContext/types.ts b/frontend/src/context/ProjectPermissionContext/types.ts index 307ef74af..d47a3d01b 100644 --- a/frontend/src/context/ProjectPermissionContext/types.ts +++ b/frontend/src/context/ProjectPermissionContext/types.ts @@ -7,14 +7,6 @@ export enum ProjectPermissionActions { Delete = "delete" } -export enum ProjectPermissionDynamicSecretActions { - ReadRootCredential = "read-root-credential", - CreateRootCredential = "create-root-credential", - EditRootCredential = "edit-root-credential", - DeleteRootCredential = "delete-root-credential", - Lease = "lease" -} - export enum ProjectPermissionCmekActions { Read = "read", Create = "create", @@ -29,7 +21,7 @@ export enum PermissionConditionOperators { $ALL = "$all", $REGEX = "$regex", $EQ = "$eq", - $NEQ = "$ne", + $NEQ = "$neq", $GLOB = "$glob" } @@ -45,7 +37,7 @@ export type TPermissionConditionOperators = { export type TPermissionCondition = Record< string, | string - | { $in: string[]; $all: string[]; $regex: string; $eq: string; $ne: string; $glob: string } + | { $in: string[]; $all: string[]; $regex: string; $eq: string; $neq: string; $glob: string } >; export enum ProjectPermissionSub { @@ -60,11 +52,9 @@ export enum ProjectPermissionSub { Tags = "tags", AuditLogs = "audit-logs", IpAllowList = "ip-allowlist", - Project = "workspace", + Workspace = "workspace", Secrets = "secrets", SecretFolders = "secret-folders", - SecretImports = "secret-imports", - DynamicSecrets = "dynamic-secrets", SecretRollback = "secret-rollback", SecretApproval = "secret-approval", SecretRotation = "secret-rotation", @@ -78,24 +68,7 @@ export enum ProjectPermissionSub { Cmek = "cmek" } -export type SecretSubjectFields = { - environment: string; - secretPath: string; - secretName: string; - secretTags: string[]; -}; - -export type SecretFolderSubjectFields = { - environment: string; - secretPath: string; -}; - -export type DynamicSecretSubjectFields = { - environment: string; - secretPath: string; -}; - -export type SecretImportSubjectFields = { +type SubjectFields = { environment: string; secretPath: string; }; @@ -103,30 +76,13 @@ export type SecretImportSubjectFields = { export type ProjectPermissionSet = | [ ProjectPermissionActions, - ( - | ProjectPermissionSub.Secrets - | (ForcedSubject & SecretSubjectFields) - ) + ProjectPermissionSub.Secrets | (ForcedSubject & SubjectFields) ] | [ ProjectPermissionActions, ( | ProjectPermissionSub.SecretFolders - | (ForcedSubject & SecretFolderSubjectFields) - ) - ] - | [ - ProjectPermissionDynamicSecretActions, - ( - | ProjectPermissionSub.DynamicSecrets - | (ForcedSubject & DynamicSecretSubjectFields) - ) - ] - | [ - ProjectPermissionActions, - ( - | ProjectPermissionSub.SecretImports - | (ForcedSubject & SecretImportSubjectFields) + | (ForcedSubject & SubjectFields) ) ] | [ProjectPermissionActions, ProjectPermissionSub.Role] @@ -139,19 +95,19 @@ export type ProjectPermissionSet = | [ProjectPermissionActions, ProjectPermissionSub.Environments] | [ProjectPermissionActions, ProjectPermissionSub.IpAllowList] | [ProjectPermissionActions, ProjectPermissionSub.Settings] + | [ProjectPermissionActions, ProjectPermissionSub.Identity] | [ProjectPermissionActions, ProjectPermissionSub.ServiceTokens] | [ProjectPermissionActions, ProjectPermissionSub.SecretApproval] | [ProjectPermissionActions, ProjectPermissionSub.SecretRotation] - | [ProjectPermissionActions, ProjectPermissionSub.Identity] | [ProjectPermissionActions, ProjectPermissionSub.CertificateAuthorities] | [ProjectPermissionActions, ProjectPermissionSub.Certificates] | [ProjectPermissionActions, ProjectPermissionSub.CertificateTemplates] | [ProjectPermissionActions, ProjectPermissionSub.PkiAlerts] | [ProjectPermissionActions, ProjectPermissionSub.PkiCollections] - | [ProjectPermissionActions.Delete, ProjectPermissionSub.Project] - | [ProjectPermissionActions.Edit, ProjectPermissionSub.Project] + | [ProjectPermissionActions.Delete, ProjectPermissionSub.Workspace] + | [ProjectPermissionActions.Edit, ProjectPermissionSub.Workspace] | [ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback] | [ProjectPermissionActions.Create, ProjectPermissionSub.SecretRollback] - | [ProjectPermissionCmekActions, ProjectPermissionSub.Cmek] - | [ProjectPermissionActions.Edit, ProjectPermissionSub.Kms]; + | [ProjectPermissionCmekActions, ProjectPermissionSub.Cmek]; + export type TProjectPermission = MongoAbility; diff --git a/frontend/src/context/index.tsx b/frontend/src/context/index.tsx index 91dae5d2d..ada436833 100644 --- a/frontend/src/context/index.tsx +++ b/frontend/src/context/index.tsx @@ -11,7 +11,6 @@ export type { TProjectPermission } from "./ProjectPermissionContext"; export { ProjectPermissionActions, ProjectPermissionCmekActions, - ProjectPermissionDynamicSecretActions, ProjectPermissionProvider, ProjectPermissionSub, useProjectPermission diff --git a/frontend/src/hoc/withProjectPermission/withProjectPermission.tsx b/frontend/src/hoc/withProjectPermission/withProjectPermission.tsx index 22c91ab52..103ff61b7 100644 --- a/frontend/src/hoc/withProjectPermission/withProjectPermission.tsx +++ b/frontend/src/hoc/withProjectPermission/withProjectPermission.tsx @@ -1,29 +1,31 @@ import { ComponentType } from "react"; -import { AbilityTuple } from "@casl/ability"; +import { Abilities, AbilityTuple, Generics, SubjectType } from "@casl/ability"; import { faLock } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { twMerge } from "tailwind-merge"; -import { useProjectPermission } from "@app/context"; -import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext"; +import { TProjectPermission, useProjectPermission } from "@app/context"; -type Props = { - className?: string; - containerClassName?: string; - action: T[0]; - subject: T[1]; -}; +type Props = (T extends AbilityTuple + ? { + action: T[0]; + subject: Extract; + } + : { + action: string; + subject: string; + }) & { className?: string; containerClassName?: string }; -export const withProjectPermission = ( - Component: ComponentType, "action" | "subject"> & T>, - { action, subject, className, containerClassName }: Props +export const withProjectPermission = ( + Component: ComponentType, + { action, subject, className, containerClassName }: Props["abilities"]> ) => { - const HOC = (hocProps: Omit, "action" | "subject"> & T) => { + const HOC = (hocProps: T) => { const { permission } = useProjectPermission(); // akhilmhdh: Set as any due to casl/react ts type bug // REASON: casl due to its type checking can't seem to union even if union intersection is applied - if (permission.cannot(action as any, subject as any)) { + if (permission.cannot(action as any, subject)) { return (
["dashboard"] as const, @@ -155,20 +154,10 @@ export const useGetProjectSecretsOverview = ( }, select: useCallback((data: Awaited>) => { const { secrets, ...select } = data; - const uniqueSecrets = secrets ? unique(secrets, (i) => i.secretKey) : []; - - const uniqueFolders = select.folders ? unique(select.folders, (i) => i.name) : []; - - const uniqueDynamicSecrets = select.dynamicSecrets - ? unique(select.dynamicSecrets, (i) => i.name) - : []; return { ...select, - secrets: secrets ? mergePersonalSecrets(secrets) : undefined, - totalUniqueSecretsInPage: uniqueSecrets.length, - totalUniqueDynamicSecretsInPage: uniqueDynamicSecrets.length, - totalUniqueFoldersInPage: uniqueFolders.length + secrets: secrets ? mergePersonalSecrets(secrets) : undefined }; }, []), keepPreviousData: true diff --git a/frontend/src/hooks/api/dashboard/types.ts b/frontend/src/hooks/api/dashboard/types.ts index 865d8541d..08e75ee3b 100644 --- a/frontend/src/hooks/api/dashboard/types.ts +++ b/frontend/src/hooks/api/dashboard/types.ts @@ -12,9 +12,6 @@ export type DashboardProjectSecretsOverviewResponse = { totalFolderCount?: number; totalDynamicSecretCount?: number; totalCount: number; - totalUniqueSecretsInPage: number; - totalUniqueDynamicSecretsInPage: number; - totalUniqueFoldersInPage: number; }; export type DashboardProjectSecretsDetailsResponse = { diff --git a/frontend/src/hooks/api/projectUserAdditionalPrivilege/mutation.tsx b/frontend/src/hooks/api/projectUserAdditionalPrivilege/mutation.tsx index 2ee6519f6..fb21a425e 100644 --- a/frontend/src/hooks/api/projectUserAdditionalPrivilege/mutation.tsx +++ b/frontend/src/hooks/api/projectUserAdditionalPrivilege/mutation.tsx @@ -1,3 +1,4 @@ +import { packRules } from "@casl/ability/extra"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { apiRequest } from "@app/config/request"; @@ -15,7 +16,10 @@ export const useCreateProjectUserAdditionalPrivilege = () => { return useMutation<{ privilege: TProjectUserPrivilege }, {}, TCreateProjectUserPrivilegeDTO>({ mutationFn: async (dto) => { - const { data } = await apiRequest.post("/api/v1/additional-privilege/users/permanent", dto); + const { data } = await apiRequest.post("/api/v1/additional-privilege/users/permanent", { + ...dto, + permissions: packRules(dto.permissions) + }); return data.privilege; }, onSuccess: (_, { projectMembershipId }) => { @@ -31,7 +35,7 @@ export const useUpdateProjectUserAdditionalPrivilege = () => { mutationFn: async (dto) => { const { data } = await apiRequest.patch( `/api/v1/additional-privilege/users/${dto.privilegeId}`, - dto + { ...dto, permissions: dto.permissions ? packRules(dto.permissions) : undefined } ); return data.privilege; }, diff --git a/frontend/src/hooks/api/projectUserAdditionalPrivilege/queries.tsx b/frontend/src/hooks/api/projectUserAdditionalPrivilege/queries.tsx index 261821c1f..41c9a0dcc 100644 --- a/frontend/src/hooks/api/projectUserAdditionalPrivilege/queries.tsx +++ b/frontend/src/hooks/api/projectUserAdditionalPrivilege/queries.tsx @@ -1,3 +1,4 @@ +import { PackRule, unpackRules } from "@casl/ability/extra"; import { useQuery } from "@tanstack/react-query"; import { apiRequest } from "@app/config/request"; @@ -17,7 +18,10 @@ const fetchProjectUserPrivilegeDetails = async (privilegeId: string) => { } = await apiRequest.get<{ privilege: Omit & { permissions: unknown }; }>(`/api/v1/additional-privilege/users/${privilegeId}`); - return privilege; + return { + ...privilege, + permissions: unpackRules(privilege.permissions as PackRule[]) + }; }; export const useGetProjectUserPrivilegeDetails = (privilegeId: string) => { @@ -40,7 +44,7 @@ export const useListProjectUserPrivileges = (projectMembershipId: string) => { }>("/api/v1/additional-privilege/users", { params: { projectMembershipId } }); return privileges.map((el) => ({ ...el, - permissions: el.permissions as TProjectPermission[] + permissions: unpackRules(el.permissions as PackRule[]) })); } }); diff --git a/frontend/src/hooks/api/projectUserAdditionalPrivilege/types.tsx b/frontend/src/hooks/api/projectUserAdditionalPrivilege/types.tsx index da40005c2..b757a07ab 100644 --- a/frontend/src/hooks/api/projectUserAdditionalPrivilege/types.tsx +++ b/frontend/src/hooks/api/projectUserAdditionalPrivilege/types.tsx @@ -4,15 +4,6 @@ export enum ProjectUserAdditionalPrivilegeTemporaryMode { Relative = "relative" } -export type TProjectSpecificPrivilegePermission = { - conditions: { - environment: string; - secretPath?: { $glob: string }; - }; - actions: string[]; - subject: string; -}; - export type TProjectUserPrivilege = { projectMembershipId: string; slug: string; @@ -21,21 +12,21 @@ export type TProjectUserPrivilege = { updatedAt: Date; permissions?: TProjectPermission[]; } & ( - | { + | { isTemporary: true; temporaryMode: string; temporaryRange: string; temporaryAccessStartTime: string; temporaryAccessEndTime?: string; } - | { + | { isTemporary: false; temporaryMode?: null; temporaryRange?: null; temporaryAccessStartTime?: null; temporaryAccessEndTime?: null; } -); + ); export type TCreateProjectUserPrivilegeDTO = { projectMembershipId: string; @@ -44,7 +35,7 @@ export type TCreateProjectUserPrivilegeDTO = { temporaryMode?: ProjectUserAdditionalPrivilegeTemporaryMode; temporaryRange?: string; temporaryAccessStartTime?: string; - permissions: TProjectSpecificPrivilegePermission; + permissions: TProjectPermission[]; }; export type TUpdateProjectUserPrivlegeDTO = { diff --git a/frontend/src/hooks/api/roles/mutation.tsx b/frontend/src/hooks/api/roles/mutation.tsx index 1c6b85b66..3f782171e 100644 --- a/frontend/src/hooks/api/roles/mutation.tsx +++ b/frontend/src/hooks/api/roles/mutation.tsx @@ -22,7 +22,7 @@ export const useCreateProjectRole = () => { mutationFn: async ({ projectSlug, ...dto }: TCreateProjectRoleDTO) => { const { data: { role } - } = await apiRequest.post(`/api/v2/workspace/${projectSlug}/roles`, dto); + } = await apiRequest.post(`/api/v1/workspace/${projectSlug}/roles`, dto); return role; }, onSuccess: (_, { projectSlug }) => { @@ -38,7 +38,7 @@ export const useUpdateProjectRole = () => { mutationFn: async ({ id, projectSlug, ...dto }: TUpdateProjectRoleDTO) => { const { data: { role } - } = await apiRequest.patch(`/api/v2/workspace/${projectSlug}/roles/${id}`, dto); + } = await apiRequest.patch(`/api/v1/workspace/${projectSlug}/roles/${id}`, dto); return role; }, onSuccess: (_, { projectSlug }) => { @@ -53,7 +53,7 @@ export const useDeleteProjectRole = () => { mutationFn: async ({ projectSlug, id }: TDeleteProjectRoleDTO) => { const { data: { role } - } = await apiRequest.delete(`/api/v2/workspace/${projectSlug}/roles/${id}`); + } = await apiRequest.delete(`/api/v1/workspace/${projectSlug}/roles/${id}`); return role; }, onSuccess: (_, { projectSlug }) => { diff --git a/frontend/src/hooks/api/roles/queries.tsx b/frontend/src/hooks/api/roles/queries.tsx index 1726abfd3..77e82e4fa 100644 --- a/frontend/src/hooks/api/roles/queries.tsx +++ b/frontend/src/hooks/api/roles/queries.tsx @@ -7,8 +7,6 @@ import picomatch from "picomatch"; import { apiRequest } from "@app/config/request"; import { OrgPermissionSet } from "@app/context/OrgPermissionContext/types"; import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext/types"; -import { groupBy } from "@app/lib/fn/array"; -import { omit } from "@app/lib/fn/object"; import { OrgUser, TProjectMembership } from "../users/types"; import { @@ -51,7 +49,7 @@ export const roleQueryKeys = { export const getProjectRoles = async (projectId: string) => { const { data } = await apiRequest.get<{ roles: Array> }>( - `/api/v2/workspace/${projectId}/roles` + `/api/v1/workspace/${projectId}/roles` ); return data.roles; }; @@ -68,7 +66,7 @@ export const useGetProjectRoleBySlug = (projectSlug: string, roleSlug: string) = queryKey: roleQueryKeys.getProjectRoleBySlug(projectSlug, roleSlug), queryFn: async () => { const { data } = await apiRequest.get<{ role: TProjectRole }>( - `/api/v2/workspace/${projectSlug}/roles/slug/${roleSlug}` + `/api/v1/workspace/${projectSlug}/roles/slug/${roleSlug}` ); return data.role; }, @@ -136,7 +134,7 @@ const getUserProjectPermissions = async ({ workspaceId }: TGetUserProjectPermiss permissions: PackRule>>[]; membership: Omit & { roles: { role: string }[] }; }; - }>(`/api/v2/workspace/${workspaceId}/permissions`, {}); + }>(`/api/v1/workspace/${workspaceId}/permissions`, {}); return data.data; }; @@ -148,32 +146,8 @@ export const useGetUserProjectPermissions = ({ workspaceId }: TGetUserProjectPer enabled: Boolean(workspaceId), select: (data) => { const rule = unpackRules>>(data.permissions); - const negatedRules = groupBy( - rule.filter((i) => i.inverted && i.conditions), - (i) => `${i.subject}-${JSON.stringify(i.conditions)}` - ); - const ability = createMongoAbility(rule, { - // this allows in frontend to skip some rules using * - conditionsMatcher: (rules) => { - return (entity) => { - // skip validation if its negated rules - const isNegatedRule = - // eslint-disable-next-line no-underscore-dangle - negatedRules?.[`${entity.__caslSubjectType__}-${JSON.stringify(rules)}`]; - if (isNegatedRule) { - const baseMatcher = conditionsMatcher(rules); - return baseMatcher(entity); - } + const ability = createMongoAbility(rule, { conditionsMatcher }); - const rulesStrippedOfWildcard = omit( - rules, - Object.keys(entity).filter((el) => entity[el]?.includes("*")) - ); - const baseMatcher = conditionsMatcher(rulesStrippedOfWildcard); - return baseMatcher(entity); - }; - } - }); const membership = { ...data.membership, roles: data.membership.roles.map(({ role }) => role) diff --git a/frontend/src/hooks/api/roles/types.ts b/frontend/src/hooks/api/roles/types.ts index 50cdf5a22..da28d9ca8 100644 --- a/frontend/src/hooks/api/roles/types.ts +++ b/frontend/src/hooks/api/roles/types.ts @@ -40,7 +40,6 @@ export type TPermission = { export type TProjectPermission = { conditions?: Record; - inverted?: boolean; action: string | string[]; subject: string | string[]; }; diff --git a/frontend/src/lib/fn/array.ts b/frontend/src/lib/fn/array.ts index eef80a892..b92390697 100644 --- a/frontend/src/lib/fn/array.ts +++ b/frontend/src/lib/fn/array.ts @@ -13,22 +13,3 @@ export const groupBy = ( acc[groupId].push(item); return acc; }, {} as Record); - -/** - * Given a list of items returns a new list with only - * unique items. Accepts an optional identity function - * to convert each item in the list to a comparable identity - * value - */ -export const unique = ( - array: readonly T[], - toKey?: (item: T) => K -): T[] => { - const valueMap = array.reduce((acc, item) => { - const key = toKey ? toKey(item) : (item as unknown as string | number | symbol); - if (acc[key]) return acc; - acc[key] = item; - return acc; - }, {} as Record); - return Object.values(valueMap); -}; diff --git a/frontend/src/lib/fn/object.ts b/frontend/src/lib/fn/object.ts deleted file mode 100644 index 0af1ead2d..000000000 --- a/frontend/src/lib/fn/object.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Omit a list of properties from an object - * returning a new object with the properties - * that remain - */ -export const omit = (obj: T, keys: TKeys[]): Omit => { - if (!obj) return {} as Omit; - if (!keys || keys.length === 0) return obj as Omit; - return keys.reduce( - (acc, key) => { - // Gross, I know, it's mutating the object, but we - // are allowing it in this very limited scope due - // to the performance implications of an omit func. - // Not a pattern or practice to use elsewhere. - delete acc[key]; - return acc; - }, - { ...obj } - ); -}; diff --git a/frontend/src/views/Project/MembersPage/components/MembersTab/components/MemberRoleForm/SpecificPrivilegeSection.tsx b/frontend/src/views/Project/MembersPage/components/MembersTab/components/MemberRoleForm/SpecificPrivilegeSection.tsx index 51581de4d..7894d0e78 100644 --- a/frontend/src/views/Project/MembersPage/components/MembersTab/components/MemberRoleForm/SpecificPrivilegeSection.tsx +++ b/frontend/src/views/Project/MembersPage/components/MembersTab/components/MemberRoleForm/SpecificPrivilegeSection.tsx @@ -184,20 +184,20 @@ export const SpecificPrivilegeSecretForm = ({ { action: ProjectPermissionActions.Delete, allowed: data.delete }, { action: ProjectPermissionActions.Edit, allowed: data.edit } ]; - const conditions: { environment: string; secretPath?: { $glob: string } } = { - environment: data.environmentSlug - }; + const conditions: Record = { environment: data.environmentSlug }; if (data.secretPath) { conditions.secretPath = { $glob: removeTrailingSlash(data.secretPath) }; } await updateUserPrivilege.mutateAsync({ privilegeId: privilege.id, ...data.temporaryAccess, - permissions: { - subject: ProjectPermissionSub.Secrets, - conditions, - actions: actions.filter((i) => i.allowed).map((i) => i.action) - }, + permissions: actions + .filter(({ allowed }) => allowed) + .map(({ action }) => ({ + action, + subject: [ProjectPermissionSub.Secrets], + conditions + })), projectMembershipId: privilege.projectMembershipId }); createNotification({ @@ -642,13 +642,15 @@ export const SpecificPrivilegeSection = ({ membershipId }: Props) => { if (createUserPrivilege.isLoading) return; try { await createUserPrivilege.mutateAsync({ - permissions: { - actions: [ProjectPermissionActions.Read], - subject: ProjectPermissionSub.Secrets, - conditions: { - environment: currentWorkspace?.environments?.[0].slug || "" + permissions: [ + { + action: ProjectPermissionActions.Read, + subject: [ProjectPermissionSub.Secrets], + conditions: { + environment: currentWorkspace?.environments?.[0].slug + } } - }, + ], projectMembershipId: membershipId }); createNotification({ diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts index 5832e5a14..7dd981691 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts @@ -7,7 +7,6 @@ import { } from "@app/context"; import { PermissionConditionOperators, - ProjectPermissionDynamicSecretActions, TPermissionCondition, TPermissionConditionOperators } from "@app/context/ProjectPermissionContext/types"; @@ -29,12 +28,8 @@ const CmekPolicyActionSchema = z.object({ decrypt: z.boolean().optional() }); -const DynamicSecretPolicyActionSchema = z.object({ - [ProjectPermissionDynamicSecretActions.ReadRootCredential]: z.boolean().optional(), - [ProjectPermissionDynamicSecretActions.EditRootCredential]: z.boolean().optional(), - [ProjectPermissionDynamicSecretActions.DeleteRootCredential]: z.boolean().optional(), - [ProjectPermissionDynamicSecretActions.CreateRootCredential]: z.boolean().optional(), - [ProjectPermissionDynamicSecretActions.Lease]: z.boolean().optional() +const SecretFolderPolicyActionSchema = z.object({ + read: z.boolean().optional() }); const SecretRollbackPolicyActionSchema = z.object({ @@ -47,29 +42,11 @@ const WorkspacePolicyActionSchema = z.object({ delete: z.boolean().optional() }); -const ConditionSchema = z - .object({ - operator: z.string(), - lhs: z.string(), - rhs: z.string().min(1) - }) - .array() - .optional() - .default([]) - .refine( - (el) => { - const lhsOperatorSet = new Set(); - for (let i = 0; i < el.length; i += 1) { - const { lhs, operator } = el[i]; - if (lhsOperatorSet.has(`${lhs}-${operator}`)) { - return false; - } - lhsOperatorSet.add(`${lhs}-${operator}`); - } - return true; - }, - { message: "Duplicate operator found for a condition" } - ); +const ConditionSchema = z.object({ + operator: z.string(), + lhs: z.string(), + rhs: z.string().min(1) +}); export const formSchema = z.object({ name: z.string().trim(), @@ -82,29 +59,27 @@ export const formSchema = z.object({ permissions: z .object({ [ProjectPermissionSub.Secrets]: GeneralPolicyActionSchema.extend({ - inverted: z.boolean().optional(), - conditions: ConditionSchema - }) - .array() - .default([]), - [ProjectPermissionSub.SecretFolders]: GeneralPolicyActionSchema.extend({ - inverted: z.boolean().optional(), - conditions: ConditionSchema - }) - .array() - .default([]), - [ProjectPermissionSub.SecretImports]: GeneralPolicyActionSchema.extend({ - inverted: z.boolean().optional(), - conditions: ConditionSchema - }) - .array() - .default([]), - [ProjectPermissionSub.DynamicSecrets]: DynamicSecretPolicyActionSchema.extend({ - inverted: z.boolean().optional(), - conditions: ConditionSchema + conditions: ConditionSchema.array() + .optional() + .default([]) + .refine( + (el) => { + const lhsOperatorSet = new Set(); + for (let i = 0; i < el.length; i += 1) { + const { lhs, operator } = el[i]; + if (lhsOperatorSet.has(`${lhs}-${operator}`)) { + return false; + } + lhsOperatorSet.add(`${lhs}-${operator}`); + } + return true; + }, + { message: "Duplicate operator found for a condition" } + ) }) .array() .default([]), + [ProjectPermissionSub.SecretFolders]: SecretFolderPolicyActionSchema.array().default([]), [ProjectPermissionSub.Member]: GeneralPolicyActionSchema.array().default([]), [ProjectPermissionSub.Groups]: GeneralPolicyActionSchema.array().default([]), [ProjectPermissionSub.Identity]: GeneralPolicyActionSchema.array().default([]), @@ -123,7 +98,7 @@ export const formSchema = z.object({ [ProjectPermissionSub.CertificateTemplates]: GeneralPolicyActionSchema.array().default([]), [ProjectPermissionSub.SecretApproval]: GeneralPolicyActionSchema.array().default([]), [ProjectPermissionSub.SecretRollback]: SecretRollbackPolicyActionSchema.array().default([]), - [ProjectPermissionSub.Project]: WorkspacePolicyActionSchema.array().default([]), + [ProjectPermissionSub.Workspace]: WorkspacePolicyActionSchema.array().default([]), [ProjectPermissionSub.Tags]: GeneralPolicyActionSchema.array().default([]), [ProjectPermissionSub.SecretRotation]: GeneralPolicyActionSchema.array().default([]), [ProjectPermissionSub.Kms]: GeneralPolicyActionSchema.array().default([]), @@ -135,22 +110,8 @@ export const formSchema = z.object({ export type TFormSchema = z.infer; -type TConditionalFields = - | ProjectPermissionSub.Secrets - | ProjectPermissionSub.SecretFolders - | ProjectPermissionSub.SecretImports - | ProjectPermissionSub.DynamicSecrets; - -export const isConditionalSubjects = ( - subject: ProjectPermissionSub -): subject is TConditionalFields => - subject === (ProjectPermissionSub.Secrets as const) || - subject === ProjectPermissionSub.DynamicSecrets || - subject === ProjectPermissionSub.SecretImports || - subject === ProjectPermissionSub.SecretFolders; - const convertCaslConditionToFormOperator = (caslConditions: TPermissionCondition) => { - const formConditions: z.infer = []; + const formConditions: z.infer[] = []; Object.entries(caslConditions).forEach(([type, condition]) => { if (typeof condition === "string") { formConditions.push({ @@ -177,15 +138,12 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { const formVal: Partial = {}; permissions.forEach((permission) => { - const { subject: caslSub, action, conditions, inverted } = permission; + const { subject: caslSub, action, conditions } = permission; const subject = (typeof caslSub === "string" ? caslSub : caslSub[0]) as ProjectPermissionSub; if ( [ ProjectPermissionSub.Secrets, - ProjectPermissionSub.DynamicSecrets, - ProjectPermissionSub.SecretFolders, - ProjectPermissionSub.SecretImports, ProjectPermissionSub.Member, ProjectPermissionSub.Groups, ProjectPermissionSub.Identity, @@ -208,67 +166,37 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { ProjectPermissionSub.Kms ].includes(subject) ) { + const canRead = action.includes(ProjectPermissionActions.Read); + const canEdit = action.includes(ProjectPermissionActions.Edit); + const canDelete = action.includes(ProjectPermissionActions.Delete); + const canCreate = action.includes(ProjectPermissionActions.Create); + // from above statement we are sure it won't be undefined - if (isConditionalSubjects(subject)) { + if (subject === ProjectPermissionSub.Secrets) { if (!formVal[subject]) formVal[subject] = []; - - if (subject === ProjectPermissionSub.DynamicSecrets) { - const canRead = action.includes(ProjectPermissionDynamicSecretActions.ReadRootCredential); - const canEdit = action.includes(ProjectPermissionDynamicSecretActions.EditRootCredential); - const canDelete = action.includes( - ProjectPermissionDynamicSecretActions.DeleteRootCredential - ); - const canCreate = action.includes( - ProjectPermissionDynamicSecretActions.CreateRootCredential - ); - const canLease = action.includes(ProjectPermissionDynamicSecretActions.Lease); - - // from above statement we are sure it won't be undefined - formVal[subject]!.push({ - [ProjectPermissionDynamicSecretActions.ReadRootCredential]: canRead, - [ProjectPermissionDynamicSecretActions.CreateRootCredential]: canCreate, - [ProjectPermissionDynamicSecretActions.EditRootCredential]: canEdit, - [ProjectPermissionDynamicSecretActions.DeleteRootCredential]: canDelete, - conditions: conditions ? convertCaslConditionToFormOperator(conditions) : [], - inverted, - [ProjectPermissionDynamicSecretActions.Lease]: canLease - }); - } else { - // for other subjects - const canRead = action.includes(ProjectPermissionActions.Read); - const canEdit = action.includes(ProjectPermissionActions.Edit); - const canDelete = action.includes(ProjectPermissionActions.Delete); - const canCreate = action.includes(ProjectPermissionActions.Create); - formVal[subject]!.push({ - read: canRead, - create: canCreate, - edit: canEdit, - delete: canDelete, - conditions: conditions ? convertCaslConditionToFormOperator(conditions) : [], - inverted - }); - } + formVal[subject]!.push({ + read: canRead, + create: canCreate, + edit: canEdit, + delete: canDelete, + conditions: conditions ? convertCaslConditionToFormOperator(conditions) : [] + }); } else { // deduplicate multiple rules for other policies // because they don't have condition it doesn't make sense for multiple rules - const canRead = action.includes(ProjectPermissionActions.Read); - const canEdit = action.includes(ProjectPermissionActions.Edit); - const canDelete = action.includes(ProjectPermissionActions.Delete); - const canCreate = action.includes(ProjectPermissionActions.Create); - if (!formVal[subject]) formVal[subject] = [{}]; if (canRead) formVal[subject as ProjectPermissionSub.Member]![0].read = true; if (canEdit) formVal[subject as ProjectPermissionSub.Member]![0].edit = true; if (canCreate) formVal[subject as ProjectPermissionSub.Member]![0].create = true; if (canDelete) formVal[subject as ProjectPermissionSub.Member]![0].delete = true; } - } else if (subject === ProjectPermissionSub.Project) { + } else if (subject === ProjectPermissionSub.Workspace) { const canEdit = action.includes(ProjectPermissionActions.Edit); const canDelete = action.includes(ProjectPermissionActions.Delete); if (!formVal[subject]) formVal[subject] = [{}]; // from above statement we are sure it won't be undefined - if (canEdit) formVal[subject as ProjectPermissionSub.Project]![0].edit = true; + if (canEdit) formVal[subject as ProjectPermissionSub.Workspace]![0].edit = true; if (canDelete) formVal[subject as ProjectPermissionSub.Member]![0].delete = true; } else if (subject === ProjectPermissionSub.SecretRollback) { const canRead = action.includes(ProjectPermissionActions.Read); @@ -278,6 +206,12 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { // from above statement we are sure it won't be undefined if (canRead) formVal[subject as ProjectPermissionSub.Member]![0].read = true; if (canCreate) formVal[subject as ProjectPermissionSub.Member]![0].create = true; + } else if (subject === ProjectPermissionSub.SecretFolders) { + const canRead = action.includes(ProjectPermissionActions.Read); + if (!formVal[subject]) formVal[subject] = [{}]; + + // from above statement we are sure it won't be undefined + if (canRead) formVal[subject as ProjectPermissionSub.Member]![0].read = true; } else if (subject === ProjectPermissionSub.Cmek) { const canRead = action.includes(ProjectPermissionCmekActions.Read); const canEdit = action.includes(ProjectPermissionCmekActions.Edit); @@ -330,7 +264,7 @@ export const formRolePermission2API = (formVal: TFormSchema["permissions"]) => { Object.entries(formVal || {}).forEach(([subject, rules]) => { rules.forEach((actions) => { const caslActions = Object.keys(actions).filter( - (el) => actions?.[el as keyof typeof actions] && el !== "conditions" && el !== "inverted" + (el) => actions?.[el as keyof typeof actions] && el !== "conditions" ); const caslConditions = "conditions" in actions @@ -340,7 +274,6 @@ export const formRolePermission2API = (formVal: TFormSchema["permissions"]) => { permissions.push({ action: caslActions, subject, - inverted: (actions as { inverted?: boolean })?.inverted, conditions: caslConditions }); }); @@ -355,7 +288,7 @@ export type TProjectPermissionObject = { label: string; value: keyof Omit< NonNullable[K]>[number], - "conditions" | "inverted" + "conditions" >; }[]; }; @@ -373,42 +306,7 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = { }, [ProjectPermissionSub.SecretFolders]: { title: "Secret Folders", - actions: [ - { label: "Create", value: "create" }, - { label: "Modify", value: "edit" }, - { label: "Remove", value: "delete" } - ] - }, - [ProjectPermissionSub.SecretImports]: { - title: "Secret Imports", - actions: [ - { label: "Read", value: "read" }, - { label: "Create", value: "create" }, - { label: "Modify", value: "edit" }, - { label: "Remove", value: "delete" } - ] - }, - [ProjectPermissionSub.DynamicSecrets]: { - title: "Dynamic Secrets", - actions: [ - { - label: "Read root credentials", - value: ProjectPermissionDynamicSecretActions.ReadRootCredential - }, - { - label: "Create root credentials", - value: ProjectPermissionDynamicSecretActions.CreateRootCredential - }, - { - label: "Modify root credentials", - value: ProjectPermissionDynamicSecretActions.EditRootCredential - }, - { - label: "Remove root credentials", - value: ProjectPermissionDynamicSecretActions.DeleteRootCredential - }, - { label: "Manage Leases", value: ProjectPermissionDynamicSecretActions.Lease } - ] + actions: [{ label: "Read Only", value: "read" }] }, [ProjectPermissionSub.Cmek]: { title: "KMS", @@ -434,7 +332,7 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = { { label: "Remove", value: "delete" } ] }, - [ProjectPermissionSub.Project]: { + [ProjectPermissionSub.Workspace]: { title: "Project", actions: [ { label: "Update project details", value: "edit" }, diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx index a7ac06010..fb3567897 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx @@ -10,15 +10,13 @@ import { ProjectPermissionSub, useWorkspace } from "@app/context"; import { usePopUp } from "@app/hooks"; import { useGetProjectRoleBySlug, useUpdateProjectRole } from "@app/hooks/api"; -import { GeneralPermissionConditions } from "./components/GeneralPermissionConditions"; -import { GeneralPermissionPolicies } from "./components/GeneralPermissionPolicies"; +import { GeneralPermissionOptions } from "./components/GeneralPermissionOptions"; import { NewPermissionRule } from "./components/NewPermissionRule"; import { SecretPermissionConditions } from "./components/SecretPermissionConditions"; import { PermissionEmptyState } from "./PermissionEmptyState"; import { formRolePermission2API, formSchema, - isConditionalSubjects, PROJECT_PERMISSION_OBJECT, rolePermission2Form, TFormSchema @@ -29,17 +27,6 @@ type Props = { isDisabled?: boolean; }; -const renderConditionalComponents = (subject: ProjectPermissionSub, isDisabled?: boolean) => { - if (subject === ProjectPermissionSub.Secrets) - return ; - - if (isConditionalSubjects(subject)) { - return ; - } - - return undefined; -}; - export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => { const { currentWorkspace } = useWorkspace(); const { popUp, handlePopUpToggle } = usePopUp(["createPolicy"] as const); @@ -143,15 +130,17 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => {
{!isLoading && } {(Object.keys(PROJECT_PERMISSION_OBJECT) as ProjectPermissionSub[]).map((subject) => ( - - {renderConditionalComponents(subject, isDisabled)} - + {subject === ProjectPermissionSub.Secrets ? ( + + ) : undefined} + ))}
diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx deleted file mode 100644 index 2ac518038..000000000 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionConditions.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import { Controller, useFieldArray, useFormContext } from "react-hook-form"; -import { faInfoCircle, faPlus, faTrash, faWarning } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; - -import { - Button, - FormControl, - IconButton, - Input, - Select, - SelectItem, - Tooltip -} from "@app/components/v2"; -import { - PermissionConditionOperators, - ProjectPermissionSub -} from "@app/context/ProjectPermissionContext/types"; - -import { TFormSchema } from "../ProjectRoleModifySection.utils"; -import { - getConditionOperatorHelperInfo, - renderOperatorSelectItems -} from "./PermissionConditionHelpers"; - -type Props = { - position?: number; - isDisabled?: boolean; - type: - | ProjectPermissionSub.DynamicSecrets - | ProjectPermissionSub.SecretFolders - | ProjectPermissionSub.SecretImports; -}; - -export const GeneralPermissionConditions = ({ position = 0, isDisabled, type }: Props) => { - const { - control, - watch, - formState: { errors } - } = useFormContext(); - const items = useFieldArray({ - control, - name: `permissions.${type}.${position}.conditions` - }); - - return ( -
-

Conditions

-

- When this policy should apply (always if no conditions are added). -

-
- {items.fields.map((el, index) => { - const condition = - (watch(`permissions.${type}.${position}.conditions.${index}`) as { - lhs: string; - rhs: string; - operator: string; - }) || {}; - return ( -
-
- ( - - - - )} - /> -
-
- ( - - - - )} - /> -
- - - -
-
-
- ( - - - - )} - /> -
-
- items.remove(index)} - > - - -
-
- ); - })} -
- {errors?.permissions?.[type]?.[position]?.conditions?.message && ( -
- - {errors?.permissions?.[type]?.[position]?.conditions?.message} -
- )} -
{}
-
- -
-
- ); -}; diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx similarity index 66% rename from frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx rename to frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx index 58c403579..cdf0f5151 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionPolicies.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx @@ -1,24 +1,14 @@ import { cloneElement } from "react"; import { Controller, useFieldArray, useFormContext } from "react-hook-form"; -import { - faChevronDown, - faChevronRight, - faInfoCircle, - faPlus, - faTrash -} from "@fortawesome/free-solid-svg-icons"; +import { faChevronDown, faChevronRight, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { twMerge } from "tailwind-merge"; -import { Button, Checkbox, Select, SelectItem, Tag, Tooltip } from "@app/components/v2"; +import { Button, Checkbox, Tag } from "@app/components/v2"; import { ProjectPermissionSub } from "@app/context"; import { useToggle } from "@app/hooks"; -import { - isConditionalSubjects, - TFormSchema, - TProjectPermissionObject -} from "../ProjectRoleModifySection.utils"; +import { TFormSchema, TProjectPermissionObject } from "../ProjectRoleModifySection.utils"; type Props = { title: string; @@ -28,7 +18,7 @@ type Props = { isDisabled?: boolean; }; -export const GeneralPermissionPolicies = >({ +export const GeneralPermissionOptions = >({ subject, actions, children, @@ -73,44 +63,6 @@ export const GeneralPermissionPolicies = {items.fields.map((el, rootIndex) => (
- {isConditionalSubjects(subject) && ( -
-
Permission
-
- ( - - )} - /> -
-
- -

- Whether to allow or forbid the selected actions when the following - conditions (if any) are met. -

-

Forbid rules must come after allow rules.

- - } - > - -
-
-
- )}
Actions
@@ -146,10 +98,10 @@ export const GeneralPermissionPolicies = - {!isDisabled && isConditionalSubjects(subject) && ( + {!isDisabled && subject === ProjectPermissionSub.Secrets && (
diff --git a/frontend/src/views/SecretMainPage/SecretMainPage.tsx b/frontend/src/views/SecretMainPage/SecretMainPage.tsx index 58d8d34d9..324fa9082 100644 --- a/frontend/src/views/SecretMainPage/SecretMainPage.tsx +++ b/frontend/src/views/SecretMainPage/SecretMainPage.tsx @@ -12,7 +12,6 @@ import { PermissionDeniedBanner } from "@app/components/permissions"; import { ContentLoader, Pagination } from "@app/components/v2"; import { ProjectPermissionActions, - ProjectPermissionDynamicSecretActions, ProjectPermissionSub, useProjectPermission, useWorkspace @@ -38,7 +37,7 @@ import { ActionBar } from "./components/ActionBar"; import { CreateSecretForm } from "./components/CreateSecretForm"; import { PitDrawer } from "./components/PitDrawer"; import { SecretDropzone } from "./components/SecretDropzone"; -import { SecretListView, SecretNoAccessListView } from "./components/SecretListView"; +import { SecretListView } from "./components/SecretListView"; import { SnapshotView } from "./components/SnapshotView"; import { StoreProvider } from "./SecretMainPage.store"; import { Filter, RowType } from "./SecretMainPage.types"; @@ -80,24 +79,8 @@ export const SecretMainPage = () => { const secretPath = (router.query.secretPath as string) || "/"; const canReadSecret = permission.can( ProjectPermissionActions.Read, - subject(ProjectPermissionSub.Secrets, { - environment, - secretPath, - secretName: "*", - secretTags: ["*"] - }) + subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); - - const canReadSecretImports = permission.can( - ProjectPermissionActions.Read, - subject(ProjectPermissionSub.SecretImports, { environment, secretPath }) - ); - - const canReadDynamicSecret = permission.can( - ProjectPermissionDynamicSecretActions.ReadRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath }) - ); - const canDoReadRollback = permission.can( ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback @@ -106,12 +89,11 @@ export const SecretMainPage = () => { const defaultFilterState = { tags: {}, searchFilter: (router.query.searchFilter as string) || "", - // these should always be on by default for the UI, they will be disabled for the query below based off permissions include: { [RowType.Folder]: true, - [RowType.Import]: true, - [RowType.DynamicSecret]: true, - [RowType.Secret]: true + [RowType.Import]: canReadSecret, + [RowType.DynamicSecret]: canReadSecret, + [RowType.Secret]: canReadSecret } }; @@ -119,6 +101,19 @@ export const SecretMainPage = () => { const [debouncedSearchFilter, setDebouncedSearchFilter] = useDebounce(filter.searchFilter); const [filterHistory, setFilterHistory] = useState>(new Map()); + // change filters if permissions change at different paths/env + useEffect(() => { + setFilter((prev) => ({ + ...prev, + include: { + [RowType.Folder]: true, + [RowType.Import]: canReadSecret, + [RowType.DynamicSecret]: canReadSecret, + [RowType.Secret]: canReadSecret + } + })); + }, [canReadSecret]); + useEffect(() => { if ( !isWorkspaceLoading && @@ -146,9 +141,9 @@ export const SecretMainPage = () => { orderBy, search: debouncedSearchFilter, orderDirection, - includeImports: canReadSecretImports && filter.include.import, + includeImports: canReadSecret && filter.include.import, includeFolders: filter.include.folder, - includeDynamicSecrets: canReadDynamicSecret && filter.include.dynamic, + includeDynamicSecrets: canReadSecret && filter.include.dynamic, includeSecrets: canReadSecret && filter.include.secret, tags: filter.tags }); @@ -210,20 +205,8 @@ export const SecretMainPage = () => { isPaused: !canDoReadRollback }); - const noAccessSecretCount = Math.max( - (page * perPage > totalCount ? totalCount % perPage : perPage) - - (imports?.length || 0) - - (folders?.length || 0) - - (secrets?.length || 0) - - (dynamicSecrets?.length || 0), - 0 - ); const isNotEmpty = Boolean( - secrets?.length || - folders?.length || - imports?.length || - dynamicSecrets?.length || - noAccessSecretCount + secrets?.length || folders?.length || imports?.length || dynamicSecrets?.length ); const handleSortToggle = () => @@ -315,6 +298,7 @@ export const SecretMainPage = () => { setFilter(defaultFilterState); setDebouncedSearchFilter(""); }; + return (
@@ -378,7 +362,7 @@ export const SecretMainPage = () => {
Value
)} - {canReadSecretImports && Boolean(imports?.length) && ( + {canReadSecret && imports?.length && ( { importedSecrets={importedSecrets} /> )} - {Boolean(folders?.length) && ( + {folders?.length && ( { onNavigateToFolder={handleResetFilter} /> )} - {canReadDynamicSecret && Boolean(dynamicSecrets?.length) && ( + {canReadSecret && dynamicSecrets?.length && ( { dynamicSecrets={dynamicSecrets} /> )} - {canReadSecret && Boolean(secrets?.length) && ( + {canReadSecret && secrets?.length && ( { isProtectedBranch={isProtectedBranch} /> )} - {canReadSecret && } - {!canReadSecret && - !canReadDynamicSecret && - !canReadSecretImports && - folders?.length === 0 && } + {!canReadSecret && folders?.length === 0 && }
{!isDetailsLoading && totalCount > 0 && ( diff --git a/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx b/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx index 353ae3b65..333f5f0c6 100644 --- a/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx +++ b/frontend/src/views/SecretMainPage/components/ActionBar/ActionBar.tsx @@ -47,8 +47,8 @@ import { } from "@app/components/v2"; import { ProjectPermissionActions, - ProjectPermissionDynamicSecretActions, ProjectPermissionSub, + useProjectPermission, useSubscription } from "@app/context"; import { usePopUp } from "@app/hooks"; @@ -125,6 +125,12 @@ export const ActionBar = ({ const { reset: resetSelectedSecret } = useSelectedSecretActions(); const isMultiSelectActive = Boolean(Object.keys(selectedSecrets).length); + const { permission } = useProjectPermission(); + + const shouldCheckFolderPermission = permission.rules.some((rule) => + (rule.subject as ProjectPermissionSub[]).includes(ProjectPermissionSub.SecretFolders) + ); + const handleFolderCreate = async (folderName: string) => { try { await createFolder({ @@ -432,12 +438,7 @@ export const ActionBar = ({
{(isAllowed) => ( - )} - + diff --git a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx index 8953ab2bc..abef7b6c3 100644 --- a/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx +++ b/frontend/src/views/SecretMainPage/components/DynamicSecretListView/DynamicSecretListView.tsx @@ -18,7 +18,7 @@ import { Tag, Tooltip } from "@app/components/v2"; -import { ProjectPermissionDynamicSecretActions, ProjectPermissionSub } from "@app/context"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context"; import { usePopUp } from "@app/hooks"; import { useDeleteDynamicSecret } from "@app/hooks/api"; import { @@ -132,27 +132,17 @@ export const DynamicSecretListView = ({ )}
- { + evt.stopPropagation(); + handlePopUpOpen("createDynamicSecretLease", secret); + }} > - {(isAllowed) => ( - - )} - - + Generate + {secret.status === DynamicSecretStatus.FailedDeletion && ( @@ -419,12 +388,7 @@ export const SecretDetailSidebar = ({ render={({ field: { value, onChange, onBlur } }) => ( {(isAllowed) => ( {(isAllowed) => (
- + {(isAllowed) => ( { )}
- + {(isAllowed) => (