feat: updated pr by review changes

This commit is contained in:
=
2025-12-19 14:28:04 +05:30
parent be83592f16
commit fa52dca642
12 changed files with 172 additions and 17 deletions

View File

@@ -16,7 +16,9 @@ import { SecretNameSchema } from "@app/server/lib/schemas";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
export const MongoDBCredentialsRotationGeneratedCredentialsSchema = SqlCredentialsRotationGeneratedCredentialsSchema;
export const MongoDBCredentialsRotationParametersSchema = SqlCredentialsRotationParametersSchema;
export const MongoDBCredentialsRotationParametersSchema = SqlCredentialsRotationParametersSchema.omit({
rotationStatement: true
});
export const MongoDBCredentialsRotationTemplateSchema = SqlCredentialsRotationTemplateSchema.omit({
rotationStatement: true
});

View File

@@ -89,6 +89,22 @@ export const sqlCredentialsRotationFactory: TRotationFactory<
}
};
const $executeQuery = async (tx: Knex, username: string, password: string) => {
if (userProvidedRotationStatement) {
const revokeStatement = handlebars.compile(userProvidedRotationStatement)({
username,
password,
database: connection.credentials.database
});
const queries = revokeStatement.toString().split(";").filter(Boolean);
for await (const query of queries) {
await tx.raw(query);
}
} else {
await tx.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app]({ username, password }));
}
};
const issueCredentials: TRotationFactoryIssueCredentials<TSqlCredentialsRotationGeneratedCredentials> = async (
callback
) => {
@@ -103,19 +119,7 @@ export const sqlCredentialsRotationFactory: TRotationFactory<
await executeOperation(async (client) => {
await client.transaction(async (tx) => {
for await (const credentials of credentialsSet) {
if (userProvidedRotationStatement) {
const revokeStatement = handlebars.compile(userProvidedRotationStatement)({
username: credentials.username,
password: credentials.password,
database: connection.credentials.database
});
const queries = revokeStatement.toString().split(";").filter(Boolean);
for await (const query of queries) {
await tx.raw(query);
}
} else {
await tx.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app](credentials));
}
await $executeQuery(tx, credentials.username, credentials.password);
}
});
});
@@ -144,7 +148,7 @@ export const sqlCredentialsRotationFactory: TRotationFactory<
await client.transaction(async (tx) => {
for await (const credentials of revokedCredentials) {
// invalidate previous passwords
await tx.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app](credentials));
await $executeQuery(tx, credentials.username, credentials.password);
}
});
});
@@ -167,7 +171,7 @@ export const sqlCredentialsRotationFactory: TRotationFactory<
try {
await executeOperation(async (client) => {
await client.raw(...SQL_CONNECTION_ALTER_LOGIN_STATEMENT[connection.app](credentials));
await $executeQuery(client, credentials.username, credentials.password);
});
} catch (error) {
throw new Error(redactPasswords(error, [credentials]));

View File

@@ -56,6 +56,8 @@ An example creation statement might look like:
- **Database Username 1** - the username of the first user that will be used for rotation.
- **Database Username 2** - the username of the second user that will be used for rotation.
![Rotation Advance Parameters](/images/secret-rotations-v2/mssql-credentials/mssql-credentials-advance-parameters.png)
- **Rotation Statement** - the template string query to generate password for the rotated user.
- **Password Requirements** - the requirements for the password of the MySQL users that will be created for the rotation.

View File

@@ -60,6 +60,8 @@ description: "Learn how to automatically rotate Oracle Database credentials."
<Note>
If your Oracle usernames were created without "quotes", Oracle sees them as UPPERCASE. Please use UPPERCASE for those names in the fields above.
</Note>
![Rotation Advance Parameters](/images/secret-rotations-v2/oracledb-credentials/oracledb-credentials-advance-parameters.png)
- **Rotation Statement** - the template string query to generate password for the rotated user.
- **Password Requirements** - the requirements for the password of the MySQL users that will be created for the rotation.

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 837 KiB

After

Width:  |  Height:  |  Size: 563 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 712 KiB

After

Width:  |  Height:  |  Size: 531 KiB

View File

@@ -0,0 +1,66 @@
import { Controller, useFormContext } from "react-hook-form";
import { TSecretRotationV2Form } from "@app/components/secret-rotations-v2/forms/schemas";
import { FormControl, Input } from "@app/components/v2";
import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2";
import { SecretRotation, useSecretRotationV2Option } from "@app/hooks/api/secretRotationsV2";
export const MongoRotationParametersFields = () => {
const { control, watch } = useFormContext<
TSecretRotationV2Form & {
type: SecretRotation.MongoDBCredentials;
}
>();
const type = watch("type");
const { rotationOption } = useSecretRotationV2Option(type);
return (
<>
<Controller
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
isError={Boolean(error)}
errorText={error?.message}
label="Database Username 1"
>
<Input value={value} onChange={onChange} placeholder="infisical_user_1" />
</FormControl>
)}
control={control}
name="parameters.username1"
/>
<Controller
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl
isError={Boolean(error)}
errorText={error?.message}
label="Database Username 2"
>
<Input value={value} onChange={onChange} placeholder="infisical_user_2" />
</FormControl>
)}
control={control}
name="parameters.username2"
/>
<NoticeBannerV2 title="Example Create User Statement">
<p className="mb-3 text-sm text-mineshaft-300">
Infisical requires two database users to be created for rotation.
</p>
<p className="mb-3 text-sm text-mineshaft-300">
These users are intended to be solely managed by Infisical. Altering their login after
rotation may cause unexpected failure.
</p>
<p className="mb-3 text-sm text-mineshaft-300">
Below is an example statement for creating the required users. You may need to modify it
to suit your needs.
</p>
<p className="mb-3 text-sm">
<pre className="max-h-40 overflow-y-auto rounded-sm border border-mineshaft-700 bg-mineshaft-800 p-2 whitespace-pre-wrap text-mineshaft-300">
{rotationOption!.template.createUserStatement}
</pre>
</p>
</NoticeBannerV2>
</>
);
};

