diff --git a/backend/src/helpers/secrets.ts b/backend/src/helpers/secrets.ts index beacf709d..f6252d5c6 100644 --- a/backend/src/helpers/secrets.ts +++ b/backend/src/helpers/secrets.ts @@ -49,7 +49,7 @@ import { import { TelemetryService } from "../services"; import { client, getEncryptionKey, getRootEncryptionKey } from "../config"; import { EEAuditLogService, EELogService, EESecretService } from "../ee/services"; -import { getAuthDataPayloadIdObj, getAuthDataPayloadUserObj } from "../utils/authn/authDataExtractors"; +import { getAuthDataPayloadIdObj, getAuthDataPayloadUserObj } from "../utils/authn/helpers"; import { getFolderByPath, getFolderIdFromServiceToken } from "../services/FolderService"; import picomatch from "picomatch"; import path from "path"; diff --git a/backend/src/middleware/requireAuth.ts b/backend/src/middleware/requireAuth.ts index 87672feb9..929d22fea 100644 --- a/backend/src/middleware/requireAuth.ts +++ b/backend/src/middleware/requireAuth.ts @@ -2,7 +2,7 @@ import jwt from "jsonwebtoken"; import { NextFunction, Request, Response } from "express"; import { AuthMode } from "../variables"; import { AuthData } from "../interfaces/middleware"; -import { extractAuthMode, getAuthData } from "../utils/authn/authMode"; +import { extractAuthMode, getAuthData } from "../utils/authn/helpers"; import { UnauthorizedRequestError } from "../utils/errors"; declare module "jsonwebtoken" { diff --git a/backend/src/utils/authn/authDataExtractors/index.ts b/backend/src/utils/authn/authDataExtractors/index.ts deleted file mode 100644 index 89c1f419e..000000000 --- a/backend/src/utils/authn/authDataExtractors/index.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { AuthData } from "../../../interfaces/middleware"; -import { - ServiceAccount, - ServiceTokenData, - ServiceTokenDataV3, - User -} from "../../../models"; - -/** - * Returns an object containing the id of the authentication data payload - * @param {AuthData} authData - authentication data object - * @returns - */ -export const getAuthDataPayloadIdObj = (authData: AuthData) => { - if (authData.authPayload instanceof User) { - return { userId: authData.authPayload._id }; - } - - if (authData.authPayload instanceof ServiceAccount) { - return { serviceAccountId: authData.authPayload._id }; - } - - if (authData.authPayload instanceof ServiceTokenData) { - return { serviceTokenDataId: authData.authPayload._id }; - } - - if (authData.authPayload instanceof ServiceTokenDataV3) { - return { serviceTokenDataId: authData.authPayload._id }; - } -}; - -/** - * Returns an object containing the user associated with the authentication data payload - * @param {AuthData} authData - authentication data object - * @returns - */ -export const getAuthDataPayloadUserObj = (authData: AuthData) => { - if (authData.authPayload instanceof User) { - return { user: authData.authPayload._id }; - } - - if (authData.authPayload instanceof ServiceAccount) { - return { user: authData.authPayload.user }; - } - - if (authData.authPayload instanceof ServiceTokenData) { - return { user: authData.authPayload.user }; - } - - if (authData.authPayload instanceof ServiceTokenDataV3) { - return { user: authData.authPayload.user }; - } -} \ No newline at end of file diff --git a/backend/src/utils/authn/authMode/index.ts b/backend/src/utils/authn/authMode/index.ts deleted file mode 100644 index 7d7262551..000000000 --- a/backend/src/utils/authn/authMode/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - extractAuthMode, - getAuthData -} from "./helpers"; \ No newline at end of file diff --git a/backend/src/utils/authn/authMode/apiKey.ts b/backend/src/utils/authn/authModeValidators/apiKey.ts similarity index 100% rename from backend/src/utils/authn/authMode/apiKey.ts rename to backend/src/utils/authn/authModeValidators/apiKey.ts diff --git a/backend/src/utils/authn/authMode/apiKeyV2.ts b/backend/src/utils/authn/authModeValidators/apiKeyV2.ts similarity index 100% rename from backend/src/utils/authn/authMode/apiKeyV2.ts rename to backend/src/utils/authn/authModeValidators/apiKeyV2.ts diff --git a/backend/src/utils/authn/authModeValidators/index.ts b/backend/src/utils/authn/authModeValidators/index.ts new file mode 100644 index 000000000..0ac4c3c1c --- /dev/null +++ b/backend/src/utils/authn/authModeValidators/index.ts @@ -0,0 +1,5 @@ +export * from "./apiKey"; +export * from "./apiKeyV2"; +export * from "./jwt"; +export * from "./serviceTokenV2"; +export * from "./serviceTokenV3"; \ No newline at end of file diff --git a/backend/src/utils/authn/authMode/jwt.ts b/backend/src/utils/authn/authModeValidators/jwt.ts similarity index 100% rename from backend/src/utils/authn/authMode/jwt.ts rename to backend/src/utils/authn/authModeValidators/jwt.ts diff --git a/backend/src/utils/authn/authMode/serviceTokenV2.ts b/backend/src/utils/authn/authModeValidators/serviceTokenV2.ts similarity index 100% rename from backend/src/utils/authn/authMode/serviceTokenV2.ts rename to backend/src/utils/authn/authModeValidators/serviceTokenV2.ts diff --git a/backend/src/utils/authn/authMode/serviceTokenV3.ts b/backend/src/utils/authn/authModeValidators/serviceTokenV3.ts similarity index 100% rename from backend/src/utils/authn/authMode/serviceTokenV3.ts rename to backend/src/utils/authn/authModeValidators/serviceTokenV3.ts diff --git a/backend/src/utils/authn/helpers/authDataExtractors.ts b/backend/src/utils/authn/helpers/authDataExtractors.ts new file mode 100644 index 000000000..60639739e --- /dev/null +++ b/backend/src/utils/authn/helpers/authDataExtractors.ts @@ -0,0 +1,53 @@ +import { AuthData } from "../../../interfaces/middleware"; +import { + ServiceAccount, + ServiceTokenData, + ServiceTokenDataV3, + User +} from "../../../models"; + +/** + * Returns an object containing the id of the authentication data payload + * @param {AuthData} authData - authentication data object + * @returns + */ + export const getAuthDataPayloadIdObj = (authData: AuthData) => { + if (authData.authPayload instanceof User) { + return { userId: authData.authPayload._id }; + } + + if (authData.authPayload instanceof ServiceAccount) { + return { serviceAccountId: authData.authPayload._id }; + } + + if (authData.authPayload instanceof ServiceTokenData) { + return { serviceTokenDataId: authData.authPayload._id }; + } + + if (authData.authPayload instanceof ServiceTokenDataV3) { + return { serviceTokenDataId: authData.authPayload._id }; + } +}; + +/** + * Returns an object containing the user associated with the authentication data payload + * @param {AuthData} authData - authentication data object + * @returns + */ +export const getAuthDataPayloadUserObj = (authData: AuthData) => { + if (authData.authPayload instanceof User) { + return { user: authData.authPayload._id }; + } + + if (authData.authPayload instanceof ServiceAccount) { + return { user: authData.authPayload.user }; + } + + if (authData.authPayload instanceof ServiceTokenData) { + return { user: authData.authPayload.user }; + } + + if (authData.authPayload instanceof ServiceTokenDataV3) { + return { user: authData.authPayload.user }; + } +} \ No newline at end of file diff --git a/backend/src/utils/authn/authMode/helpers.ts b/backend/src/utils/authn/helpers/index.ts similarity index 95% rename from backend/src/utils/authn/authMode/helpers.ts rename to backend/src/utils/authn/helpers/index.ts index ecb852f61..064efe133 100644 --- a/backend/src/utils/authn/authMode/helpers.ts +++ b/backend/src/utils/authn/helpers/index.ts @@ -1,15 +1,19 @@ +import { AuthData } from "../../../interfaces/middleware"; import jwt from "jsonwebtoken"; import { getAuthSecret } from "../../../config"; import { ActorType } from "../../../ee/models"; import { AuthMode, AuthTokenType } from "../../../variables"; import { UnauthorizedRequestError } from "../../errors"; -import { validateAPIKey } from "./apiKey"; -import { validateAPIKeyV2 } from "./apiKeyV2"; -import { validateServiceTokenV2 } from "./serviceTokenV2"; -import { validateServiceTokenV3 } from "./serviceTokenV3"; -import { validateJWT } from "./jwt"; +import { + validateAPIKey, + validateAPIKeyV2, + validateJWT, + validateServiceTokenV2, + validateServiceTokenV3 +} from "../authModeValidators"; import { getUserAgentType } from "../../posthog"; -import { AuthData } from "../../../interfaces/middleware"; + +export * from "./authDataExtractors"; interface ExtractAuthModeParams { headers: { [key: string]: string | string[] | undefined } diff --git a/frontend/src/views/Settings/PersonalSettingsPage/PersonalAPIKeyTab/PersonalAPIKeyTab.tsx b/frontend/src/views/Settings/PersonalSettingsPage/PersonalAPIKeyTab/PersonalAPIKeyTab.tsx index 035f0b322..aba48b23e 100644 --- a/frontend/src/views/Settings/PersonalSettingsPage/PersonalAPIKeyTab/PersonalAPIKeyTab.tsx +++ b/frontend/src/views/Settings/PersonalSettingsPage/PersonalAPIKeyTab/PersonalAPIKeyTab.tsx @@ -1,10 +1,10 @@ import { APIKeySection } from "../APIKeySection"; -import { APIKeyV2Section } from "../APIKeyV2Section"; +// import { APIKeyV2Section } from "../APIKeyV2Section"; export const PersonalAPIKeyTab = () => { return ( <> - + {/* */} > ); diff --git a/frontend/src/views/Settings/ProjectSettingsPage/components/ProjectServiceTokensTab/ProjectServiceTokensTab.tsx b/frontend/src/views/Settings/ProjectSettingsPage/components/ProjectServiceTokensTab/ProjectServiceTokensTab.tsx index 12312dc78..d4f8e79e7 100644 --- a/frontend/src/views/Settings/ProjectSettingsPage/components/ProjectServiceTokensTab/ProjectServiceTokensTab.tsx +++ b/frontend/src/views/Settings/ProjectSettingsPage/components/ProjectServiceTokensTab/ProjectServiceTokensTab.tsx @@ -1,10 +1,10 @@ import { ServiceTokenSection } from "../ServiceTokenSection"; -import { ServiceTokenV3Section } from "../ServiceTokenV3Section"; +// import { ServiceTokenV3Section } from "../ServiceTokenV3Section"; export const ProjectServiceTokensTab = () => { return ( <> - + {/* */} > ); diff --git a/frontend/src/views/Settings/ProjectSettingsPage/components/ServiceTokenV3Section/AddServiceTokenV3Modal.tsx b/frontend/src/views/Settings/ProjectSettingsPage/components/ServiceTokenV3Section/AddServiceTokenV3Modal.tsx index c1779b19e..3d76b2435 100644 --- a/frontend/src/views/Settings/ProjectSettingsPage/components/ServiceTokenV3Section/AddServiceTokenV3Modal.tsx +++ b/frontend/src/views/Settings/ProjectSettingsPage/components/ServiceTokenV3Section/AddServiceTokenV3Modal.tsx @@ -1,11 +1,13 @@ import { useEffect, useState } from "react"; import { Controller, useFieldArray, useForm } from "react-hook-form"; -import { faPlus, faXmark, faCheck, faCopy } from "@fortawesome/free-solid-svg-icons"; +import { faCheck, faCopy,faPlus, faXmark } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { yupResolver } from "@hookform/resolvers/yup"; +import { motion } from "framer-motion"; import nacl from "tweetnacl"; import { encodeBase64 } from "tweetnacl-util"; import * as yup from "yup"; + import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { decryptAssymmetric, @@ -21,8 +23,11 @@ import { Select, SelectItem, Switch, - UpgradePlanModal -} from "@app/components/v2"; + Tab, + TabList, + TabPanel, + Tabs, + UpgradePlanModal} from "@app/components/v2"; import { useSubscription, useWorkspace @@ -42,6 +47,11 @@ import { } from "@app/hooks/api/serviceTokens/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; +enum TabSections { + General = "general", + Advanced = "advanced" +} + const expirations = [ { label: "Never", value: "" }, { label: "1 day", value: "86400" }, @@ -343,246 +353,269 @@ export const AddServiceTokenV3Modal = ({ {!hasServiceTokenJSON ? ( - ( - + + + General + Advanced + + + + - - - )} - /> - {tokenScopes.map(({ id }, index) => ( - - ( - - onChange(e)} - className="w-36" - > - - Read - - - Read & Write - - - - )} - /> - ( - - onChange(e)} - className="w-36" - > - {currentWorkspace?.environments.map(({ name, slug }) => ( - - {name} - - ))} - - - )} - /> - ( - - - - )} - /> - remove(index)} - size="lg" - colorSchema="danger" - variant="plain" - ariaLabel="update" - className="p-3" - > - - - - ))} - - - append({ - permission: "read", - environment: currentWorkspace?.environments?.[0]?.slug || "", - secretPath: "/" - }) - } - leftIcon={} - size="xs" - > - Add Scope - - - {tokenTrustedIps.map(({ id }, index) => ( - - { - return ( + ( { + {...field} + placeholder="My ST V3" + /> + + )} + /> + {tokenScopes.map(({ id }, index) => ( + + ( + + onChange(e)} + className="w-36" + > + + Read + + + Read & Write + + + + )} + /> + ( + + onChange(e)} + className="w-36" + > + {currentWorkspace?.environments.map(({ name, slug }) => ( + + {name} + + ))} + + + )} + /> + ( + + + + )} + /> + remove(index)} + size="lg" + colorSchema="danger" + variant="plain" + ariaLabel="update" + className="p-3" + > + + + + ))} + + + append({ + permission: "read", + environment: currentWorkspace?.environments?.[0]?.slug || "", + secretPath: "/" + }) + } + leftIcon={} + size="xs" + > + Add Scope + + + ( + + onChange(e)} + className="w-full" + > + {expirations.map(({ label, value }) => ( + + {label} + + ))} + + + )} + /> + + + + + {tokenTrustedIps.map(({ id }, index) => ( + + { + return ( + + { + if (subscription?.ipAllowlisting) { + field.onChange(e); + return; + } + + handlePopUpOpen("upgradePlan"); + }} + placeholder="123.456.789.0" + /> + + ); + }} + /> + { if (subscription?.ipAllowlisting) { - field.onChange(e); + removeTrustedIp(index); return; } handlePopUpOpen("upgradePlan"); }} - placeholder="123.456.789.0" + size="lg" + colorSchema="danger" + variant="plain" + ariaLabel="update" + className="p-3" + > + + + + ))} + + { + if (subscription?.ipAllowlisting) { + appendTrustedIp({ + ipAddress: "0.0.0.0/0" + }) + return; + } + + handlePopUpOpen("upgradePlan"); + }} + leftIcon={} + size="xs" + > + Add IP Address + + + ( + + - ); - }} - /> - { - if (subscription?.ipAllowlisting) { - removeTrustedIp(index); - return; - } - - handlePopUpOpen("upgradePlan"); - }} - size="lg" - colorSchema="danger" - variant="plain" - ariaLabel="update" - className="p-3" - > - - - - ))} - - { - if (subscription?.ipAllowlisting) { - appendTrustedIp({ - ipAddress: "0.0.0.0/0" - }) - return; - } - - handlePopUpOpen("upgradePlan"); - }} - leftIcon={} - size="xs" - > - Add IP Address - - - ( - - onChange(e)} - className="w-full" - > - {expirations.map(({ label, value }) => ( - - {label} - - ))} - - - )} - /> - ( - - - - )} - /> - - ( - onChange(isChecked)} - isChecked={value} - > - Refresh Token Rotation - - )} - /> - - + )} + /> + + ( + onChange(isChecked)} + isChecked={value} + > + Refresh Token Rotation + + )} + /> + When enabled, as a result of exchanging a refresh token, a new refresh token will be issued and the existing token will be invalidated. + + + + +
When enabled, as a result of exchanging a refresh token, a new refresh token will be issued and the existing token will be invalidated.