mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-09 03:28:15 +00:00
Split ST V3 modal into option tabs, re-modularized authn methods
This commit is contained in:
@@ -49,7 +49,7 @@ import {
|
|||||||
import { TelemetryService } from "../services";
|
import { TelemetryService } from "../services";
|
||||||
import { client, getEncryptionKey, getRootEncryptionKey } from "../config";
|
import { client, getEncryptionKey, getRootEncryptionKey } from "../config";
|
||||||
import { EEAuditLogService, EELogService, EESecretService } from "../ee/services";
|
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 { getFolderByPath, getFolderIdFromServiceToken } from "../services/FolderService";
|
||||||
import picomatch from "picomatch";
|
import picomatch from "picomatch";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import jwt from "jsonwebtoken";
|
|||||||
import { NextFunction, Request, Response } from "express";
|
import { NextFunction, Request, Response } from "express";
|
||||||
import { AuthMode } from "../variables";
|
import { AuthMode } from "../variables";
|
||||||
import { AuthData } from "../interfaces/middleware";
|
import { AuthData } from "../interfaces/middleware";
|
||||||
import { extractAuthMode, getAuthData } from "../utils/authn/authMode";
|
import { extractAuthMode, getAuthData } from "../utils/authn/helpers";
|
||||||
import { UnauthorizedRequestError } from "../utils/errors";
|
import { UnauthorizedRequestError } from "../utils/errors";
|
||||||
|
|
||||||
declare module "jsonwebtoken" {
|
declare module "jsonwebtoken" {
|
||||||
|
|||||||
@@ -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 };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export {
|
|
||||||
extractAuthMode,
|
|
||||||
getAuthData
|
|
||||||
} from "./helpers";
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export * from "./apiKey";
|
||||||
|
export * from "./apiKeyV2";
|
||||||
|
export * from "./jwt";
|
||||||
|
export * from "./serviceTokenV2";
|
||||||
|
export * from "./serviceTokenV3";
|
||||||
@@ -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 };
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-6
@@ -1,15 +1,19 @@
|
|||||||
|
import { AuthData } from "../../../interfaces/middleware";
|
||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
import { getAuthSecret } from "../../../config";
|
import { getAuthSecret } from "../../../config";
|
||||||
import { ActorType } from "../../../ee/models";
|
import { ActorType } from "../../../ee/models";
|
||||||
import { AuthMode, AuthTokenType } from "../../../variables";
|
import { AuthMode, AuthTokenType } from "../../../variables";
|
||||||
import { UnauthorizedRequestError } from "../../errors";
|
import { UnauthorizedRequestError } from "../../errors";
|
||||||
import { validateAPIKey } from "./apiKey";
|
import {
|
||||||
import { validateAPIKeyV2 } from "./apiKeyV2";
|
validateAPIKey,
|
||||||
import { validateServiceTokenV2 } from "./serviceTokenV2";
|
validateAPIKeyV2,
|
||||||
import { validateServiceTokenV3 } from "./serviceTokenV3";
|
validateJWT,
|
||||||
import { validateJWT } from "./jwt";
|
validateServiceTokenV2,
|
||||||
|
validateServiceTokenV3
|
||||||
|
} from "../authModeValidators";
|
||||||
import { getUserAgentType } from "../../posthog";
|
import { getUserAgentType } from "../../posthog";
|
||||||
import { AuthData } from "../../../interfaces/middleware";
|
|
||||||
|
export * from "./authDataExtractors";
|
||||||
|
|
||||||
interface ExtractAuthModeParams {
|
interface ExtractAuthModeParams {
|
||||||
headers: { [key: string]: string | string[] | undefined }
|
headers: { [key: string]: string | string[] | undefined }
|
||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
import { APIKeySection } from "../APIKeySection";
|
import { APIKeySection } from "../APIKeySection";
|
||||||
import { APIKeyV2Section } from "../APIKeyV2Section";
|
// import { APIKeyV2Section } from "../APIKeyV2Section";
|
||||||
|
|
||||||
export const PersonalAPIKeyTab = () => {
|
export const PersonalAPIKeyTab = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<APIKeyV2Section />
|
{/* <APIKeyV2Section /> */}
|
||||||
<APIKeySection />
|
<APIKeySection />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
import { ServiceTokenSection } from "../ServiceTokenSection";
|
import { ServiceTokenSection } from "../ServiceTokenSection";
|
||||||
import { ServiceTokenV3Section } from "../ServiceTokenV3Section";
|
// import { ServiceTokenV3Section } from "../ServiceTokenV3Section";
|
||||||
|
|
||||||
export const ProjectServiceTokensTab = () => {
|
export const ProjectServiceTokensTab = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ServiceTokenV3Section />
|
{/* <ServiceTokenV3Section /> */}
|
||||||
<ServiceTokenSection />
|
<ServiceTokenSection />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
+64
-31
@@ -1,11 +1,13 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { Controller, useFieldArray, useForm } from "react-hook-form";
|
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 { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
import { motion } from "framer-motion";
|
||||||
import nacl from "tweetnacl";
|
import nacl from "tweetnacl";
|
||||||
import { encodeBase64 } from "tweetnacl-util";
|
import { encodeBase64 } from "tweetnacl-util";
|
||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
|
|
||||||
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
||||||
import {
|
import {
|
||||||
decryptAssymmetric,
|
decryptAssymmetric,
|
||||||
@@ -21,8 +23,11 @@ import {
|
|||||||
Select,
|
Select,
|
||||||
SelectItem,
|
SelectItem,
|
||||||
Switch,
|
Switch,
|
||||||
UpgradePlanModal
|
Tab,
|
||||||
} from "@app/components/v2";
|
TabList,
|
||||||
|
TabPanel,
|
||||||
|
Tabs,
|
||||||
|
UpgradePlanModal} from "@app/components/v2";
|
||||||
import {
|
import {
|
||||||
useSubscription,
|
useSubscription,
|
||||||
useWorkspace
|
useWorkspace
|
||||||
@@ -42,6 +47,11 @@ import {
|
|||||||
} from "@app/hooks/api/serviceTokens/types";
|
} from "@app/hooks/api/serviceTokens/types";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
|
enum TabSections {
|
||||||
|
General = "general",
|
||||||
|
Advanced = "advanced"
|
||||||
|
}
|
||||||
|
|
||||||
const expirations = [
|
const expirations = [
|
||||||
{ label: "Never", value: "" },
|
{ label: "Never", value: "" },
|
||||||
{ label: "1 day", value: "86400" },
|
{ label: "1 day", value: "86400" },
|
||||||
@@ -343,6 +353,21 @@ export const AddServiceTokenV3Modal = ({
|
|||||||
<ModalContent title={`${popUp?.serviceTokenV3?.data ? "Update" : "Create"} Service Token V3`}>
|
<ModalContent title={`${popUp?.serviceTokenV3?.data ? "Update" : "Create"} Service Token V3`}>
|
||||||
{!hasServiceTokenJSON ? (
|
{!hasServiceTokenJSON ? (
|
||||||
<form onSubmit={handleSubmit(onFormSubmit)}>
|
<form onSubmit={handleSubmit(onFormSubmit)}>
|
||||||
|
<Tabs defaultValue={TabSections.General}>
|
||||||
|
<TabList>
|
||||||
|
<div className="flex flex-row border-b border-mineshaft-600 w-full">
|
||||||
|
<Tab value={TabSections.General}>General</Tab>
|
||||||
|
<Tab value={TabSections.Advanced}>Advanced</Tab>
|
||||||
|
</div>
|
||||||
|
</TabList>
|
||||||
|
<TabPanel value={TabSections.General}>
|
||||||
|
<motion.div
|
||||||
|
key="panel-1"
|
||||||
|
transition={{ duration: 0.15 }}
|
||||||
|
initial={{ opacity: 0, translateX: 30 }}
|
||||||
|
animate={{ opacity: 1, translateX: 0 }}
|
||||||
|
exit={{ opacity: 0, translateX: 30 }}
|
||||||
|
>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue=""
|
defaultValue=""
|
||||||
@@ -456,6 +481,36 @@ export const AddServiceTokenV3Modal = ({
|
|||||||
Add Scope
|
Add Scope
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="expiresIn"
|
||||||
|
defaultValue=""
|
||||||
|
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label={`${popUp?.serviceTokenV3?.data ? "Update" : ""} Refresh Token Expires In`}
|
||||||
|
errorText={error?.message}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
className="mt-4"
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
defaultValue={field.value}
|
||||||
|
{...field}
|
||||||
|
onValueChange={(e) => onChange(e)}
|
||||||
|
className="w-full"
|
||||||
|
>
|
||||||
|
{expirations.map(({ label, value }) => (
|
||||||
|
<SelectItem value={String(value || "")} key={`api-key-expiration-${label}`}>
|
||||||
|
{label}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel value={TabSections.Advanced}>
|
||||||
|
<div>
|
||||||
{tokenTrustedIps.map(({ id }, index) => (
|
{tokenTrustedIps.map(({ id }, index) => (
|
||||||
<div className="flex items-end space-x-2 mb-3" key={id}>
|
<div className="flex items-end space-x-2 mb-3" key={id}>
|
||||||
<Controller
|
<Controller
|
||||||
@@ -524,32 +579,6 @@ export const AddServiceTokenV3Modal = ({
|
|||||||
Add IP Address
|
Add IP Address
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="expiresIn"
|
|
||||||
defaultValue=""
|
|
||||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => (
|
|
||||||
<FormControl
|
|
||||||
label={`${popUp?.serviceTokenV3?.data ? "Update" : ""} Refresh Token Expires In`}
|
|
||||||
errorText={error?.message}
|
|
||||||
isError={Boolean(error)}
|
|
||||||
className="mt-4"
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
defaultValue={field.value}
|
|
||||||
{...field}
|
|
||||||
onValueChange={(e) => onChange(e)}
|
|
||||||
className="w-full"
|
|
||||||
>
|
|
||||||
{expirations.map(({ label, value }) => (
|
|
||||||
<SelectItem value={String(value || "")} key={`api-key-expiration-${label}`}>
|
|
||||||
{label}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue="7200"
|
defaultValue="7200"
|
||||||
@@ -567,7 +596,7 @@ export const AddServiceTokenV3Modal = ({
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<div className="mt-8 mb-[2.36rem]">
|
<div className="mt-8">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="isRefreshTokenRotationEnabled"
|
name="isRefreshTokenRotationEnabled"
|
||||||
@@ -581,8 +610,12 @@ export const AddServiceTokenV3Modal = ({
|
|||||||
</Switch>
|
</Switch>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<p className="mt-4 text-sm font-normal text-mineshaft-400">When enabled, as a result of exchanging a refresh token, a new refresh token will be issued and the existing token will be invalidated.</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-8 flex items-center">
|
</div>
|
||||||
|
</TabPanel>
|
||||||
|
</Tabs>
|
||||||
|
<div className="flex items-center">
|
||||||
<Button
|
<Button
|
||||||
className="mr-4"
|
className="mr-4"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
Reference in New Issue
Block a user