View File

@@ -7,6 +7,7 @@ import { Auth0ClientSecretRotationParametersFields } from "./Auth0ClientSecretRo
import { AwsIamUserSecretRotationParametersFields } from "./AwsIamUserSecretRotationParametersFields";
import { AzureClientSecretRotationParametersFields } from "./AzureClientSecretRotationParametersFields";
import { LdapPasswordRotationParametersFields } from "./LdapPasswordRotationParametersFields";
import { MongoRotationParametersFields } from "./MongoRotationParametersFields";
import { OktaClientSecretRotationParametersFields } from "./OktaClientSecretRotationParametersFields";
import { RedisCredentialsRotationParametersFields } from "./RedisCredentialsRotationParametersFields";
import { SqlCredentialsRotationParametersFields } from "./shared";
@@ -22,7 +23,7 @@ const COMPONENT_MAP: Record<SecretRotation, React.FC> = {
[SecretRotation.AwsIamUserSecret]: AwsIamUserSecretRotationParametersFields,
[SecretRotation.OktaClientSecret]: OktaClientSecretRotationParametersFields,
[SecretRotation.RedisCredentials]: RedisCredentialsRotationParametersFields,
[SecretRotation.MongoDBCredentials]: SqlCredentialsRotationParametersFields
[SecretRotation.MongoDBCredentials]: MongoRotationParametersFields
};
export const SecretRotationV2ParametersFields = () => {

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -e
CONTAINER_NAME="mssql"
SA_PASSWORD="StrongP@ssw0rd!"
IMAGE="mcr.microsoft.com/mssql/server:2022-latest"
echo "🚀 Starting SQL Server 2022 container..."
docker run -d \
--platform=linux/amd64 \
--name "${CONTAINER_NAME}" \
-p 1433:1433 \
-e "ACCEPT_EULA=Y" \
-e "SA_PASSWORD=${SA_PASSWORD}" \
"${IMAGE}"
echo "⏳ Waiting for SQL Server to be ready..."
# Check logs for ready message
until docker logs "${CONTAINER_NAME}" 2>&1 | grep -q "SQL Server is now ready for client connections."; do
sleep 5
done
echo ""
echo "✅ SQL Server is ready!"
echo ""
echo "🔐 Connection details:"
echo "------------------------------------"
echo "Host: localhost"
echo "Port: 1433"
echo "Username: sa"
echo "Password: ${SA_PASSWORD}"
echo "Database: master"
echo ""
echo "📎 JDBC URL:"
echo "jdbc:sqlserver://localhost:1433;databaseName=master;user=sa;password=${SA_PASSWORD}"
echo ""
echo "🧪 Connect using sqlcmd:"
echo "sqlcmd -S localhost,1433 -U sa -P '${SA_PASSWORD}'"
echo "------------------------------------"

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -e
CONTAINER_NAME="oracle-free"
ORACLE_PASSWORD="oracle"
IMAGE="gvenzl/oracle-free:23-slim"
echo "🚀 Starting Oracle Free 23c container..."
docker run -d \
--name "${CONTAINER_NAME}" \
-p 1521:1521 \
-p 5500:5500 \
-e ORACLE_PASSWORD="${ORACLE_PASSWORD}" \
"${IMAGE}"
echo "⏳ Waiting for Oracle database to be ready..."
until docker logs "${CONTAINER_NAME}" 2>&1 | grep -q "DATABASE IS READY TO USE"; do
sleep 5
done
echo ""
echo "✅ Oracle Database is ready!"
echo ""
echo "🔐 Connection details:"
echo "------------------------------------"
echo "Host: localhost"
echo "Port: 1521"
echo "Service: FREEPDB1"
echo "Username: system"
echo "Password: ${ORACLE_PASSWORD}"
echo ""
echo "📎 JDBC URL:"
echo "jdbc:oracle:thin:@localhost:1521/FREEPDB1"
echo ""
echo "🧪 Connect using SQL*Plus:"
echo "sqlplus system/${ORACLE_PASSWORD}@FREEPDB1"
echo "------------------------------------"