mirror of
https://github.com/Infisical/infisical.git
synced 2025-07-29 22:37:44 +00:00
Compare commits
50 Commits
misc/soft-
...
infisical/
Author | SHA1 | Date | |
---|---|---|---|
|
fed44f328d | ||
|
95a68f2c2d | ||
|
db7c0c45f6 | ||
|
82bca03162 | ||
|
043c04778f | ||
|
560cd81a1c | ||
|
df3a87fabf | ||
|
6ceeccf583 | ||
|
9b0b14b847 | ||
|
78f4c0f002 | ||
|
6cff2f0437 | ||
|
6cefb180d6 | ||
|
59a44155c5 | ||
|
d0ad9c6b17 | ||
|
58a406b114 | ||
|
8a85695dc5 | ||
|
7ed8feee6f | ||
|
de67c0ad9f | ||
|
b8d11d31a6 | ||
|
d630ceaffe | ||
|
a89e60f296 | ||
|
a5d9abf1c8 | ||
|
d97dea2573 | ||
|
bc58f6b988 | ||
|
ed8e3f34fb | ||
|
91315c88c3 | ||
|
9267f881d6 | ||
|
c90ecd336c | ||
|
d8b1da3ddd | ||
|
58e86382fe | ||
|
2080c4419e | ||
|
b582a4a06d | ||
|
a5c6a864de | ||
|
5082c1ba3b | ||
|
cceb08b1b5 | ||
|
4c34e58945 | ||
|
72de1901a1 | ||
|
65fefcdd87 | ||
|
7137c94fa2 | ||
|
52ea7dfa61 | ||
|
093925ed0e | ||
|
539785acae | ||
|
3c63346d3a | ||
|
0c673f6cca | ||
|
5d4c7c2cbf | ||
|
08f0bf9c67 | ||
|
654dd97793 | ||
|
2e7baf8c89 | ||
|
7ca7a95070 | ||
|
71c49c8b90 |
1062
backend/package-lock.json
generated
1062
backend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -106,6 +106,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-iam": "^3.525.0",
|
||||
"@aws-sdk/client-kms": "^3.609.0",
|
||||
"@aws-sdk/client-secrets-manager": "^3.504.0",
|
||||
"@aws-sdk/client-sts": "^3.600.0",
|
||||
"@casl/ability": "^6.5.0",
|
||||
|
2
backend/src/@types/fastify.d.ts
vendored
2
backend/src/@types/fastify.d.ts
vendored
@@ -9,6 +9,7 @@ import { TAuditLogStreamServiceFactory } from "@app/ee/services/audit-log-stream
|
||||
import { TCertificateAuthorityCrlServiceFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-service";
|
||||
import { TDynamicSecretServiceFactory } from "@app/ee/services/dynamic-secret/dynamic-secret-service";
|
||||
import { TDynamicSecretLeaseServiceFactory } from "@app/ee/services/dynamic-secret-lease/dynamic-secret-lease-service";
|
||||
import { TExternalKmsServiceFactory } from "@app/ee/services/external-kms/external-kms-service";
|
||||
import { TGroupServiceFactory } from "@app/ee/services/group/group-service";
|
||||
import { TIdentityProjectAdditionalPrivilegeServiceFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service";
|
||||
import { TLdapConfigServiceFactory } from "@app/ee/services/ldap-config/ldap-config-service";
|
||||
@@ -163,6 +164,7 @@ declare module "fastify" {
|
||||
secretSharing: TSecretSharingServiceFactory;
|
||||
rateLimit: TRateLimitServiceFactory;
|
||||
userEngagement: TUserEngagementServiceFactory;
|
||||
externalKms: TExternalKmsServiceFactory;
|
||||
};
|
||||
// this is exclusive use for middlewares in which we need to inject data
|
||||
// everywhere else access using service layer
|
||||
|
8
backend/src/@types/knex.d.ts
vendored
8
backend/src/@types/knex.d.ts
vendored
@@ -59,6 +59,9 @@ import {
|
||||
TDynamicSecrets,
|
||||
TDynamicSecretsInsert,
|
||||
TDynamicSecretsUpdate,
|
||||
TExternalKms,
|
||||
TExternalKmsInsert,
|
||||
TExternalKmsUpdate,
|
||||
TGitAppInstallSessions,
|
||||
TGitAppInstallSessionsInsert,
|
||||
TGitAppInstallSessionsUpdate,
|
||||
@@ -125,6 +128,9 @@ import {
|
||||
TIntegrations,
|
||||
TIntegrationsInsert,
|
||||
TIntegrationsUpdate,
|
||||
TInternalKms,
|
||||
TInternalKmsInsert,
|
||||
TInternalKmsUpdate,
|
||||
TKmsKeys,
|
||||
TKmsKeysInsert,
|
||||
TKmsKeysUpdate,
|
||||
@@ -656,6 +662,8 @@ declare module "knex/types/tables" {
|
||||
TKmsRootConfigInsert,
|
||||
TKmsRootConfigUpdate
|
||||
>;
|
||||
[TableName.InternalKms]: KnexOriginal.CompositeTableType<TInternalKms, TInternalKmsInsert, TInternalKmsUpdate>;
|
||||
[TableName.ExternalKms]: KnexOriginal.CompositeTableType<TExternalKms, TExternalKmsInsert, TExternalKmsUpdate>;
|
||||
[TableName.KmsKey]: KnexOriginal.CompositeTableType<TKmsKeys, TKmsKeysInsert, TKmsKeysUpdate>;
|
||||
[TableName.KmsKeyVersion]: KnexOriginal.CompositeTableType<
|
||||
TKmsKeyVersions,
|
||||
|
256
backend/src/db/migrations/20240708100026_external-kms.ts
Normal file
256
backend/src/db/migrations/20240708100026_external-kms.ts
Normal file
@@ -0,0 +1,256 @@
|
||||
import slugify from "@sindresorhus/slugify";
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
|
||||
import { TableName } from "../schemas";
|
||||
|
||||
const createInternalKmsTableAndBackfillData = async (knex: Knex) => {
|
||||
const doesOldKmsKeyTableExist = await knex.schema.hasTable(TableName.KmsKey);
|
||||
const doesInternalKmsTableExist = await knex.schema.hasTable(TableName.InternalKms);
|
||||
|
||||
// building the internal kms table by filling from old kms table
|
||||
if (doesOldKmsKeyTableExist && !doesInternalKmsTableExist) {
|
||||
await knex.schema.createTable(TableName.InternalKms, (tb) => {
|
||||
tb.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
|
||||
tb.binary("encryptedKey").notNullable();
|
||||
tb.string("encryptionAlgorithm").notNullable();
|
||||
tb.integer("version").defaultTo(1).notNullable();
|
||||
tb.uuid("kmsKeyId").unique().notNullable();
|
||||
tb.foreign("kmsKeyId").references("id").inTable(TableName.KmsKey).onDelete("CASCADE");
|
||||
});
|
||||
|
||||
// copy the old kms and backfill
|
||||
const oldKmsKey = await knex(TableName.KmsKey).select("version", "encryptedKey", "encryptionAlgorithm", "id");
|
||||
if (oldKmsKey.length) {
|
||||
await knex(TableName.InternalKms).insert(
|
||||
oldKmsKey.map((el) => ({
|
||||
encryptionAlgorithm: el.encryptionAlgorithm,
|
||||
encryptedKey: el.encryptedKey,
|
||||
kmsKeyId: el.id,
|
||||
version: el.version
|
||||
}))
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const renameKmsKeyVersionTableAsInternalKmsKeyVersion = async (knex: Knex) => {
|
||||
const doesOldKmsKeyVersionTableExist = await knex.schema.hasTable(TableName.KmsKeyVersion);
|
||||
const doesNewKmsKeyVersionTableExist = await knex.schema.hasTable(TableName.InternalKmsKeyVersion);
|
||||
|
||||
if (doesOldKmsKeyVersionTableExist && !doesNewKmsKeyVersionTableExist) {
|
||||
// because we haven't started using versioning for kms thus no data exist
|
||||
await knex.schema.renameTable(TableName.KmsKeyVersion, TableName.InternalKmsKeyVersion);
|
||||
const hasKmsKeyIdColumn = await knex.schema.hasColumn(TableName.InternalKmsKeyVersion, "kmsKeyId");
|
||||
const hasInternalKmsIdColumn = await knex.schema.hasColumn(TableName.InternalKmsKeyVersion, "internalKmsId");
|
||||
|
||||
await knex.schema.alterTable(TableName.InternalKmsKeyVersion, (tb) => {
|
||||
if (hasKmsKeyIdColumn) tb.dropColumn("kmsKeyId");
|
||||
if (!hasInternalKmsIdColumn) {
|
||||
tb.uuid("internalKmsId").notNullable();
|
||||
tb.foreign("internalKmsId").references("id").inTable(TableName.InternalKms).onDelete("CASCADE");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const createExternalKmsKeyTable = async (knex: Knex) => {
|
||||
const doesExternalKmsServiceExist = await knex.schema.hasTable(TableName.ExternalKms);
|
||||
if (!doesExternalKmsServiceExist) {
|
||||
await knex.schema.createTable(TableName.ExternalKms, (tb) => {
|
||||
tb.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
|
||||
tb.string("provider").notNullable();
|
||||
tb.binary("encryptedProviderInputs").notNullable();
|
||||
tb.string("status");
|
||||
tb.string("statusDetails");
|
||||
tb.uuid("kmsKeyId").unique().notNullable();
|
||||
tb.foreign("kmsKeyId").references("id").inTable(TableName.KmsKey).onDelete("CASCADE");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const removeNonRequiredFieldsFromKmsKeyTableAndBackfillRequiredData = async (knex: Knex) => {
|
||||
const doesOldKmsKeyTableExist = await knex.schema.hasTable(TableName.KmsKey);
|
||||
|
||||
// building the internal kms table by filling from old kms table
|
||||
if (doesOldKmsKeyTableExist) {
|
||||
const hasSlugColumn = await knex.schema.hasColumn(TableName.KmsKey, "slug");
|
||||
const hasEncryptedKeyColumn = await knex.schema.hasColumn(TableName.KmsKey, "encryptedKey");
|
||||
const hasEncryptionAlgorithmColumn = await knex.schema.hasColumn(TableName.KmsKey, "encryptionAlgorithm");
|
||||
const hasVersionColumn = await knex.schema.hasColumn(TableName.KmsKey, "version");
|
||||
const hasTimestamps = await knex.schema.hasColumn(TableName.KmsKey, "createdAt");
|
||||
const hasProjectId = await knex.schema.hasColumn(TableName.KmsKey, "projectId");
|
||||
const hasOrgId = await knex.schema.hasColumn(TableName.KmsKey, "orgId");
|
||||
|
||||
await knex.schema.alterTable(TableName.KmsKey, (tb) => {
|
||||
if (!hasSlugColumn) tb.string("slug", 32);
|
||||
if (hasEncryptedKeyColumn) tb.dropColumn("encryptedKey");
|
||||
if (hasEncryptionAlgorithmColumn) tb.dropColumn("encryptionAlgorithm");
|
||||
if (hasVersionColumn) tb.dropColumn("version");
|
||||
if (!hasTimestamps) tb.timestamps(true, true, true);
|
||||
});
|
||||
|
||||
// backfill all org id in kms key because its gonna be changed to non nullable
|
||||
if (hasProjectId && hasOrgId) {
|
||||
await knex(TableName.KmsKey)
|
||||
.whereNull("orgId")
|
||||
.update({
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore because generate schema happens after this
|
||||
orgId: knex(TableName.Project)
|
||||
.select("orgId")
|
||||
.where("id", knex.raw("??", [`${TableName.KmsKey}.projectId`]))
|
||||
});
|
||||
}
|
||||
|
||||
// backfill slugs in kms
|
||||
const missingSlugs = await knex(TableName.KmsKey).whereNull("slug").select("id");
|
||||
if (missingSlugs.length) {
|
||||
await knex(TableName.KmsKey)
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore because generate schema happens after this
|
||||
.insert(missingSlugs.map(({ id }) => ({ id, slug: slugify(alphaNumericNanoId(8).toLowerCase()) })))
|
||||
.onConflict("id")
|
||||
.merge();
|
||||
}
|
||||
|
||||
await knex.schema.alterTable(TableName.KmsKey, (tb) => {
|
||||
if (hasOrgId) tb.uuid("orgId").notNullable().alter();
|
||||
tb.string("slug", 32).notNullable().alter();
|
||||
if (hasProjectId) tb.dropColumn("projectId");
|
||||
if (hasOrgId) tb.unique(["orgId", "slug"]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* The goal for this migration is split the existing kms key into three table
|
||||
* the kms-key table would be a container table that contains
|
||||
* the internal kms key table and external kms table
|
||||
*/
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
await createInternalKmsTableAndBackfillData(knex);
|
||||
await renameKmsKeyVersionTableAsInternalKmsKeyVersion(knex);
|
||||
await removeNonRequiredFieldsFromKmsKeyTableAndBackfillRequiredData(knex);
|
||||
await createExternalKmsKeyTable(knex);
|
||||
|
||||
const doesOrgKmsKeyExist = await knex.schema.hasColumn(TableName.Organization, "kmsDefaultKeyId");
|
||||
if (!doesOrgKmsKeyExist) {
|
||||
await knex.schema.alterTable(TableName.Organization, (tb) => {
|
||||
tb.uuid("kmsDefaultKeyId").nullable();
|
||||
tb.foreign("kmsDefaultKeyId").references("id").inTable(TableName.KmsKey);
|
||||
});
|
||||
}
|
||||
|
||||
const doesProjectKmsSecretManagerKeyExist = await knex.schema.hasColumn(TableName.Project, "kmsSecretManagerKeyId");
|
||||
if (!doesProjectKmsSecretManagerKeyExist) {
|
||||
await knex.schema.alterTable(TableName.Project, (tb) => {
|
||||
tb.uuid("kmsSecretManagerKeyId").nullable();
|
||||
tb.foreign("kmsSecretManagerKeyId").references("id").inTable(TableName.KmsKey);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const renameInternalKmsKeyVersionBackToKmsKeyVersion = async (knex: Knex) => {
|
||||
const doesInternalKmsKeyVersionTableExist = await knex.schema.hasTable(TableName.InternalKmsKeyVersion);
|
||||
const doesKmsKeyVersionTableExist = await knex.schema.hasTable(TableName.KmsKeyVersion);
|
||||
if (doesInternalKmsKeyVersionTableExist && !doesKmsKeyVersionTableExist) {
|
||||
// because we haven't started using versioning for kms thus no data exist
|
||||
await knex.schema.renameTable(TableName.InternalKmsKeyVersion, TableName.KmsKeyVersion);
|
||||
const hasInternalKmsIdColumn = await knex.schema.hasColumn(TableName.KmsKeyVersion, "internalKmsId");
|
||||
const hasKmsKeyIdColumn = await knex.schema.hasColumn(TableName.KmsKeyVersion, "kmsKeyId");
|
||||
|
||||
await knex.schema.alterTable(TableName.KmsKeyVersion, (tb) => {
|
||||
if (hasInternalKmsIdColumn) tb.dropColumn("internalKmsId");
|
||||
if (!hasKmsKeyIdColumn) {
|
||||
tb.uuid("kmsKeyId").notNullable();
|
||||
tb.foreign("kmsKeyId").references("id").inTable(TableName.KmsKey).onDelete("CASCADE");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const bringBackKmsKeyFields = async (knex: Knex) => {
|
||||
const doesOldKmsKeyTableExist = await knex.schema.hasTable(TableName.KmsKey);
|
||||
const doesInternalKmsTableExist = await knex.schema.hasTable(TableName.InternalKms);
|
||||
if (doesOldKmsKeyTableExist && doesInternalKmsTableExist) {
|
||||
const hasSlug = await knex.schema.hasColumn(TableName.KmsKey, "slug");
|
||||
const hasEncryptedKeyColumn = await knex.schema.hasColumn(TableName.KmsKey, "encryptedKey");
|
||||
const hasEncryptionAlgorithmColumn = await knex.schema.hasColumn(TableName.KmsKey, "encryptionAlgorithm");
|
||||
const hasVersionColumn = await knex.schema.hasColumn(TableName.KmsKey, "version");
|
||||
const hasNullableOrgId = await knex.schema.hasColumn(TableName.KmsKey, "orgId");
|
||||
const hasProjectIdColumn = await knex.schema.hasColumn(TableName.KmsKey, "projectId");
|
||||
|
||||
await knex.schema.alterTable(TableName.KmsKey, (tb) => {
|
||||
if (!hasEncryptedKeyColumn) tb.binary("encryptedKey");
|
||||
if (!hasEncryptionAlgorithmColumn) tb.string("encryptionAlgorithm");
|
||||
if (!hasVersionColumn) tb.integer("version").defaultTo(1);
|
||||
if (hasNullableOrgId) tb.uuid("orgId").nullable().alter();
|
||||
if (!hasProjectIdColumn) {
|
||||
tb.string("projectId");
|
||||
tb.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
|
||||
}
|
||||
if (hasSlug) tb.dropColumn("slug");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const backfillKmsKeyFromInternalKmsTable = async (knex: Knex) => {
|
||||
const doesOldKmsKeyTableExist = await knex.schema.hasTable(TableName.KmsKey);
|
||||
const doesInternalKmsTableExist = await knex.schema.hasTable(TableName.InternalKms);
|
||||
if (doesInternalKmsTableExist && doesOldKmsKeyTableExist) {
|
||||
// backfill kms key with internal kms data
|
||||
await knex(TableName.KmsKey).update({
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore because generate schema happens after this
|
||||
encryptedKey: knex(TableName.InternalKms)
|
||||
.select("encryptedKey")
|
||||
.where("kmsKeyId", knex.raw("??", [`${TableName.KmsKey}.id`])),
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore because generate schema happens after this
|
||||
encryptionAlgorithm: knex(TableName.InternalKms)
|
||||
.select("encryptionAlgorithm")
|
||||
.where("kmsKeyId", knex.raw("??", [`${TableName.KmsKey}.id`])),
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore because generate schema happens after this
|
||||
projectId: knex(TableName.Project)
|
||||
.select("id")
|
||||
.where("kmsCertificateKeyId", knex.raw("??", [`${TableName.KmsKey}.id`]))
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
const doesOrgKmsKeyExist = await knex.schema.hasColumn(TableName.Organization, "kmsDefaultKeyId");
|
||||
if (doesOrgKmsKeyExist) {
|
||||
await knex.schema.alterTable(TableName.Organization, (tb) => {
|
||||
tb.dropColumn("kmsDefaultKeyId");
|
||||
});
|
||||
}
|
||||
|
||||
const doesProjectKmsSecretManagerKeyExist = await knex.schema.hasColumn(TableName.Project, "kmsSecretManagerKeyId");
|
||||
if (doesProjectKmsSecretManagerKeyExist) {
|
||||
await knex.schema.alterTable(TableName.Project, (tb) => {
|
||||
tb.dropColumn("kmsSecretManagerKeyId");
|
||||
});
|
||||
}
|
||||
|
||||
await renameInternalKmsKeyVersionBackToKmsKeyVersion(knex);
|
||||
await bringBackKmsKeyFields(knex);
|
||||
await backfillKmsKeyFromInternalKmsTable(knex);
|
||||
|
||||
const doesOldKmsKeyTableExist = await knex.schema.hasTable(TableName.KmsKey);
|
||||
if (doesOldKmsKeyTableExist) {
|
||||
await knex.schema.alterTable(TableName.KmsKey, (tb) => {
|
||||
tb.binary("encryptedKey").notNullable().alter();
|
||||
tb.string("encryptionAlgorithm").notNullable().alter();
|
||||
});
|
||||
}
|
||||
|
||||
const doesInternalKmsTableExist = await knex.schema.hasTable(TableName.InternalKms);
|
||||
if (doesInternalKmsTableExist) await knex.schema.dropTable(TableName.InternalKms);
|
||||
|
||||
const doesExternalKmsServiceExist = await knex.schema.hasTable(TableName.ExternalKms);
|
||||
if (doesExternalKmsServiceExist) await knex.schema.dropTable(TableName.ExternalKms);
|
||||
}
|
23
backend/src/db/schemas/external-kms.ts
Normal file
23
backend/src/db/schemas/external-kms.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
// Code generated by automation script, DO NOT EDIT.
|
||||
// Automated by pulling database and generating zod schema
|
||||
// To update. Just run npm run generate:schema
|
||||
// Written by akhilmhdh.
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { zodBuffer } from "@app/lib/zod";
|
||||
|
||||
import { TImmutableDBKeys } from "./models";
|
||||
|
||||
export const ExternalKmsSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
provider: z.string(),
|
||||
encryptedProviderInputs: zodBuffer,
|
||||
status: z.string().nullable().optional(),
|
||||
statusDetails: z.string().nullable().optional(),
|
||||
kmsKeyId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TExternalKms = z.infer<typeof ExternalKmsSchema>;
|
||||
export type TExternalKmsInsert = Omit<z.input<typeof ExternalKmsSchema>, TImmutableDBKeys>;
|
||||
export type TExternalKmsUpdate = Partial<Omit<z.input<typeof ExternalKmsSchema>, TImmutableDBKeys>>;
|
@@ -17,6 +17,7 @@ export * from "./certificate-secrets";
|
||||
export * from "./certificates";
|
||||
export * from "./dynamic-secret-leases";
|
||||
export * from "./dynamic-secrets";
|
||||
export * from "./external-kms";
|
||||
export * from "./git-app-install-sessions";
|
||||
export * from "./git-app-org";
|
||||
export * from "./group-project-membership-roles";
|
||||
@@ -39,6 +40,7 @@ export * from "./identity-universal-auths";
|
||||
export * from "./incident-contacts";
|
||||
export * from "./integration-auths";
|
||||
export * from "./integrations";
|
||||
export * from "./internal-kms";
|
||||
export * from "./kms-key-versions";
|
||||
export * from "./kms-keys";
|
||||
export * from "./kms-root-config";
|
||||
|
21
backend/src/db/schemas/internal-kms-key-version.ts
Normal file
21
backend/src/db/schemas/internal-kms-key-version.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
// Code generated by automation script, DO NOT EDIT.
|
||||
// Automated by pulling database and generating zod schema
|
||||
// To update. Just run npm run generate:schema
|
||||
// Written by akhilmhdh.
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { zodBuffer } from "@app/lib/zod";
|
||||
|
||||
import { TImmutableDBKeys } from "./models";
|
||||
|
||||
export const InternalKmsKeyVersionSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
encryptedKey: zodBuffer,
|
||||
version: z.number(),
|
||||
internalKmsId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TInternalKmsKeyVersion = z.infer<typeof InternalKmsKeyVersionSchema>;
|
||||
export type TInternalKmsKeyVersionInsert = Omit<z.input<typeof InternalKmsKeyVersionSchema>, TImmutableDBKeys>;
|
||||
export type TInternalKmsKeyVersionUpdate = Partial<Omit<z.input<typeof InternalKmsKeyVersionSchema>, TImmutableDBKeys>>;
|
22
backend/src/db/schemas/internal-kms.ts
Normal file
22
backend/src/db/schemas/internal-kms.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
// Code generated by automation script, DO NOT EDIT.
|
||||
// Automated by pulling database and generating zod schema
|
||||
// To update. Just run npm run generate:schema
|
||||
// Written by akhilmhdh.
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { zodBuffer } from "@app/lib/zod";
|
||||
|
||||
import { TImmutableDBKeys } from "./models";
|
||||
|
||||
export const InternalKmsSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
encryptedKey: zodBuffer,
|
||||
encryptionAlgorithm: z.string(),
|
||||
version: z.number().default(1),
|
||||
kmsKeyId: z.string().uuid()
|
||||
});
|
||||
|
||||
export type TInternalKms = z.infer<typeof InternalKmsSchema>;
|
||||
export type TInternalKmsInsert = Omit<z.input<typeof InternalKmsSchema>, TImmutableDBKeys>;
|
||||
export type TInternalKmsUpdate = Partial<Omit<z.input<typeof InternalKmsSchema>, TImmutableDBKeys>>;
|
@@ -5,20 +5,17 @@
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { zodBuffer } from "@app/lib/zod";
|
||||
|
||||
import { TImmutableDBKeys } from "./models";
|
||||
|
||||
export const KmsKeysSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
encryptedKey: zodBuffer,
|
||||
encryptionAlgorithm: z.string(),
|
||||
version: z.number().default(1),
|
||||
description: z.string().nullable().optional(),
|
||||
isDisabled: z.boolean().default(false).nullable().optional(),
|
||||
isReserved: z.boolean().default(true).nullable().optional(),
|
||||
projectId: z.string().nullable().optional(),
|
||||
orgId: z.string().uuid().nullable().optional()
|
||||
orgId: z.string().uuid(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
slug: z.string()
|
||||
});
|
||||
|
||||
export type TKmsKeys = z.infer<typeof KmsKeysSchema>;
|
||||
|
@@ -96,6 +96,10 @@ export enum TableName {
|
||||
// KMS Service
|
||||
KmsServerRootConfig = "kms_root_config",
|
||||
KmsKey = "kms_keys",
|
||||
ExternalKms = "external_kms",
|
||||
InternalKms = "internal_kms",
|
||||
InternalKmsKeyVersion = "internal_kms_key_version",
|
||||
// @depreciated
|
||||
KmsKeyVersion = "kms_key_versions"
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,8 @@ export const OrganizationsSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
authEnforced: z.boolean().default(false).nullable().optional(),
|
||||
scimEnabled: z.boolean().default(false).nullable().optional()
|
||||
scimEnabled: z.boolean().default(false).nullable().optional(),
|
||||
kmsDefaultKeyId: z.string().uuid().nullable().optional()
|
||||
});
|
||||
|
||||
export type TOrganizations = z.infer<typeof OrganizationsSchema>;
|
||||
|
@@ -19,7 +19,8 @@ export const ProjectsSchema = z.object({
|
||||
upgradeStatus: z.string().nullable().optional(),
|
||||
pitVersionLimit: z.number().default(10),
|
||||
kmsCertificateKeyId: z.string().uuid().nullable().optional(),
|
||||
auditLogsRetentionDays: z.number().nullable().optional()
|
||||
auditLogsRetentionDays: z.number().nullable().optional(),
|
||||
kmsSecretManagerKeyId: z.string().uuid().nullable().optional()
|
||||
});
|
||||
|
||||
export type TProjects = z.infer<typeof ProjectsSchema>;
|
||||
|
190
backend/src/ee/routes/v1/external-kms-router.ts
Normal file
190
backend/src/ee/routes/v1/external-kms-router.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { ExternalKmsSchema, KmsKeysSchema } from "@app/db/schemas";
|
||||
import {
|
||||
ExternalKmsAwsSchema,
|
||||
ExternalKmsInputSchema,
|
||||
ExternalKmsInputUpdateSchema
|
||||
} from "@app/ee/services/external-kms/providers/model";
|
||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
|
||||
const sanitizedExternalSchema = KmsKeysSchema.extend({
|
||||
external: ExternalKmsSchema.pick({
|
||||
id: true,
|
||||
status: true,
|
||||
statusDetails: true,
|
||||
provider: true
|
||||
})
|
||||
});
|
||||
|
||||
const sanitizedExternalSchemaForGetById = KmsKeysSchema.extend({
|
||||
external: ExternalKmsSchema.pick({
|
||||
id: true,
|
||||
status: true,
|
||||
statusDetails: true,
|
||||
provider: true
|
||||
}).extend({
|
||||
providerInput: ExternalKmsAwsSchema
|
||||
})
|
||||
});
|
||||
|
||||
export const registerExternalKmsRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
schema: {
|
||||
body: z.object({
|
||||
slug: z.string().min(1).trim().toLowerCase().optional(),
|
||||
description: z.string().min(1).trim().optional(),
|
||||
provider: ExternalKmsInputSchema
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
externalKms: sanitizedExternalSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const externalKms = await server.services.externalKms.create({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
slug: req.body.slug,
|
||||
provider: req.body.provider,
|
||||
description: req.body.description
|
||||
});
|
||||
return { externalKms };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "PATCH",
|
||||
url: "/:id",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
schema: {
|
||||
params: z.object({
|
||||
id: z.string().trim().min(1)
|
||||
}),
|
||||
body: z.object({
|
||||
slug: z.string().min(1).trim().toLowerCase().optional(),
|
||||
description: z.string().min(1).trim().optional(),
|
||||
provider: ExternalKmsInputUpdateSchema
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
externalKms: sanitizedExternalSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const externalKms = await server.services.externalKms.updateById({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
slug: req.body.slug,
|
||||
provider: req.body.provider,
|
||||
description: req.body.description,
|
||||
id: req.params.id
|
||||
});
|
||||
return { externalKms };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "DELETE",
|
||||
url: "/:id",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
schema: {
|
||||
params: z.object({
|
||||
id: z.string().trim().min(1)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
externalKms: sanitizedExternalSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const externalKms = await server.services.externalKms.deleteById({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
id: req.params.id
|
||||
});
|
||||
return { externalKms };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/:id",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
params: z.object({
|
||||
id: z.string().trim().min(1)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
externalKms: sanitizedExternalSchemaForGetById
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const externalKms = await server.services.externalKms.findById({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
id: req.params.id
|
||||
});
|
||||
return { externalKms };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/slug/:slug",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
params: z.object({
|
||||
slug: z.string().trim().min(1)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
externalKms: sanitizedExternalSchemaForGetById
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const externalKms = await server.services.externalKms.findBySlug({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
slug: req.params.slug
|
||||
});
|
||||
return { externalKms };
|
||||
}
|
||||
});
|
||||
};
|
@@ -475,10 +475,13 @@ export const registerScimRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
z.object({
|
||||
op: z.literal("add"),
|
||||
value: z.object({
|
||||
value: z.string().trim(),
|
||||
display: z.string().trim().optional()
|
||||
})
|
||||
path: z.string().trim(),
|
||||
value: z.array(
|
||||
z.object({
|
||||
value: z.string().trim(),
|
||||
display: z.string().trim().optional()
|
||||
})
|
||||
)
|
||||
})
|
||||
])
|
||||
)
|
||||
|
@@ -17,7 +17,7 @@ type TCertificateAuthorityCrlServiceFactoryDep = {
|
||||
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
||||
certificateAuthorityCrlDAL: Pick<TCertificateAuthorityCrlDALFactory, "findOne">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||
kmsService: Pick<TKmsServiceFactory, "decrypt" | "generateKmsKey">;
|
||||
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||
};
|
||||
@@ -68,11 +68,11 @@ export const certificateAuthorityCrlServiceFactory = ({
|
||||
kmsService
|
||||
});
|
||||
|
||||
const decryptedCrl = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
cipherTextBlob: caCrl.encryptedCrl
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: keyId
|
||||
});
|
||||
|
||||
const decryptedCrl = kmsDecryptor({ cipherTextBlob: caCrl.encryptedCrl });
|
||||
const crl = new x509.X509Crl(decryptedCrl);
|
||||
|
||||
const base64crl = crl.toString("base64");
|
||||
|
47
backend/src/ee/services/external-kms/external-kms-dal.ts
Normal file
47
backend/src/ee/services/external-kms/external-kms-dal.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { TDbClient } from "@app/db";
|
||||
import { TableName, TKmsKeys } from "@app/db/schemas";
|
||||
import { DatabaseError } from "@app/lib/errors";
|
||||
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
||||
|
||||
export type TExternalKmsDALFactory = ReturnType<typeof externalKmsDALFactory>;
|
||||
|
||||
export const externalKmsDALFactory = (db: TDbClient) => {
|
||||
const externalKmsOrm = ormify(db, TableName.ExternalKms);
|
||||
|
||||
const find = async (filter: Partial<TKmsKeys>, tx?: Knex) => {
|
||||
try {
|
||||
const result = await (tx || db.replicaNode())(TableName.ExternalKms)
|
||||
.join(TableName.KmsKey, `${TableName.KmsKey}.id`, `${TableName.ExternalKms}.kmsKeyId`)
|
||||
.where(filter)
|
||||
.select(selectAllTableCols(TableName.KmsKey))
|
||||
.select(
|
||||
db.ref("id").withSchema(TableName.ExternalKms).as("externalKmsId"),
|
||||
db.ref("provider").withSchema(TableName.ExternalKms).as("externalKmsProvider"),
|
||||
db.ref("encryptedProviderInputs").withSchema(TableName.ExternalKms).as("externalKmsEncryptedProviderInput"),
|
||||
db.ref("status").withSchema(TableName.ExternalKms).as("externalKmsStatus"),
|
||||
db.ref("statusDetails").withSchema(TableName.ExternalKms).as("externalKmsStatusDetails")
|
||||
);
|
||||
|
||||
return result.map((el) => ({
|
||||
id: el.id,
|
||||
description: el.description,
|
||||
isDisabled: el.isDisabled,
|
||||
isReserved: el.isReserved,
|
||||
orgId: el.orgId,
|
||||
slug: el.slug,
|
||||
externalKms: {
|
||||
id: el.externalKmsId,
|
||||
provider: el.externalKmsProvider,
|
||||
status: el.externalKmsStatus,
|
||||
statusDetails: el.externalKmsStatusDetails
|
||||
}
|
||||
}));
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "Find" });
|
||||
}
|
||||
};
|
||||
|
||||
return { ...externalKmsOrm, find };
|
||||
};
|
309
backend/src/ee/services/external-kms/external-kms-service.ts
Normal file
309
backend/src/ee/services/external-kms/external-kms-service.ts
Normal file
@@ -0,0 +1,309 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import slugify from "@sindresorhus/slugify";
|
||||
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
import { TKmsKeyDALFactory } from "@app/services/kms/kms-key-dal";
|
||||
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "../permission/permission-service";
|
||||
import { TExternalKmsDALFactory } from "./external-kms-dal";
|
||||
import {
|
||||
TCreateExternalKmsDTO,
|
||||
TDeleteExternalKmsDTO,
|
||||
TGetExternalKmsByIdDTO,
|
||||
TGetExternalKmsBySlugDTO,
|
||||
TListExternalKmsDTO,
|
||||
TUpdateExternalKmsDTO
|
||||
} from "./external-kms-types";
|
||||
import { AwsKmsProviderFactory } from "./providers/aws-kms";
|
||||
import { ExternalKmsAwsSchema, KmsProviders } from "./providers/model";
|
||||
|
||||
type TExternalKmsServiceFactoryDep = {
|
||||
externalKmsDAL: TExternalKmsDALFactory;
|
||||
kmsService: Pick<TKmsServiceFactory, "getOrgKmsKeyId" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||
kmsDAL: Pick<TKmsKeyDALFactory, "create" | "updateById" | "findById" | "deleteById" | "findOne">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||
};
|
||||
|
||||
export type TExternalKmsServiceFactory = ReturnType<typeof externalKmsServiceFactory>;
|
||||
|
||||
export const externalKmsServiceFactory = ({
|
||||
externalKmsDAL,
|
||||
permissionService,
|
||||
kmsService,
|
||||
kmsDAL
|
||||
}: TExternalKmsServiceFactoryDep) => {
|
||||
const create = async ({
|
||||
provider,
|
||||
description,
|
||||
actor,
|
||||
slug,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod
|
||||
}: TCreateExternalKmsDTO) => {
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
|
||||
const kmsSlug = slug ? slugify(slug) : slugify(alphaNumericNanoId(8).toLowerCase());
|
||||
|
||||
let sanitizedProviderInput = "";
|
||||
switch (provider.type) {
|
||||
case KmsProviders.Aws:
|
||||
{
|
||||
const externalKms = await AwsKmsProviderFactory({ inputs: provider.inputs });
|
||||
await externalKms.validateConnection();
|
||||
// if missing kms key this generate a new kms key id and returns new provider input
|
||||
const newProviderInput = await externalKms.generateInputKmsKey();
|
||||
sanitizedProviderInput = JSON.stringify(newProviderInput);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new BadRequestError({ message: "external kms provided is invalid" });
|
||||
}
|
||||
|
||||
const orgKmsKeyId = await kmsService.getOrgKmsKeyId(actorOrgId);
|
||||
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||
kmsId: orgKmsKeyId
|
||||
});
|
||||
const { cipherTextBlob: encryptedProviderInputs } = kmsEncryptor({
|
||||
plainText: Buffer.from(sanitizedProviderInput, "utf8")
|
||||
});
|
||||
|
||||
const externalKms = await externalKmsDAL.transaction(async (tx) => {
|
||||
const kms = await kmsDAL.create(
|
||||
{
|
||||
isReserved: false,
|
||||
description,
|
||||
slug: kmsSlug,
|
||||
orgId: actorOrgId
|
||||
},
|
||||
tx
|
||||
);
|
||||
const externalKmsCfg = await externalKmsDAL.create(
|
||||
{
|
||||
provider: provider.type,
|
||||
encryptedProviderInputs,
|
||||
kmsKeyId: kms.id
|
||||
},
|
||||
tx
|
||||
);
|
||||
return { ...kms, external: externalKmsCfg };
|
||||
});
|
||||
|
||||
return externalKms;
|
||||
};
|
||||
|
||||
const updateById = async ({
|
||||
provider,
|
||||
description,
|
||||
actor,
|
||||
id: kmsId,
|
||||
slug,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod
|
||||
}: TUpdateExternalKmsDTO) => {
|
||||
const kmsDoc = await kmsDAL.findById(kmsId);
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
kmsDoc.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
|
||||
const kmsSlug = slug ? slugify(slug) : undefined;
|
||||
|
||||
const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id });
|
||||
if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" });
|
||||
|
||||
const orgDefaultKmsId = await kmsService.getOrgKmsKeyId(kmsDoc.orgId);
|
||||
let sanitizedProviderInput = "";
|
||||
if (provider) {
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: orgDefaultKmsId
|
||||
});
|
||||
const decryptedProviderInputBlob = kmsDecryptor({
|
||||
cipherTextBlob: externalKmsDoc.encryptedProviderInputs
|
||||
});
|
||||
|
||||
switch (provider.type) {
|
||||
case KmsProviders.Aws:
|
||||
{
|
||||
const decryptedProviderInput = await ExternalKmsAwsSchema.parseAsync(
|
||||
JSON.parse(decryptedProviderInputBlob.toString("utf8"))
|
||||
);
|
||||
const updatedProviderInput = { ...decryptedProviderInput, ...provider.inputs };
|
||||
const externalKms = await AwsKmsProviderFactory({ inputs: updatedProviderInput });
|
||||
await externalKms.validateConnection();
|
||||
sanitizedProviderInput = JSON.stringify(updatedProviderInput);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new BadRequestError({ message: "external kms provided is invalid" });
|
||||
}
|
||||
}
|
||||
|
||||
let encryptedProviderInputs: Buffer | undefined;
|
||||
if (sanitizedProviderInput) {
|
||||
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||
kmsId: orgDefaultKmsId
|
||||
});
|
||||
const { cipherTextBlob } = kmsEncryptor({
|
||||
plainText: Buffer.from(sanitizedProviderInput, "utf8")
|
||||
});
|
||||
encryptedProviderInputs = cipherTextBlob;
|
||||
}
|
||||
|
||||
const externalKms = await externalKmsDAL.transaction(async (tx) => {
|
||||
const kms = await kmsDAL.updateById(
|
||||
kmsDoc.id,
|
||||
{
|
||||
description,
|
||||
slug: kmsSlug
|
||||
},
|
||||
tx
|
||||
);
|
||||
if (encryptedProviderInputs) {
|
||||
const externalKmsCfg = await externalKmsDAL.updateById(
|
||||
externalKmsDoc.id,
|
||||
{
|
||||
encryptedProviderInputs
|
||||
},
|
||||
tx
|
||||
);
|
||||
return { ...kms, external: externalKmsCfg };
|
||||
}
|
||||
return { ...kms, external: externalKmsDoc };
|
||||
});
|
||||
|
||||
return externalKms;
|
||||
};
|
||||
|
||||
const deleteById = async ({ actor, id: kmsId, actorId, actorOrgId, actorAuthMethod }: TDeleteExternalKmsDTO) => {
|
||||
const kmsDoc = await kmsDAL.findById(kmsId);
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
kmsDoc.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
|
||||
|
||||
const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id });
|
||||
if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" });
|
||||
|
||||
const externalKms = await externalKmsDAL.transaction(async (tx) => {
|
||||
const kms = await kmsDAL.deleteById(kmsDoc.id, tx);
|
||||
return { ...kms, external: externalKmsDoc };
|
||||
});
|
||||
|
||||
return externalKms;
|
||||
};
|
||||
|
||||
const list = async ({ actor, actorId, actorOrgId, actorAuthMethod }: TListExternalKmsDTO) => {
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
|
||||
|
||||
const externalKmsDocs = await externalKmsDAL.find({ orgId: actorOrgId });
|
||||
|
||||
return externalKmsDocs;
|
||||
};
|
||||
|
||||
const findById = async ({ actor, actorId, actorOrgId, actorAuthMethod, id: kmsId }: TGetExternalKmsByIdDTO) => {
|
||||
const kmsDoc = await kmsDAL.findById(kmsId);
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
kmsDoc.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
|
||||
|
||||
const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id });
|
||||
if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" });
|
||||
|
||||
const orgDefaultKmsId = await kmsService.getOrgKmsKeyId(kmsDoc.orgId);
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: orgDefaultKmsId
|
||||
});
|
||||
const decryptedProviderInputBlob = kmsDecryptor({
|
||||
cipherTextBlob: externalKmsDoc.encryptedProviderInputs
|
||||
});
|
||||
switch (externalKmsDoc.provider) {
|
||||
case KmsProviders.Aws: {
|
||||
const decryptedProviderInput = await ExternalKmsAwsSchema.parseAsync(
|
||||
JSON.parse(decryptedProviderInputBlob.toString("utf8"))
|
||||
);
|
||||
return { ...kmsDoc, external: { ...externalKmsDoc, providerInput: decryptedProviderInput } };
|
||||
}
|
||||
default:
|
||||
throw new BadRequestError({ message: "external kms provided is invalid" });
|
||||
}
|
||||
};
|
||||
|
||||
const findBySlug = async ({
|
||||
actor,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
slug: kmsSlug
|
||||
}: TGetExternalKmsBySlugDTO) => {
|
||||
const kmsDoc = await kmsDAL.findOne({ slug: kmsSlug, orgId: actorOrgId });
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
kmsDoc.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
|
||||
|
||||
const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id });
|
||||
if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" });
|
||||
|
||||
const orgDefaultKmsId = await kmsService.getOrgKmsKeyId(kmsDoc.orgId);
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: orgDefaultKmsId
|
||||
});
|
||||
const decryptedProviderInputBlob = kmsDecryptor({
|
||||
cipherTextBlob: externalKmsDoc.encryptedProviderInputs
|
||||
});
|
||||
|
||||
switch (externalKmsDoc.provider) {
|
||||
case KmsProviders.Aws: {
|
||||
const decryptedProviderInput = await ExternalKmsAwsSchema.parseAsync(
|
||||
JSON.parse(decryptedProviderInputBlob.toString("utf8"))
|
||||
);
|
||||
return { ...kmsDoc, external: { ...externalKmsDoc, providerInput: decryptedProviderInput } };
|
||||
}
|
||||
default:
|
||||
throw new BadRequestError({ message: "external kms provided is invalid" });
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
create,
|
||||
updateById,
|
||||
deleteById,
|
||||
list,
|
||||
findById,
|
||||
findBySlug
|
||||
};
|
||||
};
|
30
backend/src/ee/services/external-kms/external-kms-types.ts
Normal file
30
backend/src/ee/services/external-kms/external-kms-types.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { TOrgPermission } from "@app/lib/types";
|
||||
|
||||
import { TExternalKmsInputSchema, TExternalKmsInputUpdateSchema } from "./providers/model";
|
||||
|
||||
export type TCreateExternalKmsDTO = {
|
||||
slug?: string;
|
||||
description?: string;
|
||||
provider: TExternalKmsInputSchema;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TUpdateExternalKmsDTO = {
|
||||
id: string;
|
||||
slug?: string;
|
||||
description?: string;
|
||||
provider?: TExternalKmsInputUpdateSchema;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TDeleteExternalKmsDTO = {
|
||||
id: string;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TListExternalKmsDTO = Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TGetExternalKmsByIdDTO = {
|
||||
id: string;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TGetExternalKmsBySlugDTO = {
|
||||
slug: string;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
102
backend/src/ee/services/external-kms/providers/aws-kms.ts
Normal file
102
backend/src/ee/services/external-kms/providers/aws-kms.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { CreateKeyCommand, DecryptCommand, DescribeKeyCommand, EncryptCommand, KMSClient } from "@aws-sdk/client-kms";
|
||||
import { AssumeRoleCommand, STSClient } from "@aws-sdk/client-sts";
|
||||
import { randomUUID } from "crypto";
|
||||
|
||||
import { ExternalKmsAwsSchema, KmsAwsCredentialType, TExternalKmsAwsSchema, TExternalKmsProviderFns } from "./model";
|
||||
|
||||
const getAwsKmsClient = async (providerInputs: TExternalKmsAwsSchema) => {
|
||||
if (providerInputs.credential.type === KmsAwsCredentialType.AssumeRole) {
|
||||
const awsCredential = providerInputs.credential.data;
|
||||
const stsClient = new STSClient({
|
||||
region: providerInputs.awsRegion
|
||||
});
|
||||
const command = new AssumeRoleCommand({
|
||||
RoleArn: awsCredential.assumeRoleArn,
|
||||
RoleSessionName: `infisical-kms-${randomUUID()}`,
|
||||
DurationSeconds: 900, // 15mins
|
||||
ExternalId: awsCredential.externalId
|
||||
});
|
||||
const response = await stsClient.send(command);
|
||||
if (!response.Credentials?.AccessKeyId || !response.Credentials?.SecretAccessKey)
|
||||
throw new Error("Failed to assume role");
|
||||
|
||||
const kmsClient = new KMSClient({
|
||||
region: providerInputs.awsRegion,
|
||||
credentials: {
|
||||
accessKeyId: response.Credentials.AccessKeyId,
|
||||
secretAccessKey: response.Credentials.SecretAccessKey,
|
||||
sessionToken: response.Credentials.SessionToken,
|
||||
expiration: response.Credentials.Expiration
|
||||
}
|
||||
});
|
||||
return kmsClient;
|
||||
}
|
||||
const awsCredential = providerInputs.credential.data;
|
||||
const kmsClient = new KMSClient({
|
||||
region: providerInputs.awsRegion,
|
||||
credentials: {
|
||||
accessKeyId: awsCredential.accessKey,
|
||||
secretAccessKey: awsCredential.secretKey
|
||||
}
|
||||
});
|
||||
return kmsClient;
|
||||
};
|
||||
|
||||
type AwsKmsProviderArgs = {
|
||||
inputs: unknown;
|
||||
};
|
||||
type TAwsKmsProviderFactoryReturn = TExternalKmsProviderFns & {
|
||||
generateInputKmsKey: () => Promise<TExternalKmsAwsSchema>;
|
||||
};
|
||||
|
||||
export const AwsKmsProviderFactory = async ({ inputs }: AwsKmsProviderArgs): Promise<TAwsKmsProviderFactoryReturn> => {
|
||||
const providerInputs = await ExternalKmsAwsSchema.parseAsync(inputs);
|
||||
const awsClient = await getAwsKmsClient(providerInputs);
|
||||
|
||||
const generateInputKmsKey = async () => {
|
||||
if (providerInputs.kmsKeyId) return providerInputs;
|
||||
|
||||
const command = new CreateKeyCommand({ Tags: [{ TagKey: "author", TagValue: "infisical" }] });
|
||||
const kmsKey = await awsClient.send(command);
|
||||
if (!kmsKey.KeyMetadata?.KeyId) throw new Error("Failed to generate kms key");
|
||||
|
||||
return { ...providerInputs, kmsKeyId: kmsKey.KeyMetadata?.KeyId };
|
||||
};
|
||||
|
||||
const validateConnection = async () => {
|
||||
const command = new DescribeKeyCommand({
|
||||
KeyId: providerInputs.kmsKeyId
|
||||
});
|
||||
const isConnected = await awsClient.send(command).then(() => true);
|
||||
return isConnected;
|
||||
};
|
||||
|
||||
const encrypt = async (data: Buffer) => {
|
||||
const command = new EncryptCommand({
|
||||
KeyId: providerInputs.kmsKeyId,
|
||||
Plaintext: data
|
||||
});
|
||||
const encryptionCommand = await awsClient.send(command);
|
||||
if (!encryptionCommand.CiphertextBlob) throw new Error("encryption failed");
|
||||
|
||||
return { encryptedBlob: Buffer.from(encryptionCommand.CiphertextBlob) };
|
||||
};
|
||||
|
||||
const decrypt = async (encryptedBlob: Buffer) => {
|
||||
const command = new DecryptCommand({
|
||||
KeyId: providerInputs.kmsKeyId,
|
||||
CiphertextBlob: encryptedBlob
|
||||
});
|
||||
const decryptionCommand = await awsClient.send(command);
|
||||
if (!decryptionCommand.Plaintext) throw new Error("decryption failed");
|
||||
|
||||
return { data: Buffer.from(decryptionCommand.Plaintext) };
|
||||
};
|
||||
|
||||
return {
|
||||
generateInputKmsKey,
|
||||
validateConnection,
|
||||
encrypt,
|
||||
decrypt
|
||||
};
|
||||
};
|
61
backend/src/ee/services/external-kms/providers/model.ts
Normal file
61
backend/src/ee/services/external-kms/providers/model.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export enum KmsProviders {
|
||||
Aws = "aws"
|
||||
}
|
||||
|
||||
export enum KmsAwsCredentialType {
|
||||
AssumeRole = "assume-role",
|
||||
AccessKey = "access-key"
|
||||
}
|
||||
|
||||
export const ExternalKmsAwsSchema = z.object({
|
||||
credential: z
|
||||
.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal(KmsAwsCredentialType.AccessKey),
|
||||
data: z.object({
|
||||
accessKey: z.string().trim().min(1).describe("AWS user account access key"),
|
||||
secretKey: z.string().trim().min(1).describe("AWS user account secret key")
|
||||
})
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal(KmsAwsCredentialType.AssumeRole),
|
||||
data: z.object({
|
||||
assumeRoleArn: z.string().trim().min(1).describe("AWS user role to be assumed by infisical"),
|
||||
externalId: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.optional()
|
||||
.describe("AWS assume role external id for furthur security in authentication")
|
||||
})
|
||||
})
|
||||
])
|
||||
.describe("AWS credential information to connect"),
|
||||
awsRegion: z.string().min(1).trim().describe("AWS region to connect"),
|
||||
kmsKeyId: z
|
||||
.string()
|
||||
.trim()
|
||||
.optional()
|
||||
.describe("A pre existing AWS KMS key id to be used for encryption. If not provided a kms key will be generated.")
|
||||
});
|
||||
export type TExternalKmsAwsSchema = z.infer<typeof ExternalKmsAwsSchema>;
|
||||
|
||||
// The root schema of the JSON
|
||||
export const ExternalKmsInputSchema = z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal(KmsProviders.Aws), inputs: ExternalKmsAwsSchema })
|
||||
]);
|
||||
export type TExternalKmsInputSchema = z.infer<typeof ExternalKmsInputSchema>;
|
||||
|
||||
export const ExternalKmsInputUpdateSchema = z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal(KmsProviders.Aws), inputs: ExternalKmsAwsSchema.partial() })
|
||||
]);
|
||||
export type TExternalKmsInputUpdateSchema = z.infer<typeof ExternalKmsInputUpdateSchema>;
|
||||
|
||||
// generic function shared by all provider
|
||||
export type TExternalKmsProviderFns = {
|
||||
validateConnection: () => Promise<boolean>;
|
||||
encrypt: (data: Buffer) => Promise<{ encryptedBlob: Buffer }>;
|
||||
decrypt: (encryptedBlob: Buffer) => Promise<{ data: Buffer }>;
|
||||
};
|
@@ -218,6 +218,8 @@ export const licenseServiceFactory = ({
|
||||
} else if (instanceType === InstanceType.EnterpriseOnPrem) {
|
||||
const usedSeats = await licenseDAL.countOfOrgMembers(null, tx);
|
||||
const usedIdentitySeats = await licenseDAL.countOrgUsersAndIdentities(null, tx);
|
||||
onPremFeatures.membersUsed = usedSeats;
|
||||
onPremFeatures.identitiesUsed = usedIdentitySeats;
|
||||
await licenseServerOnPremApi.request.patch(`/api/license/v1/license`, {
|
||||
usedSeats,
|
||||
usedIdentitySeats
|
||||
|
@@ -30,9 +30,9 @@ export type TFeatureSet = {
|
||||
workspacesUsed: 0;
|
||||
dynamicSecret: false;
|
||||
memberLimit: null;
|
||||
membersUsed: 0;
|
||||
membersUsed: number;
|
||||
identityLimit: null;
|
||||
identitiesUsed: 0;
|
||||
identitiesUsed: number;
|
||||
environmentLimit: null;
|
||||
environmentsUsed: 0;
|
||||
secretVersioning: true;
|
||||
|
@@ -109,6 +109,9 @@ export const permissionServiceFactory = ({
|
||||
authMethod: ActorAuthMethod,
|
||||
userOrgId?: string
|
||||
) => {
|
||||
// when token is scoped, ensure the passed org id is same as user org id
|
||||
if (userOrgId && userOrgId !== orgId)
|
||||
throw new BadRequestError({ message: "Invalid user token. Scoped to different organization." });
|
||||
const membership = await permissionDAL.getOrgPermission(userId, orgId);
|
||||
if (!membership) throw new UnauthorizedError({ name: "User not in org" });
|
||||
if (membership.role === OrgMembershipRole.Custom && !membership.permissions) {
|
||||
|
@@ -2,7 +2,7 @@ import { ForbiddenError } from "@casl/ability";
|
||||
import slugify from "@sindresorhus/slugify";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import { OrgMembershipRole, OrgMembershipStatus, TableName, TGroups, TOrgMemberships, TUsers } from "@app/db/schemas";
|
||||
import { OrgMembershipRole, OrgMembershipStatus, TableName, TOrgMemberships, TUsers } from "@app/db/schemas";
|
||||
import { TGroupDALFactory } from "@app/ee/services/group/group-dal";
|
||||
import { addUsersToGroupByUserIds, removeUsersFromGroupByUserIds } from "@app/ee/services/group/group-fns";
|
||||
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
||||
@@ -66,7 +66,7 @@ type TScimServiceFactoryDep = {
|
||||
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "find" | "delete" | "findProjectMembershipsByUserId">;
|
||||
groupDAL: Pick<
|
||||
TGroupDALFactory,
|
||||
"create" | "findOne" | "findAllGroupMembers" | "update" | "delete" | "findGroups" | "transaction"
|
||||
"create" | "findOne" | "findAllGroupMembers" | "delete" | "findGroups" | "transaction" | "updateById" | "update"
|
||||
>;
|
||||
groupProjectDAL: Pick<TGroupProjectDALFactory, "find">;
|
||||
userGroupMembershipDAL: Pick<
|
||||
@@ -817,7 +817,6 @@ export const scimServiceFactory = ({
|
||||
});
|
||||
};
|
||||
|
||||
// TODO: add support for add/remove op
|
||||
const updateScimGroupNamePatch = async ({ groupId, orgId, operations }: TUpdateScimGroupNamePatchDTO) => {
|
||||
const plan = await licenseService.getPlan(orgId);
|
||||
if (!plan.groups)
|
||||
@@ -840,23 +839,45 @@ export const scimServiceFactory = ({
|
||||
status: 403
|
||||
});
|
||||
|
||||
let group: TGroups | undefined;
|
||||
let group = await groupDAL.findOne({
|
||||
id: groupId,
|
||||
orgId
|
||||
});
|
||||
|
||||
if (!group) {
|
||||
throw new ScimRequestError({
|
||||
detail: "Group Not Found",
|
||||
status: 404
|
||||
});
|
||||
}
|
||||
|
||||
for await (const operation of operations) {
|
||||
switch (operation.op) {
|
||||
case "replace": {
|
||||
await groupDAL.update(
|
||||
{
|
||||
id: groupId,
|
||||
orgId
|
||||
},
|
||||
{
|
||||
name: operation.value.displayName
|
||||
}
|
||||
);
|
||||
group = await groupDAL.updateById(group.id, {
|
||||
name: operation.value.displayName
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "add": {
|
||||
// TODO
|
||||
const orgMemberships = await orgMembershipDAL.find({
|
||||
$in: {
|
||||
id: operation.value.map((member) => member.value)
|
||||
}
|
||||
});
|
||||
|
||||
await addUsersToGroupByUserIds({
|
||||
group,
|
||||
userIds: orgMemberships.map((membership) => membership.userId as string),
|
||||
userDAL,
|
||||
userGroupMembershipDAL,
|
||||
orgDAL,
|
||||
groupProjectDAL,
|
||||
projectKeyDAL,
|
||||
projectDAL,
|
||||
projectBotDAL
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case "remove": {
|
||||
@@ -872,13 +893,6 @@ export const scimServiceFactory = ({
|
||||
}
|
||||
}
|
||||
|
||||
if (!group) {
|
||||
throw new ScimRequestError({
|
||||
detail: "Group Not Found",
|
||||
status: 404
|
||||
});
|
||||
}
|
||||
|
||||
return buildScimGroup({
|
||||
groupId: group.id,
|
||||
name: group.name,
|
||||
|
@@ -125,10 +125,11 @@ type TRemoveOp = {
|
||||
|
||||
type TAddOp = {
|
||||
op: "add";
|
||||
path: string;
|
||||
value: {
|
||||
value: string;
|
||||
display?: string;
|
||||
};
|
||||
}[];
|
||||
};
|
||||
|
||||
export type TDeleteScimGroupDTO = {
|
||||
|
@@ -515,6 +515,9 @@ export const FOLDERS = {
|
||||
path: "The path to list folders from.",
|
||||
directory: "The directory to list folders from. (Deprecated in favor of path)"
|
||||
},
|
||||
GET_BY_ID: {
|
||||
folderId: "The id of the folder to get details."
|
||||
},
|
||||
CREATE: {
|
||||
workspaceId: "The ID of the project to create the folder in.",
|
||||
environment: "The slug of the environment to create the folder in.",
|
||||
|
@@ -22,6 +22,8 @@ import { buildDynamicSecretProviders } from "@app/ee/services/dynamic-secret/pro
|
||||
import { dynamicSecretLeaseDALFactory } from "@app/ee/services/dynamic-secret-lease/dynamic-secret-lease-dal";
|
||||
import { dynamicSecretLeaseQueueServiceFactory } from "@app/ee/services/dynamic-secret-lease/dynamic-secret-lease-queue";
|
||||
import { dynamicSecretLeaseServiceFactory } from "@app/ee/services/dynamic-secret-lease/dynamic-secret-lease-service";
|
||||
import { externalKmsDALFactory } from "@app/ee/services/external-kms/external-kms-dal";
|
||||
import { externalKmsServiceFactory } from "@app/ee/services/external-kms/external-kms-service";
|
||||
import { groupDALFactory } from "@app/ee/services/group/group-dal";
|
||||
import { groupServiceFactory } from "@app/ee/services/group/group-service";
|
||||
import { userGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
||||
@@ -116,7 +118,8 @@ import { integrationDALFactory } from "@app/services/integration/integration-dal
|
||||
import { integrationServiceFactory } from "@app/services/integration/integration-service";
|
||||
import { integrationAuthDALFactory } from "@app/services/integration-auth/integration-auth-dal";
|
||||
import { integrationAuthServiceFactory } from "@app/services/integration-auth/integration-auth-service";
|
||||
import { kmsDALFactory } from "@app/services/kms/kms-dal";
|
||||
import { internalKmsDALFactory } from "@app/services/kms/internal-kms-dal";
|
||||
import { kmskeyDALFactory } from "@app/services/kms/kms-key-dal";
|
||||
import { kmsRootConfigDALFactory } from "@app/services/kms/kms-root-config-dal";
|
||||
import { kmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { incidentContactDALFactory } from "@app/services/org/incident-contacts-dal";
|
||||
@@ -288,7 +291,9 @@ export const registerRoutes = async (
|
||||
const dynamicSecretDAL = dynamicSecretDALFactory(db);
|
||||
const dynamicSecretLeaseDAL = dynamicSecretLeaseDALFactory(db);
|
||||
|
||||
const kmsDAL = kmsDALFactory(db);
|
||||
const kmsDAL = kmskeyDALFactory(db);
|
||||
const internalKmsDAL = internalKmsDALFactory(db);
|
||||
const externalKmsDAL = externalKmsDALFactory(db);
|
||||
const kmsRootConfigDAL = kmsRootConfigDALFactory(db);
|
||||
|
||||
const permissionService = permissionServiceFactory({
|
||||
@@ -302,7 +307,16 @@ export const registerRoutes = async (
|
||||
const kmsService = kmsServiceFactory({
|
||||
kmsRootConfigDAL,
|
||||
keyStore,
|
||||
kmsDAL
|
||||
kmsDAL,
|
||||
internalKmsDAL,
|
||||
orgDAL,
|
||||
projectDAL
|
||||
});
|
||||
const externalKmsService = externalKmsServiceFactory({
|
||||
kmsDAL,
|
||||
kmsService,
|
||||
permissionService,
|
||||
externalKmsDAL
|
||||
});
|
||||
|
||||
const trustedIpService = trustedIpServiceFactory({
|
||||
@@ -645,7 +659,8 @@ export const registerRoutes = async (
|
||||
const webhookService = webhookServiceFactory({
|
||||
permissionService,
|
||||
webhookDAL,
|
||||
projectEnvDAL
|
||||
projectEnvDAL,
|
||||
projectDAL
|
||||
});
|
||||
|
||||
const secretTagService = secretTagServiceFactory({ secretTagDAL, permissionService });
|
||||
@@ -1030,7 +1045,8 @@ export const registerRoutes = async (
|
||||
projectUserAdditionalPrivilege: projectUserAdditionalPrivilegeService,
|
||||
identityProjectAdditionalPrivilege: identityProjectAdditionalPrivilegeService,
|
||||
secretSharing: secretSharingService,
|
||||
userEngagement: userEngagementService
|
||||
userEngagement: userEngagementService,
|
||||
externalKms: externalKmsService
|
||||
});
|
||||
|
||||
const cronJobs: CronJob[] = [];
|
||||
|
@@ -292,4 +292,39 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) =>
|
||||
return { folders };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/:id",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
description: "Get folder by id",
|
||||
security: [
|
||||
{
|
||||
bearerAuth: []
|
||||
}
|
||||
],
|
||||
params: z.object({
|
||||
id: z.string().trim().describe(FOLDERS.GET_BY_ID.folderId)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
folder: SecretFoldersSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const folder = await server.services.folder.getFolderById({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
id: req.params.id
|
||||
});
|
||||
return { folder };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@@ -75,8 +75,10 @@ export const getCaCredentials = async ({
|
||||
kmsService
|
||||
});
|
||||
|
||||
const decryptedPrivateKey = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: keyId
|
||||
});
|
||||
const decryptedPrivateKey = kmsDecryptor({
|
||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||
});
|
||||
|
||||
@@ -123,15 +125,17 @@ export const getCaCertChain = async ({
|
||||
kmsService
|
||||
});
|
||||
|
||||
const decryptedCaCert = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: keyId
|
||||
});
|
||||
|
||||
const decryptedCaCert = kmsDecryptor({
|
||||
cipherTextBlob: caCert.encryptedCertificate
|
||||
});
|
||||
|
||||
const caCertObj = new x509.X509Certificate(decryptedCaCert);
|
||||
|
||||
const decryptedChain = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
const decryptedChain = kmsDecryptor({
|
||||
cipherTextBlob: caCert.encryptedCertificateChain
|
||||
});
|
||||
|
||||
@@ -168,8 +172,11 @@ export const rebuildCaCrl = async ({
|
||||
kmsService
|
||||
});
|
||||
|
||||
const privateKey = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: keyId
|
||||
});
|
||||
|
||||
const privateKey = kmsDecryptor({
|
||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||
});
|
||||
|
||||
@@ -200,8 +207,10 @@ export const rebuildCaCrl = async ({
|
||||
signingKey: sk
|
||||
});
|
||||
|
||||
const { cipherTextBlob: encryptedCrl } = await kmsService.encrypt({
|
||||
kmsId: keyId,
|
||||
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||
kmsId: keyId
|
||||
});
|
||||
const { cipherTextBlob: encryptedCrl } = kmsEncryptor({
|
||||
plainText: Buffer.from(new Uint8Array(crl.rawData))
|
||||
});
|
||||
|
||||
|
@@ -25,7 +25,7 @@ type TCertificateAuthorityQueueFactoryDep = {
|
||||
certificateAuthoritySecretDAL: TCertificateAuthoritySecretDALFactory;
|
||||
certificateDAL: TCertificateDALFactory;
|
||||
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encrypt" | "decrypt">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||
queueService: TQueueServiceFactory;
|
||||
};
|
||||
export type TCertificateAuthorityQueueFactory = ReturnType<typeof certificateAuthorityQueueFactory>;
|
||||
@@ -88,8 +88,10 @@ export const certificateAuthorityQueueFactory = ({
|
||||
kmsService
|
||||
});
|
||||
|
||||
const privateKey = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: keyId
|
||||
});
|
||||
const privateKey = kmsDecryptor({
|
||||
cipherTextBlob: caSecret.encryptedPrivateKey
|
||||
});
|
||||
|
||||
@@ -120,8 +122,10 @@ export const certificateAuthorityQueueFactory = ({
|
||||
signingKey: sk
|
||||
});
|
||||
|
||||
const { cipherTextBlob: encryptedCrl } = await kmsService.encrypt({
|
||||
kmsId: keyId,
|
||||
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||
kmsId: keyId
|
||||
});
|
||||
const { cipherTextBlob: encryptedCrl } = kmsEncryptor({
|
||||
plainText: Buffer.from(new Uint8Array(crl.rawData))
|
||||
});
|
||||
|
||||
|
@@ -53,7 +53,7 @@ type TCertificateAuthorityServiceFactoryDep = {
|
||||
certificateDAL: Pick<TCertificateDALFactory, "transaction" | "create" | "find">;
|
||||
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encrypt" | "decrypt">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
};
|
||||
|
||||
@@ -154,11 +154,14 @@ export const certificateAuthorityServiceFactory = ({
|
||||
tx
|
||||
);
|
||||
|
||||
const keyId = await getProjectKmsCertificateKeyId({
|
||||
const certificateManagerKmsId = await getProjectKmsCertificateKeyId({
|
||||
projectId: project.id,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||
kmsId: certificateManagerKmsId
|
||||
});
|
||||
|
||||
if (type === CaType.ROOT) {
|
||||
// note: create self-signed cert only applicable for root CA
|
||||
@@ -178,13 +181,11 @@ export const certificateAuthorityServiceFactory = ({
|
||||
]
|
||||
});
|
||||
|
||||
const { cipherTextBlob: encryptedCertificate } = await kmsService.encrypt({
|
||||
kmsId: keyId,
|
||||
const { cipherTextBlob: encryptedCertificate } = kmsEncryptor({
|
||||
plainText: Buffer.from(new Uint8Array(cert.rawData))
|
||||
});
|
||||
|
||||
const { cipherTextBlob: encryptedCertificateChain } = await kmsService.encrypt({
|
||||
kmsId: keyId,
|
||||
const { cipherTextBlob: encryptedCertificateChain } = kmsEncryptor({
|
||||
plainText: Buffer.alloc(0)
|
||||
});
|
||||
|
||||
@@ -208,8 +209,7 @@ export const certificateAuthorityServiceFactory = ({
|
||||
signingKey: keys.privateKey
|
||||
});
|
||||
|
||||
const { cipherTextBlob: encryptedCrl } = await kmsService.encrypt({
|
||||
kmsId: keyId,
|
||||
const { cipherTextBlob: encryptedCrl } = kmsEncryptor({
|
||||
plainText: Buffer.from(new Uint8Array(crl.rawData))
|
||||
});
|
||||
|
||||
@@ -224,8 +224,7 @@ export const certificateAuthorityServiceFactory = ({
|
||||
// https://nodejs.org/api/crypto.html#static-method-keyobjectfromkey
|
||||
const skObj = KeyObject.from(keys.privateKey);
|
||||
|
||||
const { cipherTextBlob: encryptedPrivateKey } = await kmsService.encrypt({
|
||||
kmsId: keyId,
|
||||
const { cipherTextBlob: encryptedPrivateKey } = kmsEncryptor({
|
||||
plainText: skObj.export({
|
||||
type: "pkcs8",
|
||||
format: "der"
|
||||
@@ -449,15 +448,17 @@ export const certificateAuthorityServiceFactory = ({
|
||||
|
||||
const alg = keyAlgorithmToAlgCfg(ca.keyAlgorithm as CertKeyAlgorithm);
|
||||
|
||||
const keyId = await getProjectKmsCertificateKeyId({
|
||||
const certificateManagerKmsId = await getProjectKmsCertificateKeyId({
|
||||
projectId: ca.projectId,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: certificateManagerKmsId
|
||||
});
|
||||
|
||||
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
||||
const decryptedCaCert = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
const decryptedCaCert = kmsDecryptor({
|
||||
cipherTextBlob: caCert.encryptedCertificate
|
||||
});
|
||||
|
||||
@@ -605,19 +606,20 @@ export const certificateAuthorityServiceFactory = ({
|
||||
dn: parentCertSubject
|
||||
});
|
||||
|
||||
const keyId = await getProjectKmsCertificateKeyId({
|
||||
const certificateManagerKmsId = await getProjectKmsCertificateKeyId({
|
||||
projectId: ca.projectId,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||
kmsId: certificateManagerKmsId
|
||||
});
|
||||
|
||||
const { cipherTextBlob: encryptedCertificate } = await kmsService.encrypt({
|
||||
kmsId: keyId,
|
||||
const { cipherTextBlob: encryptedCertificate } = kmsEncryptor({
|
||||
plainText: Buffer.from(new Uint8Array(certObj.rawData))
|
||||
});
|
||||
|
||||
const { cipherTextBlob: encryptedCertificateChain } = await kmsService.encrypt({
|
||||
kmsId: keyId,
|
||||
const { cipherTextBlob: encryptedCertificateChain } = kmsEncryptor({
|
||||
plainText: Buffer.from(certificateChain)
|
||||
});
|
||||
|
||||
@@ -682,14 +684,16 @@ export const certificateAuthorityServiceFactory = ({
|
||||
const caCert = await certificateAuthorityCertDAL.findOne({ caId: ca.id });
|
||||
if (!caCert) throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
||||
|
||||
const keyId = await getProjectKmsCertificateKeyId({
|
||||
const certificateManagerKmsId = await getProjectKmsCertificateKeyId({
|
||||
projectId: ca.projectId,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: certificateManagerKmsId
|
||||
});
|
||||
|
||||
const decryptedCaCert = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
const decryptedCaCert = kmsDecryptor({
|
||||
cipherTextBlob: caCert.encryptedCertificate
|
||||
});
|
||||
|
||||
@@ -796,8 +800,10 @@ export const certificateAuthorityServiceFactory = ({
|
||||
const skLeafObj = KeyObject.from(leafKeys.privateKey);
|
||||
const skLeaf = skLeafObj.export({ format: "pem", type: "pkcs8" }) as string;
|
||||
|
||||
const { cipherTextBlob: encryptedCertificate } = await kmsService.encrypt({
|
||||
kmsId: keyId,
|
||||
const kmsEncryptor = await kmsService.encryptWithKmsKey({
|
||||
kmsId: certificateManagerKmsId
|
||||
});
|
||||
const { cipherTextBlob: encryptedCertificate } = kmsEncryptor({
|
||||
plainText: Buffer.from(new Uint8Array(leafCert.rawData))
|
||||
});
|
||||
|
||||
|
@@ -95,7 +95,7 @@ export type TGetCaCredentialsDTO = {
|
||||
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
||||
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||
kmsService: Pick<TKmsServiceFactory, "decrypt" | "generateKmsKey">;
|
||||
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
|
||||
};
|
||||
|
||||
export type TGetCaCertChainDTO = {
|
||||
@@ -103,7 +103,7 @@ export type TGetCaCertChainDTO = {
|
||||
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
|
||||
certificateAuthorityCertDAL: Pick<TCertificateAuthorityCertDALFactory, "findOne">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||
kmsService: Pick<TKmsServiceFactory, "decrypt" | "generateKmsKey">;
|
||||
kmsService: Pick<TKmsServiceFactory, "decryptWithKmsKey" | "generateKmsKey">;
|
||||
};
|
||||
|
||||
export type TRebuildCaCrlDTO = {
|
||||
@@ -113,7 +113,7 @@ export type TRebuildCaCrlDTO = {
|
||||
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "transaction">;
|
||||
certificateDAL: Pick<TCertificateDALFactory, "find">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "decrypt" | "encrypt">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "decryptWithKmsKey" | "encryptWithKmsKey">;
|
||||
};
|
||||
|
||||
export type TRotateCaCrlTriggerDTO = {
|
||||
|
@@ -25,7 +25,7 @@ type TCertificateServiceFactoryDep = {
|
||||
certificateAuthorityCrlDAL: Pick<TCertificateAuthorityCrlDALFactory, "update">;
|
||||
certificateAuthoritySecretDAL: Pick<TCertificateAuthoritySecretDALFactory, "findOne">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findOne" | "updateById" | "findById" | "transaction">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encrypt" | "decrypt">;
|
||||
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encryptWithKmsKey" | "decryptWithKmsKey">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
};
|
||||
|
||||
@@ -164,14 +164,16 @@ export const certificateServiceFactory = ({
|
||||
|
||||
const certBody = await certificateBodyDAL.findOne({ certId: cert.id });
|
||||
|
||||
const keyId = await getProjectKmsCertificateKeyId({
|
||||
const certificateManagerKeyId = await getProjectKmsCertificateKeyId({
|
||||
projectId: ca.projectId,
|
||||
projectDAL,
|
||||
kmsService
|
||||
});
|
||||
|
||||
const decryptedCert = await kmsService.decrypt({
|
||||
kmsId: keyId,
|
||||
const kmsDecryptor = await kmsService.decryptWithKmsKey({
|
||||
kmsId: certificateManagerKeyId
|
||||
});
|
||||
const decryptedCert = kmsDecryptor({
|
||||
cipherTextBlob: certBody.encryptedCertificate
|
||||
});
|
||||
|
||||
|
@@ -78,7 +78,10 @@ export const identityAwsAuthServiceFactory = ({
|
||||
.map((accountId) => accountId.trim())
|
||||
.some((accountId) => accountId === Account);
|
||||
|
||||
if (!isAccountAllowed) throw new UnauthorizedError();
|
||||
if (!isAccountAllowed)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: AWS account ID not allowed."
|
||||
});
|
||||
}
|
||||
|
||||
if (identityAwsAuth.allowedPrincipalArns) {
|
||||
@@ -94,7 +97,10 @@ export const identityAwsAuthServiceFactory = ({
|
||||
return regex.test(extractPrincipalArn(Arn));
|
||||
});
|
||||
|
||||
if (!isArnAllowed) throw new UnauthorizedError();
|
||||
if (!isArnAllowed)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: AWS principal ARN not allowed."
|
||||
});
|
||||
}
|
||||
|
||||
const identityAccessToken = await identityAwsAuthDAL.transaction(async (tx) => {
|
||||
|
@@ -17,6 +17,7 @@ export const validateAzureIdentity = async ({
|
||||
const jwksUri = `https://login.microsoftonline.com/${tenantId}/discovery/keys`;
|
||||
|
||||
const decodedJwt = jwt.decode(azureJwt, { complete: true }) as TDecodedAzureAuthJwt;
|
||||
|
||||
const { kid } = decodedJwt.header;
|
||||
|
||||
const { data }: { data: TAzureJwksUriResponse } = await axios.get(jwksUri);
|
||||
@@ -27,6 +28,13 @@ export const validateAzureIdentity = async ({
|
||||
|
||||
const publicKey = `-----BEGIN CERTIFICATE-----\n${signingKey.x5c[0]}\n-----END CERTIFICATE-----`;
|
||||
|
||||
// Case: This can happen when the user uses a custom resource (such as https://management.azure.com&client_id=value).
|
||||
// In this case, the audience in the decoded JWT will not have a trailing slash, but the resource will.
|
||||
if (!decodedJwt.payload.aud.endsWith("/") && resource.endsWith("/")) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
resource = resource.slice(0, -1);
|
||||
}
|
||||
|
||||
return jwt.verify(azureJwt, publicKey, {
|
||||
audience: resource,
|
||||
issuer: `https://sts.windows.net/${tenantId}/`
|
||||
|
@@ -81,7 +81,10 @@ export const identityGcpAuthServiceFactory = ({
|
||||
.map((serviceAccount) => serviceAccount.trim())
|
||||
.some((serviceAccount) => serviceAccount === gcpIdentityDetails.email);
|
||||
|
||||
if (!isServiceAccountAllowed) throw new UnauthorizedError();
|
||||
if (!isServiceAccountAllowed)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: GCP service account not allowed."
|
||||
});
|
||||
}
|
||||
|
||||
if (identityGcpAuth.type === "gce" && identityGcpAuth.allowedProjects && gcpIdentityDetails.computeEngineDetails) {
|
||||
@@ -92,7 +95,10 @@ export const identityGcpAuthServiceFactory = ({
|
||||
.map((project) => project.trim())
|
||||
.some((project) => project === gcpIdentityDetails.computeEngineDetails?.project_id);
|
||||
|
||||
if (!isProjectAllowed) throw new UnauthorizedError();
|
||||
if (!isProjectAllowed)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: GCP project not allowed."
|
||||
});
|
||||
}
|
||||
|
||||
if (identityGcpAuth.type === "gce" && identityGcpAuth.allowedZones && gcpIdentityDetails.computeEngineDetails) {
|
||||
@@ -101,7 +107,10 @@ export const identityGcpAuthServiceFactory = ({
|
||||
.map((zone) => zone.trim())
|
||||
.some((zone) => zone === gcpIdentityDetails.computeEngineDetails?.zone);
|
||||
|
||||
if (!isZoneAllowed) throw new UnauthorizedError();
|
||||
if (!isZoneAllowed)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: GCP zone not allowed."
|
||||
});
|
||||
}
|
||||
|
||||
const identityAccessToken = await identityGcpAuthDAL.transaction(async (tx) => {
|
||||
|
@@ -139,7 +139,10 @@ export const identityKubernetesAuthServiceFactory = ({
|
||||
.map((namespace) => namespace.trim())
|
||||
.some((namespace) => namespace === targetNamespace);
|
||||
|
||||
if (!isNamespaceAllowed) throw new UnauthorizedError();
|
||||
if (!isNamespaceAllowed)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: K8s namespace not allowed."
|
||||
});
|
||||
}
|
||||
|
||||
if (identityKubernetesAuth.allowedNames) {
|
||||
@@ -150,7 +153,10 @@ export const identityKubernetesAuthServiceFactory = ({
|
||||
.map((name) => name.trim())
|
||||
.some((name) => name === targetName);
|
||||
|
||||
if (!isNameAllowed) throw new UnauthorizedError();
|
||||
if (!isNameAllowed)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: K8s name not allowed."
|
||||
});
|
||||
}
|
||||
|
||||
if (identityKubernetesAuth.allowedAudience) {
|
||||
@@ -159,7 +165,10 @@ export const identityKubernetesAuthServiceFactory = ({
|
||||
(audience) => audience === identityKubernetesAuth.allowedAudience
|
||||
);
|
||||
|
||||
if (!isAudienceAllowed) throw new UnauthorizedError();
|
||||
if (!isAudienceAllowed)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: K8s audience not allowed."
|
||||
});
|
||||
}
|
||||
|
||||
const identityAccessToken = await identityKubernetesAuthDAL.transaction(async (tx) => {
|
||||
|
@@ -124,13 +124,17 @@ export const identityOidcAuthServiceFactory = ({
|
||||
|
||||
if (identityOidcAuth.boundSubject) {
|
||||
if (tokenData.sub !== identityOidcAuth.boundSubject) {
|
||||
throw new UnauthorizedError();
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: OIDC subject not allowed."
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (identityOidcAuth.boundAudiences) {
|
||||
if (!identityOidcAuth.boundAudiences.split(", ").includes(tokenData.aud)) {
|
||||
throw new UnauthorizedError();
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: OIDC audience not allowed."
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +143,9 @@ export const identityOidcAuthServiceFactory = ({
|
||||
const claimValue = (identityOidcAuth.boundClaims as Record<string, string>)[claimKey];
|
||||
// handle both single and multi-valued claims
|
||||
if (!claimValue.split(", ").some((claimEntry) => tokenData[claimKey] === claimEntry)) {
|
||||
throw new UnauthorizedError();
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Access denied: OIDC claim not allowed."
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -574,14 +574,14 @@ export const integrationAuthServiceFactory = ({
|
||||
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||
const { accessId, accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
|
||||
|
||||
AWS.config.update({
|
||||
const kms = new AWS.KMS({
|
||||
region,
|
||||
credentials: {
|
||||
accessKeyId: String(accessId),
|
||||
secretAccessKey: accessToken
|
||||
}
|
||||
});
|
||||
const kms = new AWS.KMS();
|
||||
|
||||
const aliases = await kms.listAliases({}).promise();
|
||||
|
||||
const keyAliases = aliases.Aliases!.filter((alias) => {
|
||||
|
10
backend/src/services/kms/internal-kms-dal.ts
Normal file
10
backend/src/services/kms/internal-kms-dal.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { TDbClient } from "@app/db";
|
||||
import { TableName } from "@app/db/schemas";
|
||||
import { ormify } from "@app/lib/knex";
|
||||
|
||||
export type TInternalKmsDALFactory = ReturnType<typeof internalKmsDALFactory>;
|
||||
|
||||
export const internalKmsDALFactory = (db: TDbClient) => {
|
||||
const internalKmsOrm = ormify(db, TableName.InternalKms);
|
||||
return internalKmsOrm;
|
||||
};
|
@@ -1,10 +0,0 @@
|
||||
import { TDbClient } from "@app/db";
|
||||
import { TableName } from "@app/db/schemas";
|
||||
import { ormify } from "@app/lib/knex";
|
||||
|
||||
export type TKmsDALFactory = ReturnType<typeof kmsDALFactory>;
|
||||
|
||||
export const kmsDALFactory = (db: TDbClient) => {
|
||||
const kmsOrm = ormify(db, TableName.KmsKey);
|
||||
return kmsOrm;
|
||||
};
|
64
backend/src/services/kms/kms-key-dal.ts
Normal file
64
backend/src/services/kms/kms-key-dal.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { TDbClient } from "@app/db";
|
||||
import { KmsKeysSchema, TableName } from "@app/db/schemas";
|
||||
import { DatabaseError } from "@app/lib/errors";
|
||||
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
||||
|
||||
export type TKmsKeyDALFactory = ReturnType<typeof kmskeyDALFactory>;
|
||||
|
||||
export const kmskeyDALFactory = (db: TDbClient) => {
|
||||
const kmsOrm = ormify(db, TableName.KmsKey);
|
||||
|
||||
const findByIdWithAssociatedKms = async (id: string, tx?: Knex) => {
|
||||
try {
|
||||
const result = await (tx || db.replicaNode())(TableName.KmsKey)
|
||||
.where({ [`${TableName.KmsKey}.id` as "id"]: id })
|
||||
.leftJoin(TableName.InternalKms, `${TableName.KmsKey}.id`, `${TableName.InternalKms}.kmsKeyId`)
|
||||
.leftJoin(TableName.ExternalKms, `${TableName.KmsKey}.id`, `${TableName.ExternalKms}.kmsKeyId`)
|
||||
.first()
|
||||
.select(selectAllTableCols(TableName.KmsKey))
|
||||
.select(
|
||||
db.ref("id").withSchema(TableName.InternalKms).as("internalKmsId"),
|
||||
db.ref("encryptedKey").withSchema(TableName.InternalKms).as("internalKmsEncryptedKey"),
|
||||
db.ref("encryptionAlgorithm").withSchema(TableName.InternalKms).as("internalKmsEncryptionAlgorithm"),
|
||||
db.ref("version").withSchema(TableName.InternalKms).as("internalKmsVersion"),
|
||||
db.ref("id").withSchema(TableName.InternalKms).as("internalKmsId")
|
||||
)
|
||||
.select(
|
||||
db.ref("id").withSchema(TableName.ExternalKms).as("externalKmsId"),
|
||||
db.ref("provider").withSchema(TableName.ExternalKms).as("externalKmsProvider"),
|
||||
db.ref("encryptedProviderInputs").withSchema(TableName.ExternalKms).as("externalKmsEncryptedProviderInput"),
|
||||
db.ref("status").withSchema(TableName.ExternalKms).as("externalKmsStatus"),
|
||||
db.ref("statusDetails").withSchema(TableName.ExternalKms).as("externalKmsStatusDetails")
|
||||
);
|
||||
|
||||
const data = {
|
||||
...KmsKeysSchema.parse(result),
|
||||
isExternal: Boolean(result?.externalKmsId),
|
||||
externalKms: result?.externalKmsId
|
||||
? {
|
||||
id: result.externalKmsId,
|
||||
provider: result.externalKmsProvider,
|
||||
encryptedProviderInput: result.externalKmsEncryptedProviderInput,
|
||||
status: result.externalKmsStatus,
|
||||
statusDetails: result.externalKmsStatusDetails
|
||||
}
|
||||
: undefined,
|
||||
internalKms: result?.internalKmsId
|
||||
? {
|
||||
id: result.internalKmsId,
|
||||
encryptedKey: result.internalKmsEncryptedKey,
|
||||
encryptionAlgorithm: result.internalKmsEncryptionAlgorithm,
|
||||
version: result.internalKmsVersion
|
||||
}
|
||||
: undefined
|
||||
};
|
||||
return data;
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "Find by id" });
|
||||
}
|
||||
};
|
||||
|
||||
return { ...kmsOrm, findByIdWithAssociatedKms };
|
||||
};
|
@@ -1,18 +1,34 @@
|
||||
import slugify from "@sindresorhus/slugify";
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { randomSecureBytes } from "@app/lib/crypto";
|
||||
import { symmetricCipherService, SymmetricEncryption } from "@app/lib/crypto/cipher";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
|
||||
import { TKmsDALFactory } from "./kms-dal";
|
||||
import { TOrgDALFactory } from "../org/org-dal";
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
import { TInternalKmsDALFactory } from "./internal-kms-dal";
|
||||
import { TKmsKeyDALFactory } from "./kms-key-dal";
|
||||
import { TKmsRootConfigDALFactory } from "./kms-root-config-dal";
|
||||
import { TDecryptWithKmsDTO, TEncryptWithKmsDTO, TGenerateKMSDTO } from "./kms-types";
|
||||
import {
|
||||
TDecryptWithKeyDTO,
|
||||
TDecryptWithKmsDTO,
|
||||
TEncryptionWithKeyDTO,
|
||||
TEncryptWithKmsDTO,
|
||||
TGenerateKMSDTO
|
||||
} from "./kms-types";
|
||||
|
||||
type TKmsServiceFactoryDep = {
|
||||
kmsDAL: TKmsDALFactory;
|
||||
kmsDAL: TKmsKeyDALFactory;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById" | "updateById" | "transaction">;
|
||||
orgDAL: Pick<TOrgDALFactory, "findById" | "updateById" | "transaction">;
|
||||
kmsRootConfigDAL: Pick<TKmsRootConfigDALFactory, "findById" | "create">;
|
||||
keyStore: Pick<TKeyStoreFactory, "acquireLock" | "waitTillReady" | "setItemWithExpiry">;
|
||||
internalKmsDAL: Pick<TInternalKmsDALFactory, "create">;
|
||||
};
|
||||
|
||||
export type TKmsServiceFactory = ReturnType<typeof kmsServiceFactory>;
|
||||
@@ -25,54 +41,161 @@ const KMS_ROOT_CREATION_WAIT_TIME = 10;
|
||||
// akhilmhdh: Don't edit this value. This is measured for blob concatination in kms
|
||||
const KMS_VERSION = "v01";
|
||||
const KMS_VERSION_BLOB_LENGTH = 3;
|
||||
export const kmsServiceFactory = ({ kmsDAL, kmsRootConfigDAL, keyStore }: TKmsServiceFactoryDep) => {
|
||||
export const kmsServiceFactory = ({
|
||||
kmsDAL,
|
||||
kmsRootConfigDAL,
|
||||
keyStore,
|
||||
internalKmsDAL,
|
||||
orgDAL,
|
||||
projectDAL
|
||||
}: TKmsServiceFactoryDep) => {
|
||||
let ROOT_ENCRYPTION_KEY = Buffer.alloc(0);
|
||||
|
||||
// this is used symmetric encryption
|
||||
const generateKmsKey = async ({ scopeId, scopeType, isReserved = true, tx }: TGenerateKMSDTO) => {
|
||||
const generateKmsKey = async ({ orgId, isReserved = true, tx, slug }: TGenerateKMSDTO) => {
|
||||
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||
const kmsKeyMaterial = randomSecureBytes(32);
|
||||
const encryptedKeyMaterial = cipher.encrypt(kmsKeyMaterial, ROOT_ENCRYPTION_KEY);
|
||||
const sanitizedSlug = slug ? slugify(slug) : slugify(alphaNumericNanoId(8).toLowerCase());
|
||||
const dbQuery = async (db: Knex) => {
|
||||
const kmsDoc = await kmsDAL.create(
|
||||
{
|
||||
slug: sanitizedSlug,
|
||||
orgId,
|
||||
isReserved
|
||||
},
|
||||
db
|
||||
);
|
||||
|
||||
const { encryptedKey, ...doc } = await kmsDAL.create(
|
||||
{
|
||||
version: 1,
|
||||
encryptedKey: encryptedKeyMaterial,
|
||||
encryptionAlgorithm: SymmetricEncryption.AES_GCM_256,
|
||||
isReserved,
|
||||
orgId: scopeType === "org" ? scopeId : undefined,
|
||||
projectId: scopeType === "project" ? scopeId : undefined
|
||||
},
|
||||
tx
|
||||
);
|
||||
await internalKmsDAL.create(
|
||||
{
|
||||
version: 1,
|
||||
encryptedKey: encryptedKeyMaterial,
|
||||
encryptionAlgorithm: SymmetricEncryption.AES_GCM_256,
|
||||
kmsKeyId: kmsDoc.id
|
||||
},
|
||||
db
|
||||
);
|
||||
return kmsDoc;
|
||||
};
|
||||
if (tx) return dbQuery(tx);
|
||||
const doc = await kmsDAL.transaction(async (tx2) => dbQuery(tx2));
|
||||
return doc;
|
||||
};
|
||||
|
||||
const encrypt = async ({ kmsId, plainText }: TEncryptWithKmsDTO) => {
|
||||
const kmsDoc = await kmsDAL.findById(kmsId);
|
||||
const encryptWithKmsKey = async ({ kmsId }: Omit<TEncryptWithKmsDTO, "plainText">) => {
|
||||
const kmsDoc = await kmsDAL.findByIdWithAssociatedKms(kmsId);
|
||||
if (!kmsDoc) throw new BadRequestError({ message: "KMS ID not found" });
|
||||
// akhilmhdh: as more encryption are added do a check here on kmsDoc.encryptionAlgorithm
|
||||
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||
return ({ plainText }: Pick<TEncryptWithKmsDTO, "plainText">) => {
|
||||
const kmsKey = cipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
|
||||
const encryptedPlainTextBlob = cipher.encrypt(plainText, kmsKey);
|
||||
|
||||
const kmsKey = cipher.decrypt(kmsDoc.encryptedKey, ROOT_ENCRYPTION_KEY);
|
||||
const encryptedPlainTextBlob = cipher.encrypt(plainText, kmsKey);
|
||||
|
||||
// Buffer#1 encrypted text + Buffer#2 version number
|
||||
const versionBlob = Buffer.from(KMS_VERSION, "utf8"); // length is 3
|
||||
const cipherTextBlob = Buffer.concat([encryptedPlainTextBlob, versionBlob]);
|
||||
return { cipherTextBlob };
|
||||
// Buffer#1 encrypted text + Buffer#2 version number
|
||||
const versionBlob = Buffer.from(KMS_VERSION, "utf8"); // length is 3
|
||||
const cipherTextBlob = Buffer.concat([encryptedPlainTextBlob, versionBlob]);
|
||||
return { cipherTextBlob };
|
||||
};
|
||||
};
|
||||
|
||||
const decrypt = async ({ cipherTextBlob: versionedCipherTextBlob, kmsId }: TDecryptWithKmsDTO) => {
|
||||
const kmsDoc = await kmsDAL.findById(kmsId);
|
||||
if (!kmsDoc) throw new BadRequestError({ message: "KMS ID not found" });
|
||||
const encryptWithInputKey = async ({ key }: Omit<TEncryptionWithKeyDTO, "plainText">) => {
|
||||
// akhilmhdh: as more encryption are added do a check here on kmsDoc.encryptionAlgorithm
|
||||
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||
const kmsKey = cipher.decrypt(kmsDoc.encryptedKey, ROOT_ENCRYPTION_KEY);
|
||||
return ({ plainText }: Pick<TEncryptWithKmsDTO, "plainText">) => {
|
||||
const encryptedPlainTextBlob = cipher.encrypt(plainText, key);
|
||||
// Buffer#1 encrypted text + Buffer#2 version number
|
||||
const versionBlob = Buffer.from(KMS_VERSION, "utf8"); // length is 3
|
||||
const cipherTextBlob = Buffer.concat([encryptedPlainTextBlob, versionBlob]);
|
||||
return { cipherTextBlob };
|
||||
};
|
||||
};
|
||||
|
||||
const cipherTextBlob = versionedCipherTextBlob.subarray(0, -KMS_VERSION_BLOB_LENGTH);
|
||||
const decryptedBlob = cipher.decrypt(cipherTextBlob, kmsKey);
|
||||
return decryptedBlob;
|
||||
const decryptWithKmsKey = async ({ kmsId }: Omit<TDecryptWithKmsDTO, "cipherTextBlob">) => {
|
||||
const kmsDoc = await kmsDAL.findByIdWithAssociatedKms(kmsId);
|
||||
if (!kmsDoc) throw new BadRequestError({ message: "KMS ID not found" });
|
||||
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||
const kmsKey = cipher.decrypt(kmsDoc.internalKms?.encryptedKey as Buffer, ROOT_ENCRYPTION_KEY);
|
||||
|
||||
return ({ cipherTextBlob: versionedCipherTextBlob }: Pick<TDecryptWithKmsDTO, "cipherTextBlob">) => {
|
||||
const cipherTextBlob = versionedCipherTextBlob.subarray(0, -KMS_VERSION_BLOB_LENGTH);
|
||||
const decryptedBlob = cipher.decrypt(cipherTextBlob, kmsKey);
|
||||
return decryptedBlob;
|
||||
};
|
||||
};
|
||||
|
||||
const decryptWithInputKey = async ({ key }: Omit<TDecryptWithKeyDTO, "cipherTextBlob">) => {
|
||||
const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256);
|
||||
|
||||
return ({ cipherTextBlob: versionedCipherTextBlob }: Pick<TDecryptWithKeyDTO, "cipherTextBlob">) => {
|
||||
const cipherTextBlob = versionedCipherTextBlob.subarray(0, -KMS_VERSION_BLOB_LENGTH);
|
||||
const decryptedBlob = cipher.decrypt(cipherTextBlob, key);
|
||||
return decryptedBlob;
|
||||
};
|
||||
};
|
||||
|
||||
const getOrgKmsKeyId = async (orgId: string) => {
|
||||
const keyId = await orgDAL.transaction(async (tx) => {
|
||||
const org = await orgDAL.findById(orgId, tx);
|
||||
if (!org) {
|
||||
throw new BadRequestError({ message: "Org not found" });
|
||||
}
|
||||
|
||||
if (!org.kmsDefaultKeyId) {
|
||||
// create default kms key for certificate service
|
||||
const key = await generateKmsKey({
|
||||
isReserved: true,
|
||||
orgId: org.id,
|
||||
tx
|
||||
});
|
||||
|
||||
await orgDAL.updateById(
|
||||
org.id,
|
||||
{
|
||||
kmsDefaultKeyId: key.id
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
return key.id;
|
||||
}
|
||||
|
||||
return org.kmsDefaultKeyId;
|
||||
});
|
||||
|
||||
return keyId;
|
||||
};
|
||||
|
||||
const getProjectSecretManagerKmsKeyId = async (projectId: string) => {
|
||||
const keyId = await projectDAL.transaction(async (tx) => {
|
||||
const project = await projectDAL.findById(projectId, tx);
|
||||
if (!project) {
|
||||
throw new BadRequestError({ message: "Project not found" });
|
||||
}
|
||||
|
||||
if (!project.kmsSecretManagerKeyId) {
|
||||
// create default kms key for certificate service
|
||||
const key = await generateKmsKey({
|
||||
isReserved: true,
|
||||
orgId: project.orgId,
|
||||
tx
|
||||
});
|
||||
|
||||
await projectDAL.updateById(
|
||||
projectId,
|
||||
{
|
||||
kmsSecretManagerKeyId: key.id
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
return key.id;
|
||||
}
|
||||
|
||||
return project.kmsSecretManagerKeyId;
|
||||
});
|
||||
|
||||
return keyId;
|
||||
};
|
||||
|
||||
const startService = async () => {
|
||||
@@ -123,7 +246,11 @@ export const kmsServiceFactory = ({ kmsDAL, kmsRootConfigDAL, keyStore }: TKmsSe
|
||||
return {
|
||||
startService,
|
||||
generateKmsKey,
|
||||
encrypt,
|
||||
decrypt
|
||||
encryptWithKmsKey,
|
||||
encryptWithInputKey,
|
||||
decryptWithKmsKey,
|
||||
decryptWithInputKey,
|
||||
getOrgKmsKeyId,
|
||||
getProjectSecretManagerKmsKeyId
|
||||
};
|
||||
};
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { Knex } from "knex";
|
||||
|
||||
export type TGenerateKMSDTO = {
|
||||
scopeType: "project" | "org";
|
||||
scopeId: string;
|
||||
orgId: string;
|
||||
isReserved?: boolean;
|
||||
slug?: string;
|
||||
tx?: Knex;
|
||||
};
|
||||
|
||||
@@ -12,7 +12,17 @@ export type TEncryptWithKmsDTO = {
|
||||
plainText: Buffer;
|
||||
};
|
||||
|
||||
export type TEncryptionWithKeyDTO = {
|
||||
key: Buffer;
|
||||
plainText: Buffer;
|
||||
};
|
||||
|
||||
export type TDecryptWithKmsDTO = {
|
||||
kmsId: string;
|
||||
cipherTextBlob: Buffer;
|
||||
};
|
||||
|
||||
export type TDecryptWithKeyDTO = {
|
||||
key: Buffer;
|
||||
cipherTextBlob: Buffer;
|
||||
};
|
||||
|
@@ -207,9 +207,9 @@ export const orgDALFactory = (db: TDbClient) => {
|
||||
}
|
||||
};
|
||||
|
||||
const updateById = async (orgId: string, data: Partial<TOrganizations>) => {
|
||||
const updateById = async (orgId: string, data: Partial<TOrganizations>, tx?: Knex) => {
|
||||
try {
|
||||
const [org] = await db(TableName.Organization)
|
||||
const [org] = await (tx || db)(TableName.Organization)
|
||||
.where({ id: orgId })
|
||||
.update({ ...data })
|
||||
.returning("*");
|
||||
|
@@ -144,10 +144,7 @@ export const orgServiceFactory = ({
|
||||
return members;
|
||||
};
|
||||
|
||||
const findAllWorkspaces = async ({ actor, actorId, actorOrgId, actorAuthMethod, orgId }: TFindAllWorkspacesDTO) => {
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Workspace);
|
||||
|
||||
const findAllWorkspaces = async ({ actor, actorId, orgId }: TFindAllWorkspacesDTO) => {
|
||||
const organizationWorkspaceIds = new Set((await projectDAL.find({ orgId })).map((workspace) => workspace.id));
|
||||
|
||||
let workspaces: (TProjects & { organization: string } & {
|
||||
|
@@ -71,9 +71,8 @@ export const getProjectKmsCertificateKeyId = async ({
|
||||
if (!project.kmsCertificateKeyId) {
|
||||
// create default kms key for certificate service
|
||||
const key = await kmsService.generateKmsKey({
|
||||
scopeId: projectId,
|
||||
scopeType: "project",
|
||||
isReserved: true,
|
||||
orgId: project.orgId,
|
||||
tx
|
||||
});
|
||||
|
||||
|
@@ -322,7 +322,7 @@ export const secretFolderDALFactory = (db: TDbClient) => {
|
||||
.first();
|
||||
if (folder) {
|
||||
const { envId, envName, envSlug, ...el } = folder;
|
||||
return { ...el, environment: { envId, envName, envSlug } };
|
||||
return { ...el, environment: { envId, envName, envSlug }, envId };
|
||||
}
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "Find by id" });
|
||||
|
@@ -6,7 +6,7 @@ import { TSecretFoldersInsert } from "@app/db/schemas";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||
@@ -14,6 +14,7 @@ import { TSecretFolderDALFactory } from "./secret-folder-dal";
|
||||
import {
|
||||
TCreateFolderDTO,
|
||||
TDeleteFolderDTO,
|
||||
TGetFolderByIdDTO,
|
||||
TGetFolderDTO,
|
||||
TUpdateFolderDTO,
|
||||
TUpdateManyFoldersDTO
|
||||
@@ -368,11 +369,22 @@ export const secretFolderServiceFactory = ({
|
||||
return folders;
|
||||
};
|
||||
|
||||
const getFolderById = async ({ actor, actorId, actorOrgId, actorAuthMethod, id }: TGetFolderByIdDTO) => {
|
||||
const folder = await folderDAL.findById(id);
|
||||
if (!folder) throw new NotFoundError({ message: "folder not found" });
|
||||
// folder list is allowed to be read by anyone
|
||||
// permission to check does user has access
|
||||
await permissionService.getProjectPermission(actor, actorId, folder.projectId, actorAuthMethod, actorOrgId);
|
||||
|
||||
return folder;
|
||||
};
|
||||
|
||||
return {
|
||||
createFolder,
|
||||
updateFolder,
|
||||
updateManyFolders,
|
||||
deleteFolder,
|
||||
getFolders
|
||||
getFolders,
|
||||
getFolderById
|
||||
};
|
||||
};
|
||||
|
@@ -37,3 +37,7 @@ export type TGetFolderDTO = {
|
||||
environment: string;
|
||||
path: string;
|
||||
} & TProjectPermission;
|
||||
|
||||
export type TGetFolderByIdDTO = {
|
||||
id: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
@@ -642,7 +642,7 @@ export const secretQueueFactory = ({
|
||||
});
|
||||
|
||||
queueService.start(QueueName.SecretWebhook, async (job) => {
|
||||
await fnTriggerWebhook({ ...job.data, projectEnvDAL, webhookDAL });
|
||||
await fnTriggerWebhook({ ...job.data, projectEnvDAL, webhookDAL, projectDAL });
|
||||
});
|
||||
|
||||
return {
|
||||
|
@@ -9,6 +9,7 @@ import { infisicalSymmetricDecrypt } from "@app/lib/crypto/encryption";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { logger } from "@app/lib/logger";
|
||||
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||
import { TWebhookDALFactory } from "./webhook-dal";
|
||||
import { WebhookType } from "./webhook-types";
|
||||
@@ -66,11 +67,16 @@ export const triggerWebhookRequest = async (webhook: TWebhooks, data: Record<str
|
||||
|
||||
export const getWebhookPayload = (
|
||||
eventName: string,
|
||||
workspaceId: string,
|
||||
environment: string,
|
||||
secretPath?: string,
|
||||
type?: string | null
|
||||
details: {
|
||||
workspaceName: string;
|
||||
workspaceId: string;
|
||||
environment: string;
|
||||
secretPath?: string;
|
||||
type?: string | null;
|
||||
}
|
||||
) => {
|
||||
const { workspaceName, workspaceId, environment, secretPath, type } = details;
|
||||
|
||||
switch (type) {
|
||||
case WebhookType.SLACK:
|
||||
return {
|
||||
@@ -80,8 +86,8 @@ export const getWebhookPayload = (
|
||||
color: "#E7F256",
|
||||
fields: [
|
||||
{
|
||||
title: "Workspace ID",
|
||||
value: workspaceId,
|
||||
title: "Project",
|
||||
value: workspaceName,
|
||||
short: false
|
||||
},
|
||||
{
|
||||
@@ -117,7 +123,9 @@ export type TFnTriggerWebhookDTO = {
|
||||
environment: string;
|
||||
webhookDAL: Pick<TWebhookDALFactory, "findAllWebhooks" | "transaction" | "update" | "bulkUpdate">;
|
||||
projectEnvDAL: Pick<TProjectEnvDALFactory, "findOne">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById">;
|
||||
};
|
||||
|
||||
// this is reusable function
|
||||
// used in secret queue to trigger webhook and update status when secrets changes
|
||||
export const fnTriggerWebhook = async ({
|
||||
@@ -125,7 +133,8 @@ export const fnTriggerWebhook = async ({
|
||||
secretPath,
|
||||
projectId,
|
||||
webhookDAL,
|
||||
projectEnvDAL
|
||||
projectEnvDAL,
|
||||
projectDAL
|
||||
}: TFnTriggerWebhookDTO) => {
|
||||
const webhooks = await webhookDAL.findAllWebhooks(projectId, environment);
|
||||
const toBeTriggeredHooks = webhooks.filter(
|
||||
@@ -134,9 +143,19 @@ export const fnTriggerWebhook = async ({
|
||||
);
|
||||
if (!toBeTriggeredHooks.length) return;
|
||||
logger.info("Secret webhook job started", { environment, secretPath, projectId });
|
||||
const project = await projectDAL.findById(projectId);
|
||||
const webhooksTriggered = await Promise.allSettled(
|
||||
toBeTriggeredHooks.map((hook) =>
|
||||
triggerWebhookRequest(hook, getWebhookPayload("secrets.modified", projectId, environment, secretPath, hook.type))
|
||||
triggerWebhookRequest(
|
||||
hook,
|
||||
getWebhookPayload("secrets.modified", {
|
||||
workspaceName: project.name,
|
||||
workspaceId: projectId,
|
||||
environment,
|
||||
secretPath,
|
||||
type: hook.type
|
||||
})
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
@@ -6,6 +6,7 @@ import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services
|
||||
import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||
import { TWebhookDALFactory } from "./webhook-dal";
|
||||
import { decryptWebhookDetails, getWebhookPayload, triggerWebhookRequest } from "./webhook-fns";
|
||||
@@ -20,12 +21,18 @@ import {
|
||||
type TWebhookServiceFactoryDep = {
|
||||
webhookDAL: TWebhookDALFactory;
|
||||
projectEnvDAL: TProjectEnvDALFactory;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
};
|
||||
|
||||
export type TWebhookServiceFactory = ReturnType<typeof webhookServiceFactory>;
|
||||
|
||||
export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionService }: TWebhookServiceFactoryDep) => {
|
||||
export const webhookServiceFactory = ({
|
||||
webhookDAL,
|
||||
projectEnvDAL,
|
||||
permissionService,
|
||||
projectDAL
|
||||
}: TWebhookServiceFactoryDep) => {
|
||||
const createWebhook = async ({
|
||||
actor,
|
||||
actorId,
|
||||
@@ -124,13 +131,21 @@ export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionSer
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks);
|
||||
|
||||
const project = await projectDAL.findById(webhook.projectId);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks);
|
||||
let webhookError: string | undefined;
|
||||
try {
|
||||
await triggerWebhookRequest(
|
||||
webhook,
|
||||
getWebhookPayload("test", webhook.projectId, webhook.environment.slug, webhook.secretPath, webhook.type)
|
||||
getWebhookPayload("test", {
|
||||
workspaceName: project.name,
|
||||
workspaceId: webhook.projectId,
|
||||
environment: webhook.environment.slug,
|
||||
secretPath: webhook.secretPath,
|
||||
type: webhook.type
|
||||
})
|
||||
);
|
||||
} catch (err) {
|
||||
webhookError = (err as Error).message;
|
||||
|
@@ -19,7 +19,7 @@ require (
|
||||
github.com/petar-dambovaliev/aho-corasick v0.0.0-20211021192214-5ab2d9280aa9
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
|
||||
github.com/posthog/posthog-go v0.0.0-20221221115252-24dfed35d71a
|
||||
github.com/rs/cors v1.9.0
|
||||
github.com/rs/cors v1.11.0
|
||||
github.com/rs/zerolog v1.26.1
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/viper v1.8.1
|
||||
|
@@ -356,8 +356,8 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=
|
||||
github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
|
||||
github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc=
|
||||
github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc=
|
||||
|
50
company/handbook/hiring.mdx
Normal file
50
company/handbook/hiring.mdx
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
title: "Hiring"
|
||||
sidebarTitle: "Hiring"
|
||||
description: "The guide to hiring at Infisical."
|
||||
---
|
||||
|
||||
Infisical is actively growing and we are hiring for many positions at any given time. This page describes some details of the hiring process we have.
|
||||
|
||||
## Strategy
|
||||
|
||||
Infisical recruitment strategy relies on 100% inbound interest by default. Many of our team members have previously used Infisical or contributed to our [open source project](https://github.com/Infisical/infisical). This allows us to hire the best candidates who are most interested in working at Infisical.
|
||||
|
||||
## Geography
|
||||
|
||||
Infisical is a remote-first company, and we have team members across the whole globe. That being said, there are some legal and accounting limitations that we need to abide by. As a result, we are currently only open to hiring from the following countries:
|
||||
|
||||
- Australia
|
||||
- Austria
|
||||
- Belgium
|
||||
- Brazil
|
||||
- Canada
|
||||
- Chile
|
||||
- Costa Rica
|
||||
- Denmark
|
||||
- Finland
|
||||
- France
|
||||
- Germany
|
||||
- India
|
||||
- Ireland
|
||||
- Israel
|
||||
- Italy
|
||||
- Japan
|
||||
- Kenya
|
||||
- Latvia
|
||||
- Luxembourg
|
||||
- Mexico
|
||||
- Netherlands
|
||||
- New Zealand
|
||||
- Philippines
|
||||
- Poland
|
||||
- Portugal
|
||||
- Singapore
|
||||
- South Africa
|
||||
- South Korea
|
||||
- Spain
|
||||
- Switzerland
|
||||
- Sweden
|
||||
- UAE
|
||||
- United Kingdom
|
||||
- United States
|
@@ -58,7 +58,8 @@
|
||||
"pages": [
|
||||
"handbook/onboarding",
|
||||
"handbook/spending-money",
|
||||
"handbook/time-off"
|
||||
"handbook/time-off",
|
||||
"handbook/hiring"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
4
docs/api-reference/endpoints/folders/get-by-id.mdx
Normal file
4
docs/api-reference/endpoints/folders/get-by-id.mdx
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: "Get by ID"
|
||||
openapi: "GET /api/v1/folders/{id}"
|
||||
---
|
@@ -122,6 +122,7 @@ spec:
|
||||
# Azure Auth
|
||||
azureAuth:
|
||||
identityId: <your-machine-identity-id>
|
||||
resource: https://management.azure.com/&client_id=CLIENT_ID # (Optional) This is the Azure resource that you want to access. For example, "https://management.azure.com/". If no value is provided, it will default to "https://management.azure.com/"
|
||||
|
||||
# secretsScope is identical to the secrets scope in the universalAuth field in this sample.
|
||||
secretsScope:
|
||||
|
@@ -576,6 +576,7 @@
|
||||
"group": "Folders",
|
||||
"pages": [
|
||||
"api-reference/endpoints/folders/list",
|
||||
"api-reference/endpoints/folders/get-by-id",
|
||||
"api-reference/endpoints/folders/create",
|
||||
"api-reference/endpoints/folders/update",
|
||||
"api-reference/endpoints/folders/delete"
|
||||
|
483
frontend/package-lock.json
generated
483
frontend/package-lock.json
generated
@@ -47,7 +47,7 @@
|
||||
"@ucast/mongo2js": "^1.3.4",
|
||||
"add": "^2.0.6",
|
||||
"argon2-browser": "^1.18.0",
|
||||
"axios": "^0.27.2",
|
||||
"axios": "^0.28.0",
|
||||
"axios-auth-refresh": "^3.3.6",
|
||||
"base64-loader": "^1.0.0",
|
||||
"classnames": "^2.3.1",
|
||||
@@ -139,7 +139,7 @@
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "^2.8.3",
|
||||
"prettier-plugin-tailwindcss": "^0.2.2",
|
||||
"storybook": "^7.5.2",
|
||||
"storybook": "^7.6.20",
|
||||
"storybook-dark-mode": "^3.0.0",
|
||||
"tailwindcss": "3.2",
|
||||
"typescript": "^4.9.3"
|
||||
@@ -6200,15 +6200,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/builder-manager": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.6.19.tgz",
|
||||
"integrity": "sha512-Dt5OLh97xeWh4h2mk9uG0SbCxBKHPhIiHLHAKEIDzIZBdwUhuyncVNDPHW2NlXM+S7U0/iKs2tw05waqh2lHvg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.6.20.tgz",
|
||||
"integrity": "sha512-e2GzpjLaw6CM/XSmc4qJRzBF8GOoOyotyu3JrSPTYOt4RD8kjUsK4QlismQM1DQRu8i39aIexxmRbiJyD74xzQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
||||
"@storybook/core-common": "7.6.19",
|
||||
"@storybook/manager": "7.6.19",
|
||||
"@storybook/node-logger": "7.6.19",
|
||||
"@storybook/core-common": "7.6.20",
|
||||
"@storybook/manager": "7.6.20",
|
||||
"@storybook/node-logger": "7.6.20",
|
||||
"@types/ejs": "^3.1.1",
|
||||
"@types/find-cache-dir": "^3.2.1",
|
||||
"@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10",
|
||||
@@ -6228,13 +6228,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/builder-manager/node_modules/@storybook/channels": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.19.tgz",
|
||||
"integrity": "sha512-2JGh+i95GwjtjqWqhtEh15jM5ifwbRGmXeFqkY7dpdHH50EEWafYHr2mg3opK3heVDwg0rJ/VBptkmshloXuvA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.20.tgz",
|
||||
"integrity": "sha512-4hkgPSH6bJclB2OvLnkZOGZW1WptJs09mhQ6j6qLjgBZzL/ZdD6priWSd7iXrmPiN5TzUobkG4P4Dp7FjkiO7A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/client-logger": "7.6.19",
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/client-logger": "7.6.20",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/global": "^5.0.0",
|
||||
"qs": "^6.10.0",
|
||||
"telejson": "^7.2.0",
|
||||
@@ -6246,9 +6246,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/builder-manager/node_modules/@storybook/client-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-oGzOxbmLmciSIfd5gsxDzPmX8DttWhoYdPKxjMuCuWLTO2TWpkCWp1FTUMWO72mm/6V/FswT/aqpJJBBvdZ3RQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-NwG0VIJQCmKrSaN5GBDFyQgTAHLNishUPLW1NrzqTDNAhfZUoef64rPQlinbopa0H4OXmlB+QxbQIb3ubeXmSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/global": "^5.0.0"
|
||||
@@ -6259,14 +6259,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/builder-manager/node_modules/@storybook/core-common": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.19.tgz",
|
||||
"integrity": "sha512-njwpGzFJrfbJr/AFxGP8KMrfPfxN85KOfSlxYnQwRm5Z0H1D/lT33LhEBf5m37gaGawHeG7KryxO6RvaioMt2Q==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.20.tgz",
|
||||
"integrity": "sha512-8H1zPWPjcmeD4HbDm4FDD0WLsfAKGVr566IZ4hG+h3iWVW57II9JW9MLBtiR2LPSd8u7o0kw64lwRGmtCO1qAw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/node-logger": "7.6.19",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/node-logger": "7.6.20",
|
||||
"@storybook/types": "7.6.20",
|
||||
"@types/find-cache-dir": "^3.2.1",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/node-fetch": "^2.6.4",
|
||||
@@ -6294,9 +6294,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/builder-manager/node_modules/@storybook/core-events": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.19.tgz",
|
||||
"integrity": "sha512-K/W6Uvum0ocZSgjbi8hiotpe+wDEHDZlvN+KlPqdh9ae9xDK8aBNBq9IelCoqM+uKO1Zj+dDfSQds7CD781DJg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.20.tgz",
|
||||
"integrity": "sha512-tlVDuVbDiNkvPDFAu+0ou3xBBYbx9zUURQz4G9fAq0ScgBOs/bpzcRrFb4mLpemUViBAd47tfZKdH4MAX45KVQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ts-dedent": "^2.0.0"
|
||||
@@ -6307,9 +6307,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/builder-manager/node_modules/@storybook/node-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-2g29QC44Zl1jKY37DmQ0/dO7+VSKnGgPI/x0mwVwQffypSapxH3rwLLT5Q5XLHeFyD+fhRu5w9Cj4vTGynJgpA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-l2i4qF1bscJkOplNffcRTsgQWYR7J51ewmizj5YrTM8BK6rslWT1RntgVJWB1RgPqvx6VsCz1gyP3yW1oKxvYw==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -6317,12 +6317,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/builder-manager/node_modules/@storybook/types": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.19.tgz",
|
||||
"integrity": "sha512-DeGYrRPRMGTVfT7o2rEZtRzyLT2yKTI2exgpnxbwPWEFAduZCSfzBrcBXZ/nb5B0pjA9tUNWls1YzGkJGlkhpg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.20.tgz",
|
||||
"integrity": "sha512-GncdY3x0LpbhmUAAJwXYtJDUQEwfF175gsjH0/fxPkxPoV7Sef9TM41jQLJW/5+6TnZoCZP/+aJZTJtq3ni23Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/channels": "7.6.19",
|
||||
"@storybook/channels": "7.6.20",
|
||||
"@types/babel__core": "^7.0.0",
|
||||
"@types/express": "^4.7.0",
|
||||
"file-system-cache": "2.3.0"
|
||||
@@ -6438,23 +6438,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/cli": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.6.19.tgz",
|
||||
"integrity": "sha512-7OVy7nPgkLfgivv6/dmvoyU6pKl9EzWFk+g9izyQHiM/jS8jOiEyn6akG8Ebj6k5pWslo5lgiXUSW+cEEZUnqQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.6.20.tgz",
|
||||
"integrity": "sha512-ZlP+BJyqg7HlnXf7ypjG2CKMI/KVOn03jFIiClItE/jQfgR6kRFgtjRU7uajh427HHfjv9DRiur8nBzuO7vapA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.23.2",
|
||||
"@babel/preset-env": "^7.23.2",
|
||||
"@babel/types": "^7.23.0",
|
||||
"@ndelangen/get-tarball": "^3.0.7",
|
||||
"@storybook/codemod": "7.6.19",
|
||||
"@storybook/core-common": "7.6.19",
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/core-server": "7.6.19",
|
||||
"@storybook/csf-tools": "7.6.19",
|
||||
"@storybook/node-logger": "7.6.19",
|
||||
"@storybook/telemetry": "7.6.19",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/codemod": "7.6.20",
|
||||
"@storybook/core-common": "7.6.20",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/core-server": "7.6.20",
|
||||
"@storybook/csf-tools": "7.6.20",
|
||||
"@storybook/node-logger": "7.6.20",
|
||||
"@storybook/telemetry": "7.6.20",
|
||||
"@storybook/types": "7.6.20",
|
||||
"@types/semver": "^7.3.4",
|
||||
"@yarnpkg/fslib": "2.10.3",
|
||||
"@yarnpkg/libzip": "2.3.0",
|
||||
@@ -6494,13 +6494,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/cli/node_modules/@storybook/channels": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.19.tgz",
|
||||
"integrity": "sha512-2JGh+i95GwjtjqWqhtEh15jM5ifwbRGmXeFqkY7dpdHH50EEWafYHr2mg3opK3heVDwg0rJ/VBptkmshloXuvA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.20.tgz",
|
||||
"integrity": "sha512-4hkgPSH6bJclB2OvLnkZOGZW1WptJs09mhQ6j6qLjgBZzL/ZdD6priWSd7iXrmPiN5TzUobkG4P4Dp7FjkiO7A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/client-logger": "7.6.19",
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/client-logger": "7.6.20",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/global": "^5.0.0",
|
||||
"qs": "^6.10.0",
|
||||
"telejson": "^7.2.0",
|
||||
@@ -6512,9 +6512,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/cli/node_modules/@storybook/client-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-oGzOxbmLmciSIfd5gsxDzPmX8DttWhoYdPKxjMuCuWLTO2TWpkCWp1FTUMWO72mm/6V/FswT/aqpJJBBvdZ3RQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-NwG0VIJQCmKrSaN5GBDFyQgTAHLNishUPLW1NrzqTDNAhfZUoef64rPQlinbopa0H4OXmlB+QxbQIb3ubeXmSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/global": "^5.0.0"
|
||||
@@ -6525,14 +6525,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/cli/node_modules/@storybook/core-common": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.19.tgz",
|
||||
"integrity": "sha512-njwpGzFJrfbJr/AFxGP8KMrfPfxN85KOfSlxYnQwRm5Z0H1D/lT33LhEBf5m37gaGawHeG7KryxO6RvaioMt2Q==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.20.tgz",
|
||||
"integrity": "sha512-8H1zPWPjcmeD4HbDm4FDD0WLsfAKGVr566IZ4hG+h3iWVW57II9JW9MLBtiR2LPSd8u7o0kw64lwRGmtCO1qAw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/node-logger": "7.6.19",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/node-logger": "7.6.20",
|
||||
"@storybook/types": "7.6.20",
|
||||
"@types/find-cache-dir": "^3.2.1",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/node-fetch": "^2.6.4",
|
||||
@@ -6560,9 +6560,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/cli/node_modules/@storybook/core-events": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.19.tgz",
|
||||
"integrity": "sha512-K/W6Uvum0ocZSgjbi8hiotpe+wDEHDZlvN+KlPqdh9ae9xDK8aBNBq9IelCoqM+uKO1Zj+dDfSQds7CD781DJg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.20.tgz",
|
||||
"integrity": "sha512-tlVDuVbDiNkvPDFAu+0ou3xBBYbx9zUURQz4G9fAq0ScgBOs/bpzcRrFb4mLpemUViBAd47tfZKdH4MAX45KVQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ts-dedent": "^2.0.0"
|
||||
@@ -6573,9 +6573,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/cli/node_modules/@storybook/csf-tools": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.19.tgz",
|
||||
"integrity": "sha512-8Vzia3cHhDdGHuS3XKXJReCRxmfRq3vmTm/Te9yKZnPSAsC58CCKcMh8FNEFJ44vxYF9itKTkRutjGs+DprKLQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.20.tgz",
|
||||
"integrity": "sha512-rwcwzCsAYh/m/WYcxBiEtLpIW5OH1ingxNdF/rK9mtGWhJxXRDV8acPkFrF8rtFWIVKoOCXu5USJYmc3f2gdYQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/generator": "^7.23.0",
|
||||
@@ -6583,7 +6583,7 @@
|
||||
"@babel/traverse": "^7.23.2",
|
||||
"@babel/types": "^7.23.0",
|
||||
"@storybook/csf": "^0.1.2",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/types": "7.6.20",
|
||||
"fs-extra": "^11.1.0",
|
||||
"recast": "^0.23.1",
|
||||
"ts-dedent": "^2.0.0"
|
||||
@@ -6594,9 +6594,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/cli/node_modules/@storybook/node-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-2g29QC44Zl1jKY37DmQ0/dO7+VSKnGgPI/x0mwVwQffypSapxH3rwLLT5Q5XLHeFyD+fhRu5w9Cj4vTGynJgpA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-l2i4qF1bscJkOplNffcRTsgQWYR7J51ewmizj5YrTM8BK6rslWT1RntgVJWB1RgPqvx6VsCz1gyP3yW1oKxvYw==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -6604,12 +6604,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/cli/node_modules/@storybook/types": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.19.tgz",
|
||||
"integrity": "sha512-DeGYrRPRMGTVfT7o2rEZtRzyLT2yKTI2exgpnxbwPWEFAduZCSfzBrcBXZ/nb5B0pjA9tUNWls1YzGkJGlkhpg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.20.tgz",
|
||||
"integrity": "sha512-GncdY3x0LpbhmUAAJwXYtJDUQEwfF175gsjH0/fxPkxPoV7Sef9TM41jQLJW/5+6TnZoCZP/+aJZTJtq3ni23Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/channels": "7.6.19",
|
||||
"@storybook/channels": "7.6.20",
|
||||
"@types/babel__core": "^7.0.0",
|
||||
"@types/express": "^4.7.0",
|
||||
"file-system-cache": "2.3.0"
|
||||
@@ -6703,18 +6703,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/codemod": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.6.19.tgz",
|
||||
"integrity": "sha512-bmHE0iEEgWZ65dXCmasd+GreChjPiWkXu2FEa0cJmNz/PqY12GsXGls4ke1TkNTj4gdSZnbtJxbclPZZnib2tQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.6.20.tgz",
|
||||
"integrity": "sha512-8vmSsksO4XukNw0TmqylPmk7PxnfNfE21YsxFa7mnEBmEKQcZCQsNil4ZgWfG0IzdhTfhglAN4r++Ew0WE+PYA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.23.2",
|
||||
"@babel/preset-env": "^7.23.2",
|
||||
"@babel/types": "^7.23.0",
|
||||
"@storybook/csf": "^0.1.2",
|
||||
"@storybook/csf-tools": "7.6.19",
|
||||
"@storybook/node-logger": "7.6.19",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/csf-tools": "7.6.20",
|
||||
"@storybook/node-logger": "7.6.20",
|
||||
"@storybook/types": "7.6.20",
|
||||
"@types/cross-spawn": "^6.0.2",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"globby": "^11.0.2",
|
||||
@@ -6729,13 +6729,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/codemod/node_modules/@storybook/channels": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.19.tgz",
|
||||
"integrity": "sha512-2JGh+i95GwjtjqWqhtEh15jM5ifwbRGmXeFqkY7dpdHH50EEWafYHr2mg3opK3heVDwg0rJ/VBptkmshloXuvA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.20.tgz",
|
||||
"integrity": "sha512-4hkgPSH6bJclB2OvLnkZOGZW1WptJs09mhQ6j6qLjgBZzL/ZdD6priWSd7iXrmPiN5TzUobkG4P4Dp7FjkiO7A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/client-logger": "7.6.19",
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/client-logger": "7.6.20",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/global": "^5.0.0",
|
||||
"qs": "^6.10.0",
|
||||
"telejson": "^7.2.0",
|
||||
@@ -6747,9 +6747,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/codemod/node_modules/@storybook/client-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-oGzOxbmLmciSIfd5gsxDzPmX8DttWhoYdPKxjMuCuWLTO2TWpkCWp1FTUMWO72mm/6V/FswT/aqpJJBBvdZ3RQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-NwG0VIJQCmKrSaN5GBDFyQgTAHLNishUPLW1NrzqTDNAhfZUoef64rPQlinbopa0H4OXmlB+QxbQIb3ubeXmSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/global": "^5.0.0"
|
||||
@@ -6760,9 +6760,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/codemod/node_modules/@storybook/core-events": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.19.tgz",
|
||||
"integrity": "sha512-K/W6Uvum0ocZSgjbi8hiotpe+wDEHDZlvN+KlPqdh9ae9xDK8aBNBq9IelCoqM+uKO1Zj+dDfSQds7CD781DJg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.20.tgz",
|
||||
"integrity": "sha512-tlVDuVbDiNkvPDFAu+0ou3xBBYbx9zUURQz4G9fAq0ScgBOs/bpzcRrFb4mLpemUViBAd47tfZKdH4MAX45KVQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ts-dedent": "^2.0.0"
|
||||
@@ -6773,9 +6773,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/codemod/node_modules/@storybook/csf-tools": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.19.tgz",
|
||||
"integrity": "sha512-8Vzia3cHhDdGHuS3XKXJReCRxmfRq3vmTm/Te9yKZnPSAsC58CCKcMh8FNEFJ44vxYF9itKTkRutjGs+DprKLQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.20.tgz",
|
||||
"integrity": "sha512-rwcwzCsAYh/m/WYcxBiEtLpIW5OH1ingxNdF/rK9mtGWhJxXRDV8acPkFrF8rtFWIVKoOCXu5USJYmc3f2gdYQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/generator": "^7.23.0",
|
||||
@@ -6783,7 +6783,7 @@
|
||||
"@babel/traverse": "^7.23.2",
|
||||
"@babel/types": "^7.23.0",
|
||||
"@storybook/csf": "^0.1.2",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/types": "7.6.20",
|
||||
"fs-extra": "^11.1.0",
|
||||
"recast": "^0.23.1",
|
||||
"ts-dedent": "^2.0.0"
|
||||
@@ -6794,9 +6794,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/codemod/node_modules/@storybook/node-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-2g29QC44Zl1jKY37DmQ0/dO7+VSKnGgPI/x0mwVwQffypSapxH3rwLLT5Q5XLHeFyD+fhRu5w9Cj4vTGynJgpA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-l2i4qF1bscJkOplNffcRTsgQWYR7J51ewmizj5YrTM8BK6rslWT1RntgVJWB1RgPqvx6VsCz1gyP3yW1oKxvYw==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -6804,12 +6804,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/codemod/node_modules/@storybook/types": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.19.tgz",
|
||||
"integrity": "sha512-DeGYrRPRMGTVfT7o2rEZtRzyLT2yKTI2exgpnxbwPWEFAduZCSfzBrcBXZ/nb5B0pjA9tUNWls1YzGkJGlkhpg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.20.tgz",
|
||||
"integrity": "sha512-GncdY3x0LpbhmUAAJwXYtJDUQEwfF175gsjH0/fxPkxPoV7Sef9TM41jQLJW/5+6TnZoCZP/+aJZTJtq3ni23Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/channels": "7.6.19",
|
||||
"@storybook/channels": "7.6.20",
|
||||
"@types/babel__core": "^7.0.0",
|
||||
"@types/express": "^4.7.0",
|
||||
"file-system-cache": "2.3.0"
|
||||
@@ -7063,26 +7063,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/core-server": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.6.19.tgz",
|
||||
"integrity": "sha512-7mKL73Wv5R2bEl0kJ6QJ9bOu5YY53Idu24QgvTnUdNsQazp2yUONBNwHIrNDnNEXm8SfCi4Mc9o0mmNRMIoiRA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.6.20.tgz",
|
||||
"integrity": "sha512-qC5BdbqqwMLTdCwMKZ1Hbc3+3AaxHYWLiJaXL9e8s8nJw89xV8c8l30QpbJOGvcDmsgY6UTtXYaJ96OsTr7MrA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@aw-web-design/x-default-browser": "1.4.126",
|
||||
"@discoveryjs/json-ext": "^0.5.3",
|
||||
"@storybook/builder-manager": "7.6.19",
|
||||
"@storybook/channels": "7.6.19",
|
||||
"@storybook/core-common": "7.6.19",
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/builder-manager": "7.6.20",
|
||||
"@storybook/channels": "7.6.20",
|
||||
"@storybook/core-common": "7.6.20",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/csf": "^0.1.2",
|
||||
"@storybook/csf-tools": "7.6.19",
|
||||
"@storybook/csf-tools": "7.6.20",
|
||||
"@storybook/docs-mdx": "^0.1.0",
|
||||
"@storybook/global": "^5.0.0",
|
||||
"@storybook/manager": "7.6.19",
|
||||
"@storybook/node-logger": "7.6.19",
|
||||
"@storybook/preview-api": "7.6.19",
|
||||
"@storybook/telemetry": "7.6.19",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/manager": "7.6.20",
|
||||
"@storybook/node-logger": "7.6.20",
|
||||
"@storybook/preview-api": "7.6.20",
|
||||
"@storybook/telemetry": "7.6.20",
|
||||
"@storybook/types": "7.6.20",
|
||||
"@types/detect-port": "^1.3.0",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/pretty-hrtime": "^1.0.0",
|
||||
@@ -7095,7 +7095,6 @@
|
||||
"express": "^4.17.3",
|
||||
"fs-extra": "^11.1.0",
|
||||
"globby": "^11.0.2",
|
||||
"ip": "^2.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"open": "^8.4.0",
|
||||
"pretty-hrtime": "^1.0.3",
|
||||
@@ -7116,13 +7115,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/core-server/node_modules/@storybook/channels": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.19.tgz",
|
||||
"integrity": "sha512-2JGh+i95GwjtjqWqhtEh15jM5ifwbRGmXeFqkY7dpdHH50EEWafYHr2mg3opK3heVDwg0rJ/VBptkmshloXuvA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.20.tgz",
|
||||
"integrity": "sha512-4hkgPSH6bJclB2OvLnkZOGZW1WptJs09mhQ6j6qLjgBZzL/ZdD6priWSd7iXrmPiN5TzUobkG4P4Dp7FjkiO7A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/client-logger": "7.6.19",
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/client-logger": "7.6.20",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/global": "^5.0.0",
|
||||
"qs": "^6.10.0",
|
||||
"telejson": "^7.2.0",
|
||||
@@ -7134,9 +7133,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/core-server/node_modules/@storybook/client-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-oGzOxbmLmciSIfd5gsxDzPmX8DttWhoYdPKxjMuCuWLTO2TWpkCWp1FTUMWO72mm/6V/FswT/aqpJJBBvdZ3RQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-NwG0VIJQCmKrSaN5GBDFyQgTAHLNishUPLW1NrzqTDNAhfZUoef64rPQlinbopa0H4OXmlB+QxbQIb3ubeXmSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/global": "^5.0.0"
|
||||
@@ -7147,14 +7146,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/core-server/node_modules/@storybook/core-common": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.19.tgz",
|
||||
"integrity": "sha512-njwpGzFJrfbJr/AFxGP8KMrfPfxN85KOfSlxYnQwRm5Z0H1D/lT33LhEBf5m37gaGawHeG7KryxO6RvaioMt2Q==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.20.tgz",
|
||||
"integrity": "sha512-8H1zPWPjcmeD4HbDm4FDD0WLsfAKGVr566IZ4hG+h3iWVW57II9JW9MLBtiR2LPSd8u7o0kw64lwRGmtCO1qAw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/node-logger": "7.6.19",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/node-logger": "7.6.20",
|
||||
"@storybook/types": "7.6.20",
|
||||
"@types/find-cache-dir": "^3.2.1",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/node-fetch": "^2.6.4",
|
||||
@@ -7182,9 +7181,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/core-server/node_modules/@storybook/core-events": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.19.tgz",
|
||||
"integrity": "sha512-K/W6Uvum0ocZSgjbi8hiotpe+wDEHDZlvN+KlPqdh9ae9xDK8aBNBq9IelCoqM+uKO1Zj+dDfSQds7CD781DJg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.20.tgz",
|
||||
"integrity": "sha512-tlVDuVbDiNkvPDFAu+0ou3xBBYbx9zUURQz4G9fAq0ScgBOs/bpzcRrFb4mLpemUViBAd47tfZKdH4MAX45KVQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ts-dedent": "^2.0.0"
|
||||
@@ -7195,9 +7194,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/core-server/node_modules/@storybook/csf-tools": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.19.tgz",
|
||||
"integrity": "sha512-8Vzia3cHhDdGHuS3XKXJReCRxmfRq3vmTm/Te9yKZnPSAsC58CCKcMh8FNEFJ44vxYF9itKTkRutjGs+DprKLQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.20.tgz",
|
||||
"integrity": "sha512-rwcwzCsAYh/m/WYcxBiEtLpIW5OH1ingxNdF/rK9mtGWhJxXRDV8acPkFrF8rtFWIVKoOCXu5USJYmc3f2gdYQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/generator": "^7.23.0",
|
||||
@@ -7205,7 +7204,7 @@
|
||||
"@babel/traverse": "^7.23.2",
|
||||
"@babel/types": "^7.23.0",
|
||||
"@storybook/csf": "^0.1.2",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/types": "7.6.20",
|
||||
"fs-extra": "^11.1.0",
|
||||
"recast": "^0.23.1",
|
||||
"ts-dedent": "^2.0.0"
|
||||
@@ -7216,9 +7215,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/core-server/node_modules/@storybook/node-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-2g29QC44Zl1jKY37DmQ0/dO7+VSKnGgPI/x0mwVwQffypSapxH3rwLLT5Q5XLHeFyD+fhRu5w9Cj4vTGynJgpA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-l2i4qF1bscJkOplNffcRTsgQWYR7J51ewmizj5YrTM8BK6rslWT1RntgVJWB1RgPqvx6VsCz1gyP3yW1oKxvYw==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -7226,17 +7225,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/core-server/node_modules/@storybook/preview-api": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.19.tgz",
|
||||
"integrity": "sha512-04hdMSQucroJT4dBjQzRd7ZwH2hij8yx2nm5qd4HYGkd1ORkvlH6GOLph4XewNJl5Um3xfzFQzBhvkqvG0WaCQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.6.20.tgz",
|
||||
"integrity": "sha512-3ic2m9LDZEPwZk02wIhNc3n3rNvbi7VDKn52hDXfAxnL5EYm7yDICAkaWcVaTfblru2zn0EDJt7ROpthscTW5w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/channels": "7.6.19",
|
||||
"@storybook/client-logger": "7.6.19",
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/channels": "7.6.20",
|
||||
"@storybook/client-logger": "7.6.20",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/csf": "^0.1.2",
|
||||
"@storybook/global": "^5.0.0",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/types": "7.6.20",
|
||||
"@types/qs": "^6.9.5",
|
||||
"dequal": "^2.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -7252,12 +7251,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/core-server/node_modules/@storybook/types": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.19.tgz",
|
||||
"integrity": "sha512-DeGYrRPRMGTVfT7o2rEZtRzyLT2yKTI2exgpnxbwPWEFAduZCSfzBrcBXZ/nb5B0pjA9tUNWls1YzGkJGlkhpg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.20.tgz",
|
||||
"integrity": "sha512-GncdY3x0LpbhmUAAJwXYtJDUQEwfF175gsjH0/fxPkxPoV7Sef9TM41jQLJW/5+6TnZoCZP/+aJZTJtq3ni23Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/channels": "7.6.19",
|
||||
"@storybook/channels": "7.6.20",
|
||||
"@types/babel__core": "^7.0.0",
|
||||
"@types/express": "^4.7.0",
|
||||
"file-system-cache": "2.3.0"
|
||||
@@ -7372,9 +7371,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@storybook/manager": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.6.19.tgz",
|
||||
"integrity": "sha512-fZWQcf59x4P0iiBhrL74PZrqKJAPuk9sWjP8BIkGbf8wTZtUunbY5Sv4225fOL4NLJbuX9/RYLUPoxQ3nucGHA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.6.20.tgz",
|
||||
"integrity": "sha512-0Cf6WN0t7yEG2DR29tN5j+i7H/TH5EfPppg9h9/KiQSoFHk+6KLoy2p5do94acFU+Ro4+zzxvdCGbcYGKuArpg==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -7810,14 +7809,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/telemetry": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.6.19.tgz",
|
||||
"integrity": "sha512-rA5xum4I36M57iiD3uzmW0MOdpl0vEpHWBSAa5hK0a0ALPeY9TgAsQlI/0dSyNYJ/K7aczEEN6d4qm1NC4u10A==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.6.20.tgz",
|
||||
"integrity": "sha512-dmAOCWmOscYN6aMbhCMmszQjoycg7tUPRVy2kTaWg6qX10wtMrvEtBV29W4eMvqdsoRj5kcvoNbzRdYcWBUOHQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/client-logger": "7.6.19",
|
||||
"@storybook/core-common": "7.6.19",
|
||||
"@storybook/csf-tools": "7.6.19",
|
||||
"@storybook/client-logger": "7.6.20",
|
||||
"@storybook/core-common": "7.6.20",
|
||||
"@storybook/csf-tools": "7.6.20",
|
||||
"chalk": "^4.1.0",
|
||||
"detect-package-manager": "^2.0.1",
|
||||
"fetch-retry": "^5.0.2",
|
||||
@@ -7830,13 +7829,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/telemetry/node_modules/@storybook/channels": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.19.tgz",
|
||||
"integrity": "sha512-2JGh+i95GwjtjqWqhtEh15jM5ifwbRGmXeFqkY7dpdHH50EEWafYHr2mg3opK3heVDwg0rJ/VBptkmshloXuvA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.6.20.tgz",
|
||||
"integrity": "sha512-4hkgPSH6bJclB2OvLnkZOGZW1WptJs09mhQ6j6qLjgBZzL/ZdD6priWSd7iXrmPiN5TzUobkG4P4Dp7FjkiO7A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/client-logger": "7.6.19",
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/client-logger": "7.6.20",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/global": "^5.0.0",
|
||||
"qs": "^6.10.0",
|
||||
"telejson": "^7.2.0",
|
||||
@@ -7848,9 +7847,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/telemetry/node_modules/@storybook/client-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-oGzOxbmLmciSIfd5gsxDzPmX8DttWhoYdPKxjMuCuWLTO2TWpkCWp1FTUMWO72mm/6V/FswT/aqpJJBBvdZ3RQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-NwG0VIJQCmKrSaN5GBDFyQgTAHLNishUPLW1NrzqTDNAhfZUoef64rPQlinbopa0H4OXmlB+QxbQIb3ubeXmSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/global": "^5.0.0"
|
||||
@@ -7861,14 +7860,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/telemetry/node_modules/@storybook/core-common": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.19.tgz",
|
||||
"integrity": "sha512-njwpGzFJrfbJr/AFxGP8KMrfPfxN85KOfSlxYnQwRm5Z0H1D/lT33LhEBf5m37gaGawHeG7KryxO6RvaioMt2Q==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.6.20.tgz",
|
||||
"integrity": "sha512-8H1zPWPjcmeD4HbDm4FDD0WLsfAKGVr566IZ4hG+h3iWVW57II9JW9MLBtiR2LPSd8u7o0kw64lwRGmtCO1qAw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/core-events": "7.6.19",
|
||||
"@storybook/node-logger": "7.6.19",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/core-events": "7.6.20",
|
||||
"@storybook/node-logger": "7.6.20",
|
||||
"@storybook/types": "7.6.20",
|
||||
"@types/find-cache-dir": "^3.2.1",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/node-fetch": "^2.6.4",
|
||||
@@ -7896,9 +7895,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/telemetry/node_modules/@storybook/core-events": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.19.tgz",
|
||||
"integrity": "sha512-K/W6Uvum0ocZSgjbi8hiotpe+wDEHDZlvN+KlPqdh9ae9xDK8aBNBq9IelCoqM+uKO1Zj+dDfSQds7CD781DJg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.6.20.tgz",
|
||||
"integrity": "sha512-tlVDuVbDiNkvPDFAu+0ou3xBBYbx9zUURQz4G9fAq0ScgBOs/bpzcRrFb4mLpemUViBAd47tfZKdH4MAX45KVQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ts-dedent": "^2.0.0"
|
||||
@@ -7909,9 +7908,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/telemetry/node_modules/@storybook/csf-tools": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.19.tgz",
|
||||
"integrity": "sha512-8Vzia3cHhDdGHuS3XKXJReCRxmfRq3vmTm/Te9yKZnPSAsC58CCKcMh8FNEFJ44vxYF9itKTkRutjGs+DprKLQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.6.20.tgz",
|
||||
"integrity": "sha512-rwcwzCsAYh/m/WYcxBiEtLpIW5OH1ingxNdF/rK9mtGWhJxXRDV8acPkFrF8rtFWIVKoOCXu5USJYmc3f2gdYQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/generator": "^7.23.0",
|
||||
@@ -7919,7 +7918,7 @@
|
||||
"@babel/traverse": "^7.23.2",
|
||||
"@babel/types": "^7.23.0",
|
||||
"@storybook/csf": "^0.1.2",
|
||||
"@storybook/types": "7.6.19",
|
||||
"@storybook/types": "7.6.20",
|
||||
"fs-extra": "^11.1.0",
|
||||
"recast": "^0.23.1",
|
||||
"ts-dedent": "^2.0.0"
|
||||
@@ -7930,9 +7929,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/telemetry/node_modules/@storybook/node-logger": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.19.tgz",
|
||||
"integrity": "sha512-2g29QC44Zl1jKY37DmQ0/dO7+VSKnGgPI/x0mwVwQffypSapxH3rwLLT5Q5XLHeFyD+fhRu5w9Cj4vTGynJgpA==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.6.20.tgz",
|
||||
"integrity": "sha512-l2i4qF1bscJkOplNffcRTsgQWYR7J51ewmizj5YrTM8BK6rslWT1RntgVJWB1RgPqvx6VsCz1gyP3yW1oKxvYw==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -7940,12 +7939,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@storybook/telemetry/node_modules/@storybook/types": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.19.tgz",
|
||||
"integrity": "sha512-DeGYrRPRMGTVfT7o2rEZtRzyLT2yKTI2exgpnxbwPWEFAduZCSfzBrcBXZ/nb5B0pjA9tUNWls1YzGkJGlkhpg==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.6.20.tgz",
|
||||
"integrity": "sha512-GncdY3x0LpbhmUAAJwXYtJDUQEwfF175gsjH0/fxPkxPoV7Sef9TM41jQLJW/5+6TnZoCZP/+aJZTJtq3ni23Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/channels": "7.6.19",
|
||||
"@storybook/channels": "7.6.20",
|
||||
"@types/babel__core": "^7.0.0",
|
||||
"@types/express": "^4.7.0",
|
||||
"file-system-cache": "2.3.0"
|
||||
@@ -10040,12 +10039,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
|
||||
"integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
|
||||
"version": "0.28.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.28.0.tgz",
|
||||
"integrity": "sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.9",
|
||||
"form-data": "^4.0.0"
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/axios-auth-refresh": {
|
||||
@@ -10056,6 +10056,11 @@
|
||||
"axios": ">= 0.18 < 0.19.0 || >= 0.19.1"
|
||||
}
|
||||
},
|
||||
"node_modules/axios/node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/axobject-query": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
|
||||
@@ -11451,6 +11456,12 @@
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/confbox": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz",
|
||||
"integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/confusing-browser-globals": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
|
||||
@@ -14389,9 +14400,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/flow-parser": {
|
||||
"version": "0.237.2",
|
||||
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.237.2.tgz",
|
||||
"integrity": "sha512-mvI/kdfr3l1waaPbThPA8dJa77nHXrfZIun+SWvFwSwDjmeByU7mGJGRmv1+7guU6ccyLV8e1lqZA1lD4iMGnQ==",
|
||||
"version": "0.239.1",
|
||||
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.239.1.tgz",
|
||||
"integrity": "sha512-topOrETNxJ6T2gAnQiWqAlzGPj8uI2wtmNOlDIMNB+qyvGJZ6R++STbUOTAYmvPhOMz2gXnXPH0hOvURYmrBow==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
@@ -18147,6 +18158,30 @@
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/mlly": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz",
|
||||
"integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"acorn": "^8.11.3",
|
||||
"pathe": "^1.1.2",
|
||||
"pkg-types": "^1.1.1",
|
||||
"ufo": "^1.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/mlly/node_modules/acorn": {
|
||||
"version": "8.12.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
|
||||
"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mri": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
|
||||
@@ -18621,16 +18656,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/nypm": {
|
||||
"version": "0.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.8.tgz",
|
||||
"integrity": "sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==",
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.9.tgz",
|
||||
"integrity": "sha512-BI2SdqqTHg2d4wJh8P9A1W+bslg33vOE9IZDY6eR2QC+Pu1iNBVZUqczrd43rJb+fMzHU7ltAYKsEFY/kHMFcw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"citty": "^0.1.6",
|
||||
"consola": "^3.2.3",
|
||||
"execa": "^8.0.1",
|
||||
"pathe": "^1.1.2",
|
||||
"ufo": "^1.4.0"
|
||||
"pkg-types": "^1.1.1",
|
||||
"ufo": "^1.5.3"
|
||||
},
|
||||
"bin": {
|
||||
"nypm": "dist/cli.mjs"
|
||||
@@ -19360,9 +19396,9 @@
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
@@ -19405,6 +19441,17 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-types": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.3.tgz",
|
||||
"integrity": "sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"confbox": "^0.1.7",
|
||||
"mlly": "^1.7.1",
|
||||
"pathe": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/pnp-webpack-plugin": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz",
|
||||
@@ -19441,9 +19488,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.33",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
|
||||
"integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
|
||||
"version": "8.4.39",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
|
||||
"integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -19460,8 +19507,8 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
"picocolors": "^1.0.1",
|
||||
"source-map-js": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
@@ -20265,9 +20312,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/puppeteer-core/node_modules/ws": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
|
||||
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz",
|
||||
"integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"async-limiter": "~1.0.0"
|
||||
@@ -22254,9 +22301,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -22420,12 +22467,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/storybook": {
|
||||
"version": "7.6.19",
|
||||
"resolved": "https://registry.npmjs.org/storybook/-/storybook-7.6.19.tgz",
|
||||
"integrity": "sha512-xWD1C4vD/4KMffCrBBrUpsLUO/9uNpm8BVW8+Vcb30gkQDfficZ0oziWkmLexpT53VSioa24iazGXMwBqllYjQ==",
|
||||
"version": "7.6.20",
|
||||
"resolved": "https://registry.npmjs.org/storybook/-/storybook-7.6.20.tgz",
|
||||
"integrity": "sha512-Wt04pPTO71pwmRmsgkyZhNo4Bvdb/1pBAMsIFb9nQLykEdzzpXjvingxFFvdOG4nIowzwgxD+CLlyRqVJqnATw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@storybook/cli": "7.6.19"
|
||||
"@storybook/cli": "7.6.20"
|
||||
},
|
||||
"bin": {
|
||||
"sb": "index.js",
|
||||
@@ -24661,9 +24708,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.17.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
|
||||
"integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
|
@@ -55,7 +55,7 @@
|
||||
"@ucast/mongo2js": "^1.3.4",
|
||||
"add": "^2.0.6",
|
||||
"argon2-browser": "^1.18.0",
|
||||
"axios": "^0.27.2",
|
||||
"axios": "^0.28.0",
|
||||
"axios-auth-refresh": "^3.3.6",
|
||||
"base64-loader": "^1.0.0",
|
||||
"classnames": "^2.3.1",
|
||||
@@ -147,7 +147,7 @@
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "^2.8.3",
|
||||
"prettier-plugin-tailwindcss": "^0.2.2",
|
||||
"storybook": "^7.5.2",
|
||||
"storybook": "^7.6.20",
|
||||
"storybook-dark-mode": "^3.0.0",
|
||||
"tailwindcss": "3.2",
|
||||
"typescript": "^4.9.3"
|
||||
|
@@ -77,7 +77,7 @@ const features = [
|
||||
"Pull secrets into your Kubernetes containers and automatically redeploy upon secret changes."
|
||||
},
|
||||
{
|
||||
_id: 1,
|
||||
id: 1,
|
||||
name: "Infisical Agent",
|
||||
link: "https://infisical.com/docs/infisical-agent/overview",
|
||||
description: "Inject secrets into your apps without modifying any application logic."
|
||||
@@ -889,27 +889,27 @@ const OrganizationPage = withPermission(
|
||||
<div className="mt-4 grid w-full grid-cols-3 gap-4">
|
||||
{features.map((feature) => (
|
||||
<div
|
||||
key={feature._id}
|
||||
className="flex h-44 w-full flex-col justify-between rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4"
|
||||
key={feature.id}
|
||||
className="relative flex h-full w-full flex-col gap-2 overflow-auto rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4"
|
||||
>
|
||||
<div className="mt-0 text-lg text-mineshaft-100">{feature.name}</div>
|
||||
<div className="mb-4 mt-2 text-[15px] font-light text-mineshaft-300">
|
||||
<div className="line-clamp overflwo-auto mb-4 mt-2 h-full text-[15px] font-light text-mineshaft-300">
|
||||
{feature.description}
|
||||
</div>
|
||||
<div className="flex w-full items-center">
|
||||
<div className="text-[15px] font-light text-mineshaft-300">
|
||||
<div className="flex w-full flex-col items-start gap-2 xl:flex-row xl:items-center">
|
||||
<p className="left-0 text-[15px] font-light text-mineshaft-300">
|
||||
Setup time: 20 min
|
||||
</div>
|
||||
</p>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group ml-auto w-max cursor-default rounded-full border border-mineshaft-600 bg-mineshaft-900 py-2 px-4 text-sm text-mineshaft-300 transition-all hover:border-primary-500/80 hover:bg-primary-800/20 hover:text-mineshaft-200"
|
||||
className="group ml-0 w-max cursor-default rounded-full border border-mineshaft-600 bg-mineshaft-900 py-2 px-4 text-sm text-mineshaft-300 transition-all hover:border-primary-500/80 hover:bg-primary-800/20 hover:text-mineshaft-200 xl:ml-auto"
|
||||
href={feature.link}
|
||||
>
|
||||
Learn more{" "}
|
||||
<FontAwesomeIcon
|
||||
icon={faArrowRight}
|
||||
className="pl-1.5 pr-0.5 duration-200 group-hover:pl-2 group-hover:pr-0"
|
||||
className="s pl-1.5 pr-0.5 duration-200 group-hover:pl-2 group-hover:pr-0"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
@@ -5,7 +5,7 @@ import { z } from "zod";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { Button, FormControl, Modal, ModalContent, Select, SelectItem } from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useOrganization,useWorkspace } from "@app/context";
|
||||
import {
|
||||
useAddIdentityToWorkspace,
|
||||
useGetIdentityProjectMemberships,
|
||||
@@ -33,6 +33,7 @@ type Props = {
|
||||
};
|
||||
|
||||
export const IdentityAddToProjectModal = ({ identityId, popUp, handlePopUpToggle }: Props) => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const { workspaces } = useWorkspace();
|
||||
const { mutateAsync: addIdentityToWorkspace } = useAddIdentityToWorkspace();
|
||||
|
||||
@@ -58,7 +59,9 @@ export const IdentityAddToProjectModal = ({ identityId, popUp, handlePopUpToggle
|
||||
wsWorkspaceIds.set(projectMembership.project.id, true);
|
||||
});
|
||||
|
||||
return (workspaces || []).filter(({ id }) => !wsWorkspaceIds.has(id));
|
||||
return (workspaces || []).filter(
|
||||
({ id, orgId }) => !wsWorkspaceIds.has(id) && orgId === currentOrg?.id
|
||||
);
|
||||
}, [workspaces, projectMemberships]);
|
||||
|
||||
const onFormSubmit = async ({ projectId: workspaceId, role }: FormData) => {
|
||||
|
@@ -13,9 +13,9 @@ type: application
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: v0.6.4
|
||||
version: v0.6.5
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "v0.6.4"
|
||||
appVersion: "v0.6.5"
|
||||
|
@@ -64,6 +64,8 @@ spec:
|
||||
properties:
|
||||
identityId:
|
||||
type: string
|
||||
resource:
|
||||
type: string
|
||||
secretsScope:
|
||||
properties:
|
||||
envSlug:
|
||||
|
@@ -32,7 +32,7 @@ controllerManager:
|
||||
- ALL
|
||||
image:
|
||||
repository: infisical/kubernetes-operator
|
||||
tag: v0.6.4
|
||||
tag: v0.6.5
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
|
@@ -58,6 +58,8 @@ type AWSIamAuthDetails struct {
|
||||
type AzureAuthDetails struct {
|
||||
// +kubebuilder:validation:Required
|
||||
IdentityID string `json:"identityId"`
|
||||
// +kubebuilder:validation:Optional
|
||||
Resource string `json:"resource"`
|
||||
|
||||
// +kubebuilder:validation:Required
|
||||
SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"`
|
||||
|
@@ -64,6 +64,8 @@ spec:
|
||||
properties:
|
||||
identityId:
|
||||
type: string
|
||||
resource:
|
||||
type: string
|
||||
secretsScope:
|
||||
properties:
|
||||
envSlug:
|
||||
|
@@ -60,6 +60,7 @@ spec:
|
||||
# Azure Auth
|
||||
azureAuth:
|
||||
identityId: <your-machine-identity-id>
|
||||
resource: https://management.azure.com/&client_id=your_client_id # This field is optional, and will default to "https://management.azure.com/" if nothing is provided.
|
||||
|
||||
# secretsScope is identical to the secrets scope in the universalAuth field in this sample.
|
||||
secretsScope:
|
||||
|
@@ -109,7 +109,7 @@ func (r *InfisicalSecretReconciler) handleAzureAuth(ctx context.Context, infisic
|
||||
return AuthenticationDetails{}, ErrAuthNotApplicable
|
||||
}
|
||||
|
||||
_, err := infisicalClient.Auth().AzureAuthLogin(azureAuthSpec.IdentityID)
|
||||
_, err := infisicalClient.Auth().AzureAuthLogin(azureAuthSpec.IdentityID, azureAuthSpec.Resource) // If resource is empty(""), it will default to "https://management.azure.com/" in the SDK.
|
||||
if err != nil {
|
||||
return AuthenticationDetails{}, fmt.Errorf("unable to login with Azure auth [err=%s]", err)
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ module github.com/Infisical/infisical/k8-operator
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/infisical/go-sdk v0.2.1
|
||||
github.com/infisical/go-sdk v0.3.2
|
||||
github.com/onsi/ginkgo/v2 v2.6.0
|
||||
github.com/onsi/gomega v1.24.1
|
||||
k8s.io/apimachinery v0.26.1
|
||||
|
@@ -13,10 +13,6 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
|
||||
cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
|
||||
cloud.google.com/go/auth v0.5.1 h1:0QNO7VThG54LUzKiQxv8C6x1YX7lUrzlAa1nVLF8CIw=
|
||||
cloud.google.com/go/auth v0.5.1/go.mod h1:vbZT8GjzDf3AVqCcQmqeeM32U9HBFc32vVVAbwDsa6s=
|
||||
cloud.google.com/go/auth v0.6.1 h1:T0Zw1XM5c1GlpN2HYr2s+m3vr1p2wy+8VN+Z1FKxW38=
|
||||
cloud.google.com/go/auth v0.6.1/go.mod h1:eFHG7zDzbXHKmjJddFG/rBlcGp6t25SwRUiEQSlO4x4=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
|
||||
@@ -27,14 +23,10 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/compute/metadata v0.4.0 h1:vHzJCWaM4g8XIcm8kopr3XmDA4Gy/lblD3EhhSux05c=
|
||||
cloud.google.com/go/compute/metadata v0.4.0/go.mod h1:SIQh1Kkb4ZJ8zJ874fqVkslA29PRXuleyj6vOzlbK7M=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0=
|
||||
cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE=
|
||||
cloud.google.com/go/iam v1.1.10 h1:ZSAr64oEhQSClwBL670MsJAW5/RLiC6kfw3Bqmd5ZDI=
|
||||
cloud.google.com/go/iam v1.1.10/go.mod h1:iEgMq62sg8zx446GCaijmA2Miwg5o3UbO+nI47WHJps=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
@@ -54,54 +46,30 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/aws/aws-sdk-go-v2 v1.27.2 h1:pLsTXqX93rimAOZG2FIYraDQstZaaGVVN4tNw65v0h8=
|
||||
github.com/aws/aws-sdk-go-v2 v1.27.2/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
|
||||
github.com/aws/aws-sdk-go-v2 v1.30.1 h1:4y/5Dvfrhd1MxRDD77SrfsDaj8kUkkljU7XE83NPV+o=
|
||||
github.com/aws/aws-sdk-go-v2 v1.30.1/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.18 h1:wFvAnwOKKe7QAyIxziwSKjmer9JBMH1vzIL6W+fYuKk=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.18/go.mod h1:0xz6cgdX55+kmppvPm2IaKzIXOheGJhAufacPJaXZ7c=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.24 h1:NM9XicZ5o1CBU/MZaHwFtimRpWx9ohAUAqkG6AqSqPo=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.24/go.mod h1:aXzi6QJTuQRVVusAO8/NxpdTeTyr/wRcybdDtfUwJSs=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.18 h1:D/ALDWqK4JdY3OFgA2thcPO1c9aYTT5STS/CvnkqY1c=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.18/go.mod h1:JuitCWq+F5QGUrmMPsk945rop6bB57jdscu+Glozdnc=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.24 h1:YclAsrnb1/GTQNt2nzv+756Iw4mF8AOzcDfweWwwm/M=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.24/go.mod h1:Hld7tmnAkoBQdTMNYZGzztzKRdA4fCdn9L83LOoigac=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5 h1:dDgptDO9dxeFkXy+tEgVkzSClHZje/6JkPW5aZyEvrQ=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5/go.mod h1:gjvE2KBUgUQhcv89jqxrIxH9GaKs1JbZzWejj/DaHGA=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/lQRMaIpJkLLaJ1ZI76no=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9 h1:cy8ahBJuhtM8GTTSyOkfy6WVPV1IE+SS5/wfXUYuulw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9/go.mod h1:CZBXGLaJnEZI6EVNcPd7a6B5IC5cA/GkRWtu9fp3S6Y=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13 h1:5SAoZ4jYpGH4721ZNoS1znQrhOfZinOhc4XuTXx/nVc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13/go.mod h1:+rdA6ZLpaSeM7tSg/B0IEDinCIBJGmW8rKDFkYpP04g=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9 h1:A4SYk07ef04+vxZToz9LWvAXl9LW0NClpPpMsi31cz0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9/go.mod h1:5jJcHuwDagxN+ErjQ3PU3ocf6Ylc/p9x+BLO/+X4iXw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13 h1:WIijqeaAO7TYFLbhsZmi2rgLEAtWOC1LhxCAVTJlSKw=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13/go.mod h1:i+kbfa76PQbWw/ULoWnp51EYVWH4ENln76fLQE3lXT8=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11 h1:o4T+fKxA3gTMcluBNZZXE9DNaMkJuUL1O3mffCUjoJo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11/go.mod h1:84oZdJ+VjuJKs9v1UTC9NaodRZRseOXCTgku+vQJWR8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15 h1:I9zMeF107l0rJrpnHpjEiiTSCKYAIw8mALiXcPsGBiA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15/go.mod h1:9xWJ3Q/S6Ojusz1UIkfycgD1mGirJfLLKqq3LPT7WN8=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.20.11 h1:gEYM2GSpr4YNWc6hCd5nod4+d4kd9vWIAWrmGuLdlMw=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.20.11/go.mod h1:gVvwPdPNYehHSP9Rs7q27U1EU+3Or2ZpXvzAYJNh63w=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5 h1:iXjh3uaH3vsVcnyZX7MqCoCfcyxIrVE9iOQruRaWPrQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5/go.mod h1:5ZXesEuy/QcO0WUnt+4sDkxhdXRHTu2yG0uCSH8B6os=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2 h1:ORnrOK0C4WmYV/uYt3koHEWBLYsRDwk2Np+eEoyV4Z0=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.2/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 h1:M/1u4HBpwLuMtjlxuI2y6HoVLzF5e2mfxHCg7ZVMYmk=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.28.12/go.mod h1:kcfd+eTdEi/40FIbLq4Hif3XMXnl5b/+t/KTfLt9xIk=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 h1:+woJ607dllHJQtsnJLi52ycuqHMwlW+Wqm2Ppsfp4nQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.30.1/go.mod h1:jiNR3JqT15Dm+QWq2SRgh0x0bCNSRP2L25+CqPNpJlQ=
|
||||
github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q=
|
||||
github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
|
||||
github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE=
|
||||
github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
@@ -113,8 +81,6 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
@@ -155,8 +121,6 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
@@ -246,8 +210,6 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg=
|
||||
github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI=
|
||||
github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA=
|
||||
github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
@@ -255,12 +217,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/infisical/go-sdk v0.1.9 h1:o9LUj0Tyn6OHusTEKEKQ4+PulJViAxgOrFa+SlwGJFc=
|
||||
github.com/infisical/go-sdk v0.1.9/go.mod h1:vHTDVw3k+wfStXab513TGk1n53kaKF2xgLqpw/xvtl4=
|
||||
github.com/infisical/go-sdk v0.2.0 h1:n1/KNdYpeQavSqVwC9BfeV8VRzf3N2X9zO1tzQOSj5Q=
|
||||
github.com/infisical/go-sdk v0.2.0/go.mod h1:vHTDVw3k+wfStXab513TGk1n53kaKF2xgLqpw/xvtl4=
|
||||
github.com/infisical/go-sdk v0.2.1 h1:z8DQ3tLV/MdxTAnXXIkll45nQcK+RK8+eoImW6J7m/g=
|
||||
github.com/infisical/go-sdk v0.2.1/go.mod h1:vHTDVw3k+wfStXab513TGk1n53kaKF2xgLqpw/xvtl4=
|
||||
github.com/infisical/go-sdk v0.3.2 h1:BfeQzG7s3qmEGhgXu0d1YNsyaiHucHgI+BaLpx+W8cc=
|
||||
github.com/infisical/go-sdk v0.3.2/go.mod h1:vHTDVw3k+wfStXab513TGk1n53kaKF2xgLqpw/xvtl4=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
@@ -375,24 +333,14 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
|
||||
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
|
||||
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
|
||||
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
@@ -413,7 +361,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
@@ -487,7 +434,6 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
@@ -559,7 +505,6 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
@@ -568,7 +513,6 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||
@@ -582,7 +526,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
@@ -658,8 +601,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.183.0 h1:PNMeRDwo1pJdgNcFQ9GstuLe/noWKIc89pRWRLMvLwE=
|
||||
google.golang.org/api v0.183.0/go.mod h1:q43adC5/pHoSZTx5h2mSmdF7NcyfW9JuDyIOJAgS9ZQ=
|
||||
google.golang.org/api v0.187.0 h1:Mxs7VATVC2v7CY+7Xwm4ndkX71hpElcvx0D1Ji/p1eo=
|
||||
google.golang.org/api v0.187.0/go.mod h1:KIHlTc4x7N7gKKuVsdmfBXN13yEEWXWFURWY6SBp2gk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
@@ -698,12 +639,8 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240521202816-d264139d666e h1:SkdGTrROJl2jRGT/Fxv5QUf9jtdKCQh4KQJXbXVLAi0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240521202816-d264139d666e/go.mod h1:LweJcLbyVij6rCex8YunD8DYR5VDonap/jYl3ZRxcIU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240708141625-4ad9e859172b h1:y/kpOWeX2pWERnbsvh/hF+Zmo69wVmjyZhstreXQQeA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240708141625-4ad9e859172b/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
@@ -719,8 +656,6 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
||||
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
|
||||
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
||||
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
@@ -735,8 +670,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
|
Reference in New Issue
Block a user