diff --git a/backend/package-lock.json b/backend/package-lock.json index 6b1c1f97a..a9bb83e6b 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -6687,9 +6687,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", - "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -17198,9 +17198,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "jsonwebtoken": { diff --git a/backend/src/app.ts b/backend/src/app.ts index 140521ee3..1e1bbb593 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -13,7 +13,9 @@ import { apiLimiter } from './helpers/rateLimiter'; import { workspace as eeWorkspaceRouter, - secret as eeSecretRouter + secret as eeSecretRouter, + secretSnapshot as eeSecretSnapshotRouter, + action as eeActionRouter } from './ee/routes/v1'; import { signup as v1SignupRouter, @@ -70,7 +72,9 @@ if (NODE_ENV === 'production') { // (EE) routes app.use('/api/v1/secret', eeSecretRouter); +app.use('/api/v1/secret-snapshot', eeSecretSnapshotRouter); app.use('/api/v1/workspace', eeWorkspaceRouter); +app.use('/api/v1/action', eeActionRouter); // v1 routes app.use('/api/v1/signup', v1SignupRouter); diff --git a/backend/src/controllers/v1/secretController.ts b/backend/src/controllers/v1/secretController.ts index 238b38ced..1b756ecc7 100644 --- a/backend/src/controllers/v1/secretController.ts +++ b/backend/src/controllers/v1/secretController.ts @@ -123,7 +123,9 @@ export const pullSecrets = async (req: Request, res: Response) => { secrets = await pull({ userId: req.user._id.toString(), workspaceId, - environment + environment, + channel: channel ? channel : 'cli', + ipAddress: req.ip }); key = await Key.findOne({ @@ -188,7 +190,9 @@ export const pullSecretsServiceToken = async (req: Request, res: Response) => { secrets = await pull({ userId: req.serviceToken.user._id.toString(), workspaceId, - environment + environment, + channel: 'cli', + ipAddress: req.ip }); key = { diff --git a/backend/src/controllers/v2/secretController.ts b/backend/src/controllers/v2/secretController.ts index 472859de9..e0cc936c4 100644 --- a/backend/src/controllers/v2/secretController.ts +++ b/backend/src/controllers/v2/secretController.ts @@ -2,7 +2,7 @@ import to from "await-to-js"; import { Request, Response } from "express"; import mongoose, { Types } from "mongoose"; import Secret, { ISecret } from "../../models/secret"; -import { CreateSecretRequestBody, ModifySecretRequestBody, SanitizedSecretForCreate, SanitizedSecretModify } from "../../types/secret/types"; +import { CreateSecretRequestBody, ModifySecretRequestBody, SanitizedSecretForCreate, SanitizedSecretModify } from "../../types/secret"; const { ValidationError } = mongoose.Error; import { BadRequestError, InternalServerError, UnauthorizedRequestError, ValidationError as RouteValidationError } from '../../utils/errors'; import { AnyBulkWriteOperation } from 'mongodb'; diff --git a/backend/src/controllers/v2/workspaceController.ts b/backend/src/controllers/v2/workspaceController.ts index 54317690d..0dbdfa076 100644 --- a/backend/src/controllers/v2/workspaceController.ts +++ b/backend/src/controllers/v2/workspaceController.ts @@ -11,10 +11,6 @@ import { ServiceToken, ServiceTokenData } from '../../models'; -import { - createWorkspace as create, - deleteWorkspace as deleteWork -} from '../../helpers/workspace'; import { v2PushSecrets as push, pullSecrets as pull, @@ -50,7 +46,6 @@ interface V2PushSecret { */ export const pushWorkspaceSecrets = async (req: Request, res: Response) => { // upload (encrypted) secrets to workspace with id [workspaceId] - try { let { secrets }: { secrets: V2PushSecret[] } = req.body; const { keys, environment, channel } = req.body; @@ -70,7 +65,9 @@ export const pushWorkspaceSecrets = async (req: Request, res: Response) => { userId: req.user._id, workspaceId, environment, - secrets + secrets, + channel: channel ? channel : 'cli', + ipAddress: req.ip }); await pushKeys({ @@ -136,7 +133,9 @@ export const pullSecrets = async (req: Request, res: Response) => { secrets = await pull({ userId, workspaceId, - environment + environment, + channel: channel ? channel : 'cli', + ipAddress: req.ip }); if (channel !== 'cli') { @@ -196,7 +195,7 @@ export const getWorkspaceServiceTokenData = async ( ) => { let serviceTokenData; try { - const { workspaceId } = req.query; + const { workspaceId } = req.params; serviceTokenData = await ServiceTokenData .find({ diff --git a/backend/src/ee/controllers/v1/actionController.ts b/backend/src/ee/controllers/v1/actionController.ts new file mode 100644 index 000000000..b136b0fa4 --- /dev/null +++ b/backend/src/ee/controllers/v1/actionController.ts @@ -0,0 +1,31 @@ +import { Request, Response } from 'express'; +import * as Sentry from '@sentry/node'; +import { Action, SecretVersion } from '../../models'; +import { ActionNotFoundError } from '../../../utils/errors'; + +export const getAction = async (req: Request, res: Response) => { + let action; + try { + const { actionId } = req.params; + + action = await Action + .findById(actionId) + .populate([ + 'payload.secretVersions.oldSecretVersion', + 'payload.secretVersions.newSecretVersion' + ]); + + if (!action) throw ActionNotFoundError({ + message: 'Failed to find action' + }); + + } catch (err) { + throw ActionNotFoundError({ + message: 'Failed to find action' + }); + } + + return res.status(200).send({ + action + }); +} \ No newline at end of file diff --git a/backend/src/ee/controllers/v1/index.ts b/backend/src/ee/controllers/v1/index.ts index 23880070d..dd88f1178 100644 --- a/backend/src/ee/controllers/v1/index.ts +++ b/backend/src/ee/controllers/v1/index.ts @@ -1,9 +1,13 @@ import * as stripeController from './stripeController'; import * as secretController from './secretController'; +import * as secretSnapshotController from './secretSnapshotController'; import * as workspaceController from './workspaceController'; +import * as actionController from './actionController'; export { stripeController, secretController, - workspaceController + secretSnapshotController, + workspaceController, + actionController } \ No newline at end of file diff --git a/backend/src/ee/controllers/v1/secretController.ts b/backend/src/ee/controllers/v1/secretController.ts index b2d66ab33..a2d68ca96 100644 --- a/backend/src/ee/controllers/v1/secretController.ts +++ b/backend/src/ee/controllers/v1/secretController.ts @@ -18,6 +18,7 @@ import { SecretVersion } from '../../models'; secretVersions = await SecretVersion.find({ secret: secretId }) + .sort({ createdAt: -1 }) .skip(offset) .limit(limit); diff --git a/backend/src/ee/controllers/v1/secretSnapshotController.ts b/backend/src/ee/controllers/v1/secretSnapshotController.ts new file mode 100644 index 000000000..40e1a74a6 --- /dev/null +++ b/backend/src/ee/controllers/v1/secretSnapshotController.ts @@ -0,0 +1,27 @@ +import { Request, Response } from 'express'; +import * as Sentry from '@sentry/node'; +import { SecretSnapshot } from '../../models'; + +export const getSecretSnapshot = async (req: Request, res: Response) => { + let secretSnapshot; + try { + const { secretSnapshotId } = req.params; + + secretSnapshot = await SecretSnapshot + .findById(secretSnapshotId) + .populate('secretVersions'); + + if (!secretSnapshot) throw new Error('Failed to find secret snapshot'); + + } catch (err) { + Sentry.setUser({ email: req.user.email }); + Sentry.captureException(err); + return res.status(400).send({ + message: 'Failed to get secret snapshot' + }); + } + + return res.status(200).send({ + secretSnapshot + }); +} \ No newline at end of file diff --git a/backend/src/ee/controllers/v1/workspaceController.ts b/backend/src/ee/controllers/v1/workspaceController.ts index 8b7ba422e..88c31b8e1 100644 --- a/backend/src/ee/controllers/v1/workspaceController.ts +++ b/backend/src/ee/controllers/v1/workspaceController.ts @@ -1,6 +1,9 @@ -import { Request, Response } from 'express'; +import e, { Request, Response } from 'express'; import * as Sentry from '@sentry/node'; -import { SecretSnapshot } from '../../models'; +import { + SecretSnapshot, + Log +} from '../../models'; /** * Return secret snapshots for workspace with id [workspaceId] @@ -18,6 +21,7 @@ import { SecretSnapshot } from '../../models'; secretSnapshots = await SecretSnapshot.find({ workspace: workspaceId }) + .sort({ createdAt: -1 }) .skip(offset) .limit(limit); @@ -32,4 +36,77 @@ import { SecretSnapshot } from '../../models'; return res.status(200).send({ secretSnapshots }); +} + +/** + * Return count of secret snapshots for workspace with id [workspaceId] + * @param req + * @param res + */ +export const getWorkspaceSecretSnapshotsCount = async (req: Request, res: Response) => { + let count; + try { + const { workspaceId } = req.params; + count = await SecretSnapshot.countDocuments({ + workspace: workspaceId + }); + } catch (err) { + Sentry.setUser({ email: req.user.email }); + Sentry.captureException(err); + return res.status(400).send({ + message: 'Failed to count number of secret snapshots' + }); + } + + return res.status(200).send({ + count + }); +} + +/** + * Return (audit) logs for workspace with id [workspaceId] + * @param req + * @param res + * @returns + */ +export const getWorkspaceLogs = async (req: Request, res: Response) => { + let logs + try { + const { workspaceId } = req.params; + + const offset: number = parseInt(req.query.offset as string); + const limit: number = parseInt(req.query.limit as string); + const sortBy: string = req.query.sortBy as string; + const userId: string = req.query.userId as string; + const actionNames: string = req.query.actionNames as string; + + logs = await Log.find({ + workspace: workspaceId, + ...( userId ? { user: userId } : {}), + ...( + actionNames + ? { + actionNames: { + $in: actionNames.split(',') + } + } : {} + ) + }) + .sort({ createdAt: sortBy === 'recent' ? -1 : 1 }) + .skip(offset) + .limit(limit) + .populate('actions') + .populate('user'); + + } catch (err) { + Sentry.setUser({ email: req.user.email }); + Sentry.captureException(err); + return res.status(400).send({ + message: 'Failed to get workspace logs' + }); + } + + return res.status(200).send({ + logs + }); } \ No newline at end of file diff --git a/backend/src/ee/helpers/action.ts b/backend/src/ee/helpers/action.ts new file mode 100644 index 000000000..2971e3f96 --- /dev/null +++ b/backend/src/ee/helpers/action.ts @@ -0,0 +1,112 @@ +import * as Sentry from '@sentry/node'; +import { Types } from 'mongoose'; +import { Secret } from '../../models'; +import { SecretVersion, Action } from '../models'; +import { ACTION_UPDATE_SECRETS } from '../../variables'; + +/** + * Create an (audit) action for secrets including + * add, delete, update, and read actions. + * @param {Object} obj + * @param {String} obj.name - name of action + * @param {ObjectId[]} obj.secretIds - ids of relevant secrets + * @returns {Action} action - new action + */ +const createActionSecretHelper = async ({ + name, + userId, + workspaceId, + secretIds +}: { + name: string; + userId: string; + workspaceId: string; + secretIds: Types.ObjectId[]; +}) => { + + let action; + let latestSecretVersions; + try { + if (name === ACTION_UPDATE_SECRETS) { + // case: action is updating secrets + // -> add old and new secret versions + + // TODO: make query more efficient + latestSecretVersions = (await SecretVersion.aggregate([ + { + $match: { + secret: { + $in: secretIds, + }, + }, + }, + { + $sort: { version: -1 }, + }, + { + $group: { + _id: "$secret", + versions: { $push: "$$ROOT" }, + }, + }, + { + $project: { + _id: 0, + secret: "$_id", + versions: { $slice: ["$versions", 2] }, + }, + } + ])) + .map((s) => ({ + oldSecretVersion: s.versions[0]._id, + newSecretVersion: s.versions[1]._id + })); + + + } else { + // case: action is adding, deleting, or reading secrets + // -> add new secret versions + latestSecretVersions = (await SecretVersion.aggregate([ + { + $match: { + secret: { + $in: secretIds + } + } + }, + { + $group: { + _id: '$secret', + version: { $max: '$version' }, + versionId: { $max: '$_id' } // secret version id + } + }, + { + $sort: { version: -1 } + } + ]) + .exec()) + .map((s) => ({ + newSecretVersion: s.versionId + })); + } + + action = await new Action({ + name, + user: userId, + workspace: workspaceId, + payload: { + secretVersions: latestSecretVersions + } + }).save(); + + } catch (err) { + Sentry.setUser(null); + Sentry.captureException(err); + throw new Error('Failed to create action'); + } + + return action; +} + +export { createActionSecretHelper }; \ No newline at end of file diff --git a/backend/src/ee/helpers/log.ts b/backend/src/ee/helpers/log.ts new file mode 100644 index 000000000..c357c9818 --- /dev/null +++ b/backend/src/ee/helpers/log.ts @@ -0,0 +1,41 @@ +import * as Sentry from '@sentry/node'; +import { + Log, + IAction +} from '../models'; + +const createLogHelper = async ({ + userId, + workspaceId, + actions, + channel, + ipAddress +}: { + userId: string; + workspaceId: string; + actions: IAction[]; + channel: string; + ipAddress: string; +}) => { + let log; + try { + log = await new Log({ + user: userId, + workspace: workspaceId, + actionNames: actions.map((a) => a.name), + actions, + channel, + ipAddress + }).save(); + } catch (err) { + Sentry.setUser(null); + Sentry.captureException(err); + throw new Error('Failed to create log'); + } + + return log; +} + +export { + createLogHelper +} \ No newline at end of file diff --git a/backend/src/ee/helpers/secret.ts b/backend/src/ee/helpers/secret.ts index a688a108f..529c9a980 100644 --- a/backend/src/ee/helpers/secret.ts +++ b/backend/src/ee/helpers/secret.ts @@ -1,6 +1,8 @@ +import { Types } from 'mongoose'; import * as Sentry from '@sentry/node'; import { - Secret + Secret, + ISecret } from '../../models'; import { SecretSnapshot, @@ -9,66 +11,159 @@ import { } from '../models'; /** - * Save a copy of the current state of secrets in workspace with id + * Save a secret snapshot that is a copy of the current state of secrets in workspace with id * [workspaceId] under a new snapshot with incremented version under the * secretsnapshots collection. * @param {Object} obj * @param {String} obj.workspaceId + * @returns {SecretSnapshot} secretSnapshot - new secret snapshot */ const takeSecretSnapshotHelper = async ({ workspaceId }: { workspaceId: string; }) => { + + let secretSnapshot; try { - const secrets = await Secret.find({ + const secretIds = (await Secret.find({ workspace: workspaceId - }); + }, '_id')).map((s) => s._id); + const latestSecretVersions = (await SecretVersion.aggregate([ + { + $match: { + secret: { + $in: secretIds + } + } + }, + { + $group: { + _id: '$secret', + version: { $max: '$version' }, + versionId: { $max: '$_id' } // secret version id + } + }, + { + $sort: { version: -1 } + } + ]) + .exec()) + .map((s) => s.versionId); + const latestSecretSnapshot = await SecretSnapshot.findOne({ workspace: workspaceId }).sort({ version: -1 }); - if (!latestSecretSnapshot) { - // case: no snapshots exist for workspace -> create first snapshot - await new SecretSnapshot({ - workspace: workspaceId, - version: 1, - secrets - }).save(); - - return; - } - - // case: snapshots exist for workspace - await new SecretSnapshot({ + secretSnapshot = await new SecretSnapshot({ workspace: workspaceId, - version: latestSecretSnapshot.version + 1, - secrets + version: latestSecretSnapshot ? latestSecretSnapshot.version + 1 : 1, + secretVersions: latestSecretVersions }).save(); - } catch (err) { Sentry.setUser(null); Sentry.captureException(err); throw new Error('Failed to take a secret snapshot'); } + + return secretSnapshot; } +/** + * Add secret versions [secretVersions] to the SecretVersion collection. + * @param {Object} obj + * @param {Object[]} obj.secretVersions + * @returns {SecretVersion[]} newSecretVersions - new secret versions + */ const addSecretVersionsHelper = async ({ secretVersions }: { secretVersions: ISecretVersion[] }) => { + let newSecretVersions; try { - await SecretVersion.insertMany(secretVersions); + newSecretVersions = await SecretVersion.insertMany(secretVersions); } catch (err) { Sentry.setUser(null); Sentry.captureException(err); throw new Error('Failed to add secret versions'); } + + return newSecretVersions; +} + +const markDeletedSecretVersionsHelper = async ({ + secretIds +}: { + secretIds: Types.ObjectId[]; +}) => { + try { + await SecretVersion.updateMany({ + secret: { $in: secretIds } + }, { + isDeleted: true + }, { + new: true + }); + } catch (err) { + Sentry.setUser(null); + Sentry.captureException(err); + throw new Error('Failed to mark secret versions as deleted'); + } +} + +/** + * Initialize secret versioning by setting previously unversioned + * secrets to version 1 and begin populating secret versions. + */ +const initSecretVersioningHelper = async () => { + try { + + await Secret.updateMany( + { version: { $exists: false } }, + { $set: { version: 1 } } + ); + + const unversionedSecrets: ISecret[] = await Secret.aggregate([ + { + $lookup: { + from: 'secretversions', + localField: '_id', + foreignField: 'secret', + as: 'versions', + }, + }, + { + $match: { + versions: { $size: 0 }, + }, + }, + ]); + + if (unversionedSecrets.length > 0) { + await addSecretVersionsHelper({ + secretVersions: unversionedSecrets.map((s, idx) => ({ + ...s, + secret: s._id, + version: s.version ? s.version : 1, + isDeleted: false, + workspace: s.workspace, + environment: s.environment + })) + }); + } + + } catch (err) { + Sentry.setUser(null); + Sentry.captureException(err); + throw new Error('Failed to ensure that secrets are versioned'); + } } export { takeSecretSnapshotHelper, - addSecretVersionsHelper + addSecretVersionsHelper, + markDeletedSecretVersionsHelper, + initSecretVersioningHelper } \ No newline at end of file diff --git a/backend/src/ee/middleware/index.ts b/backend/src/ee/middleware/index.ts new file mode 100644 index 000000000..ff9267965 --- /dev/null +++ b/backend/src/ee/middleware/index.ts @@ -0,0 +1,7 @@ +import requireLicenseAuth from './requireLicenseAuth'; +import requireSecretSnapshotAuth from './requireSecretSnapshotAuth'; + +export { + requireLicenseAuth, + requireSecretSnapshotAuth +} \ No newline at end of file diff --git a/backend/src/ee/middleware/requireSecretSnapshotAuth.ts b/backend/src/ee/middleware/requireSecretSnapshotAuth.ts new file mode 100644 index 000000000..5eae3721c --- /dev/null +++ b/backend/src/ee/middleware/requireSecretSnapshotAuth.ts @@ -0,0 +1,47 @@ +import { Request, Response, NextFunction } from 'express'; +import { UnauthorizedRequestError, SecretSnapshotNotFoundError } from '../../utils/errors'; +import { SecretSnapshot } from '../models'; +import { + validateMembership +} from '../../helpers/membership'; + +/** + * Validate if user on request has proper membership for secret snapshot + * @param {Object} obj + * @param {String[]} obj.acceptedRoles - accepted workspace roles + * @param {String[]} obj.acceptedStatuses - accepted workspace statuses + * @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing + */ +const requireSecretSnapshotAuth = ({ + acceptedRoles, +}: { + acceptedRoles: string[]; +}) => { + return async (req: Request, res: Response, next: NextFunction) => { + try { + const { secretSnapshotId } = req.params; + + const secretSnapshot = await SecretSnapshot.findById(secretSnapshotId); + + if (!secretSnapshot) { + return next(SecretSnapshotNotFoundError({ + message: 'Failed to find secret snapshot' + })); + } + + await validateMembership({ + userId: req.user._id.toString(), + workspaceId: secretSnapshot.workspace.toString(), + acceptedRoles + }); + + req.secretSnapshot = secretSnapshot as any; + + next(); + } catch (err) { + return next(UnauthorizedRequestError({ message: 'Unable to authenticate secret snapshot' })); + } + } +} + +export default requireSecretSnapshotAuth; \ No newline at end of file diff --git a/backend/src/ee/models/action.ts b/backend/src/ee/models/action.ts new file mode 100644 index 000000000..3d48aa04d --- /dev/null +++ b/backend/src/ee/models/action.ts @@ -0,0 +1,46 @@ +import { Schema, model, Types } from 'mongoose'; + +export interface IAction { + name: string; + user?: Types.ObjectId, + workspace?: Types.ObjectId, + payload: { + secretVersions?: Types.ObjectId[] + } +} + +const actionSchema = new Schema( + { + name: { + type: String, + required: true + }, + user: { + type: Schema.Types.ObjectId, + ref: 'User', + required: true + }, + workspace: { + type: Schema.Types.ObjectId, + ref: 'Workspace' + }, + payload: { + secretVersions: [{ + oldSecretVersion: { + type: Schema.Types.ObjectId, + ref: 'SecretVersion' + }, + newSecretVersion: { + type: Schema.Types.ObjectId, + ref: 'SecretVersion' + } + }] + } + }, { + timestamps: true + } +); + +const Action = model('Action', actionSchema); + +export default Action; \ No newline at end of file diff --git a/backend/src/ee/models/index.ts b/backend/src/ee/models/index.ts index 35d41c19a..a6cee725e 100644 --- a/backend/src/ee/models/index.ts +++ b/backend/src/ee/models/index.ts @@ -1,9 +1,15 @@ -import SecretSnapshot, { ISecretSnapshot } from "./secretSnapshot"; -import SecretVersion, { ISecretVersion } from "./secretVersion"; +import SecretSnapshot, { ISecretSnapshot } from './secretSnapshot'; +import SecretVersion, { ISecretVersion } from './secretVersion'; +import Log, { ILog } from './log'; +import Action, { IAction } from './action'; export { SecretSnapshot, ISecretSnapshot, SecretVersion, - ISecretVersion + ISecretVersion, + Log, + ILog, + Action, + IAction } \ No newline at end of file diff --git a/backend/src/ee/models/log.ts b/backend/src/ee/models/log.ts new file mode 100644 index 000000000..1fdd52710 --- /dev/null +++ b/backend/src/ee/models/log.ts @@ -0,0 +1,59 @@ +import { Schema, model, Types } from 'mongoose'; +import { + ACTION_ADD_SECRETS, + ACTION_UPDATE_SECRETS, + ACTION_READ_SECRETS, + ACTION_DELETE_SECRETS +} from '../../variables'; + +export interface ILog { + _id: Types.ObjectId; + user?: Types.ObjectId; + workspace?: Types.ObjectId; + actionNames: string[]; + actions: Types.ObjectId[]; + channel: string; + ipAddress?: string; +} + +const logSchema = new Schema( + { + user: { + type: Schema.Types.ObjectId, + ref: 'User' + }, + workspace: { + type: Schema.Types.ObjectId, + ref: 'Workspace' + }, + actionNames: { + type: [String], + enum: [ + ACTION_ADD_SECRETS, + ACTION_UPDATE_SECRETS, + ACTION_READ_SECRETS, + ACTION_DELETE_SECRETS + ], + required: true + }, + actions: [{ + type: Schema.Types.ObjectId, + ref: 'Action', + required: true + }], + channel: { + type: String, + enum: ['web', 'cli', 'auto'], + required: true + }, + ipAddress: { + type: String + } + }, { + timestamps: true + } +); + +const Log = model('Log', logSchema); + +export default Log; \ No newline at end of file diff --git a/backend/src/ee/models/secretSnapshot.ts b/backend/src/ee/models/secretSnapshot.ts index 69633a92e..c646f353a 100644 --- a/backend/src/ee/models/secretSnapshot.ts +++ b/backend/src/ee/models/secretSnapshot.ts @@ -1,31 +1,9 @@ import { Schema, model, Types } from 'mongoose'; -import { - SECRET_SHARED, - SECRET_PERSONAL, - ENV_DEV, - ENV_TESTING, - ENV_STAGING, - ENV_PROD -} from '../../variables'; export interface ISecretSnapshot { workspace: Types.ObjectId; version: number; - secrets: { - version: number; - workspace: Types.ObjectId; - type: string; - user: Types.ObjectId; - environment: string; - secretKeyCiphertext: string; - secretKeyIV: string; - secretKeyTag: string; - secretKeyHash: string; - secretValueCiphertext: string; - secretValueIV: string; - secretValueTag: string; - secretValueHash: string; - }[] + secretVersions: Types.ObjectId[]; } const secretSnapshotSchema = new Schema( @@ -39,64 +17,10 @@ const secretSnapshotSchema = new Schema( type: Number, required: true }, - secrets: [{ - version: { - type: Number, - default: 1, - required: true - }, - workspace: { - type: Schema.Types.ObjectId, - ref: 'Workspace', - required: true - }, - type: { - type: String, - enum: [SECRET_SHARED, SECRET_PERSONAL], - required: true - }, - user: { - // user associated with the personal secret - type: Schema.Types.ObjectId, - ref: 'User' - }, - environment: { - type: String, - enum: [ENV_DEV, ENV_TESTING, ENV_STAGING, ENV_PROD], - required: true - }, - secretKeyCiphertext: { - type: String, - required: true - }, - secretKeyIV: { - type: String, // symmetric - required: true - }, - secretKeyTag: { - type: String, // symmetric - required: true - }, - secretKeyHash: { - type: String, - required: true - }, - secretValueCiphertext: { - type: String, - required: true - }, - secretValueIV: { - type: String, // symmetric - required: true - }, - secretValueTag: { - type: String, // symmetric - required: true - }, - secretValueHash: { - type: String, - required: true - } + secretVersions: [{ + type: Schema.Types.ObjectId, + ref: 'SecretVersion', + required: true }] }, { diff --git a/backend/src/ee/models/secretVersion.ts b/backend/src/ee/models/secretVersion.ts index a93a037f6..0197c3a25 100644 --- a/backend/src/ee/models/secretVersion.ts +++ b/backend/src/ee/models/secretVersion.ts @@ -1,9 +1,30 @@ import { Schema, model, Types } from 'mongoose'; +import { + SECRET_SHARED, + SECRET_PERSONAL, + ENV_DEV, + ENV_TESTING, + ENV_STAGING, + ENV_PROD +} from '../../variables'; + +/** + * TODO: + * 1. Modify SecretVersion to also contain XX + * - type + * - user + * - environment + * 2. Modify SecretSnapshot to point to arrays of SecretVersion + */ export interface ISecretVersion { _id?: Types.ObjectId; secret: Types.ObjectId; version: number; + workspace: Types.ObjectId; // new + type: string; // new + user: Types.ObjectId; // new + environment: string; // new isDeleted: boolean; secretKeyCiphertext: string; secretKeyIV: string; @@ -27,6 +48,26 @@ const secretVersionSchema = new Schema( default: 1, required: true }, + workspace: { + type: Schema.Types.ObjectId, + ref: 'Workspace', + required: true + }, + type: { + type: String, + enum: [SECRET_SHARED, SECRET_PERSONAL], + required: true + }, + user: { + // user associated with the personal secret + type: Schema.Types.ObjectId, + ref: 'User' + }, + environment: { + type: String, + enum: [ENV_DEV, ENV_TESTING, ENV_STAGING, ENV_PROD], + required: true + }, isDeleted: { type: Boolean, default: false, diff --git a/backend/src/ee/routes/v1/action.ts b/backend/src/ee/routes/v1/action.ts new file mode 100644 index 000000000..5dca83cf9 --- /dev/null +++ b/backend/src/ee/routes/v1/action.ts @@ -0,0 +1,17 @@ +import express from 'express'; +const router = express.Router(); +import { + validateRequest +} from '../../../middleware'; +import { param } from 'express-validator'; +import { actionController } from '../../controllers/v1'; + +// TODO: put into action controller +router.get( + '/:actionId', + param('actionId').exists().trim(), + validateRequest, + actionController.getAction +); + +export default router; \ No newline at end of file diff --git a/backend/src/ee/routes/v1/index.ts b/backend/src/ee/routes/v1/index.ts index 960665f4a..612715111 100644 --- a/backend/src/ee/routes/v1/index.ts +++ b/backend/src/ee/routes/v1/index.ts @@ -1,7 +1,11 @@ import secret from './secret'; +import secretSnapshot from './secretSnapshot'; import workspace from './workspace'; +import action from './action'; export { secret, - workspace + secretSnapshot, + workspace, + action } \ No newline at end of file diff --git a/backend/src/ee/routes/v1/secretSnapshot.ts b/backend/src/ee/routes/v1/secretSnapshot.ts new file mode 100644 index 000000000..80aa7d1ee --- /dev/null +++ b/backend/src/ee/routes/v1/secretSnapshot.ts @@ -0,0 +1,27 @@ +import express from 'express'; +const router = express.Router(); +import { + requireSecretSnapshotAuth +} from '../../middleware'; +import { + requireAuth, + validateRequest +} from '../../../middleware'; +import { param } from 'express-validator'; +import { ADMIN, MEMBER } from '../../../variables'; +import { secretSnapshotController } from '../../controllers/v1'; + +router.get( + '/:secretSnapshotId', + requireAuth({ + acceptedAuthModes: ['jwt'] + }), + requireSecretSnapshotAuth({ + acceptedRoles: [ADMIN, MEMBER] + }), + param('secretSnapshotId').exists().trim(), + validateRequest, + secretSnapshotController.getSecretSnapshot +); + +export default router; \ No newline at end of file diff --git a/backend/src/ee/routes/v1/workspace.ts b/backend/src/ee/routes/v1/workspace.ts index 6a7f11626..4b2e839eb 100644 --- a/backend/src/ee/routes/v1/workspace.ts +++ b/backend/src/ee/routes/v1/workspace.ts @@ -24,4 +24,35 @@ router.get( workspaceController.getWorkspaceSecretSnapshots ); +router.get( + '/:workspaceId/secret-snapshots/count', + requireAuth({ + acceptedAuthModes: ['jwt'] + }), + requireWorkspaceAuth({ + acceptedRoles: [ADMIN, MEMBER] + }), + param('workspaceId').exists().trim(), + validateRequest, + workspaceController.getWorkspaceSecretSnapshotsCount +); + +router.get( + '/:workspaceId/logs', + requireAuth({ + acceptedAuthModes: ['jwt'] + }), + requireWorkspaceAuth({ + acceptedRoles: [ADMIN, MEMBER] + }), + param('workspaceId').exists().trim(), + query('offset').exists().isInt(), + query('limit').exists().isInt(), + query('sortBy'), + query('userId'), + query('actionNames'), + validateRequest, + workspaceController.getWorkspaceLogs +); + export default router; \ No newline at end of file diff --git a/backend/src/ee/services/EELogService.ts b/backend/src/ee/services/EELogService.ts new file mode 100644 index 000000000..c1b2da6fb --- /dev/null +++ b/backend/src/ee/services/EELogService.ts @@ -0,0 +1,81 @@ +import { Types } from 'mongoose'; +import { + Log, + Action, + IAction +} from '../models'; +import { + createLogHelper +} from '../helpers/log'; +import { + createActionSecretHelper +} from '../helpers/action'; +import EELicenseService from './EELicenseService'; + +/** + * Class to handle Enterprise Edition log actions + */ +class EELogService { + /** + * Create an (audit) log + * @param {Object} obj + * @param {String} obj.userId - id of user associated with the log + * @param {String} obj.workspaceId - id of workspace associated with the log + * @param {Action} obj.actions - actions to include in log + * @param {String} obj.channel - channel (web/cli/auto) associated with the log + * @param {String} obj.ipAddress - ip address associated with the log + * @returns {Log} log - new audit log + */ + static async createLog({ + userId, + workspaceId, + actions, + channel, + ipAddress + }: { + userId: string; + workspaceId: string; + actions: IAction[]; + channel: string; + ipAddress: string; + }) { + if (!EELicenseService.isLicenseValid) return null; + return await createLogHelper({ + userId, + workspaceId, + actions, + channel, + ipAddress + }) + } + + /** + * Create an (audit) action for secrets including + * add, delete, update, and read actions. + * @param {Object} obj + * @param {String} obj.name - name of action + * @param {ObjectId[]} obj.secretIds - secret ids + * @returns {Action} action - new action + */ + static async createActionSecret({ + name, + userId, + workspaceId, + secretIds + }: { + name: string; + userId: string; + workspaceId: string; + secretIds: Types.ObjectId[]; + }) { + if (!EELicenseService.isLicenseValid) return null; + return await createActionSecretHelper({ + name, + userId, + workspaceId, + secretIds + }); + } +} + +export default EELogService; \ No newline at end of file diff --git a/backend/src/ee/services/EESecretService.ts b/backend/src/ee/services/EESecretService.ts index 643f763f1..cea614c96 100644 --- a/backend/src/ee/services/EESecretService.ts +++ b/backend/src/ee/services/EESecretService.ts @@ -1,7 +1,10 @@ +import { Types } from 'mongoose'; import { ISecretVersion } from '../models'; import { takeSecretSnapshotHelper, - addSecretVersionsHelper + addSecretVersionsHelper, + markDeletedSecretVersionsHelper, + initSecretVersioningHelper } from '../helpers/secret'; import EELicenseService from './EELicenseService'; @@ -11,12 +14,13 @@ import EELicenseService from './EELicenseService'; class EESecretService { /** - * Save a copy of the current state of secrets in workspace with id + * Save a secret snapshot that is a copy of the current state of secrets in workspace with id * [workspaceId] under a new snapshot with incremented version under the * SecretSnapshot collection. * Requires a valid license key [licenseKey] * @param {Object} obj * @param {String} obj.workspaceId + * @returns {SecretSnapshot} secretSnapshot - new secret snpashot */ static async takeSecretSnapshot({ workspaceId @@ -24,13 +28,14 @@ class EESecretService { workspaceId: string; }) { if (!EELicenseService.isLicenseValid) return; - await takeSecretSnapshotHelper({ workspaceId }); + return await takeSecretSnapshotHelper({ workspaceId }); } /** - * Adds secret versions [secretVersions] to the SecretVersion collection. + * Add secret versions [secretVersions] to the SecretVersion collection. * @param {Object} obj - * @param {SecretVersion} obj.secretVersions + * @param {Object[]} obj.secretVersions + * @returns {SecretVersion[]} newSecretVersions - new secret versions */ static async addSecretVersions({ secretVersions @@ -38,10 +43,36 @@ class EESecretService { secretVersions: ISecretVersion[]; }) { if (!EELicenseService.isLicenseValid) return; - await addSecretVersionsHelper({ + return await addSecretVersionsHelper({ secretVersions }); } + + /** + * Mark secret versions associated with secrets with ids [secretIds] + * as deleted. + * @param {Object} obj + * @param {ObjectId[]} obj.secretIds - secret ids + */ + static async markDeletedSecretVersions({ + secretIds + }: { + secretIds: Types.ObjectId[]; + }) { + if (!EELicenseService.isLicenseValid) return; + await markDeletedSecretVersionsHelper({ + secretIds + }); + } + + /** + * Initialize secret versioning by setting previously unversioned + * secrets to version 1 and begin populating secret versions. + */ + static async initSecretVersioning() { + if (!EELicenseService.isLicenseValid) return; + await initSecretVersioningHelper(); + } } export default EESecretService; \ No newline at end of file diff --git a/backend/src/ee/services/index.ts b/backend/src/ee/services/index.ts index 3cec256bb..b3544bcff 100644 --- a/backend/src/ee/services/index.ts +++ b/backend/src/ee/services/index.ts @@ -1,7 +1,9 @@ import EELicenseService from "./EELicenseService"; import EESecretService from "./EESecretService"; +import EELogService from "./EELogService"; export { EELicenseService, - EESecretService + EESecretService, + EELogService } \ No newline at end of file diff --git a/backend/src/ee/variables.ts b/backend/src/ee/variables.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/src/events/secret.ts b/backend/src/events/secret.ts index 8bb3a86c3..479255a31 100644 --- a/backend/src/events/secret.ts +++ b/backend/src/events/secret.ts @@ -1,4 +1,7 @@ -import { EVENT_PUSH_SECRETS } from '../variables'; +import { + EVENT_PUSH_SECRETS, + EVENT_PULL_SECRETS +} from '../variables'; interface PushSecret { ciphertextKey: string; @@ -19,7 +22,7 @@ interface PushSecret { * @returns */ const eventPushSecrets = ({ - workspaceId, + workspaceId }: { workspaceId: string; }) => { @@ -32,6 +35,26 @@ const eventPushSecrets = ({ }); } +/** + * Return event for pulling secrets + * @param {Object} obj + * @param {String} obj.workspaceId - id of workspace to pull secrets from + * @returns + */ +const eventPullSecrets = ({ + workspaceId, +}: { + workspaceId: string; +}) => { + return ({ + name: EVENT_PULL_SECRETS, + workspaceId, + payload: { + + } + }); +} + export { eventPushSecrets } diff --git a/backend/src/helpers/database.ts b/backend/src/helpers/database.ts new file mode 100644 index 000000000..1ba3bb911 --- /dev/null +++ b/backend/src/helpers/database.ts @@ -0,0 +1,31 @@ +import mongoose from 'mongoose'; +import { ISecret, Secret } from '../models'; +import { EESecretService } from '../ee/services'; +import { getLogger } from '../utils/logger'; + +/** + * Initialize database connection + * @param {Object} obj + * @param {String} obj.mongoURL - mongo connection string + * @returns + */ +const initDatabaseHelper = async ({ + mongoURL +}: { + mongoURL: string; +}) => { + try { + await mongoose.connect(mongoURL); + getLogger("database").info("Database connection established"); + + await EESecretService.initSecretVersioning(); + } catch (err) { + getLogger("database").error(`Unable to establish Database connection due to the error.\n${err}`); + } + + return mongoose.connection; +} + +export { + initDatabaseHelper +} \ No newline at end of file diff --git a/backend/src/helpers/secret.ts b/backend/src/helpers/secret.ts index f055971ae..920e8dc1d 100644 --- a/backend/src/helpers/secret.ts +++ b/backend/src/helpers/secret.ts @@ -1,19 +1,24 @@ import * as Sentry from '@sentry/node'; +import { Types } from 'mongoose'; import { Secret, ISecret, } from '../models'; import { - EESecretService + EESecretService, + EELogService } from '../ee/services'; import { - SecretVersion + IAction } from '../ee/models'; -import { - takeSecretSnapshotHelper -} from '../ee/helpers/secret'; -import { decryptSymmetric } from '../utils/crypto'; -import { SECRET_SHARED, SECRET_PERSONAL } from '../variables'; +import { + SECRET_SHARED, + SECRET_PERSONAL, + ACTION_ADD_SECRETS, + ACTION_UPDATE_SECRETS, + ACTION_DELETE_SECRETS, + ACTION_READ_SECRETS +} from '../variables'; interface V1PushSecret { ciphertextKey: string; @@ -51,8 +56,6 @@ interface Update { [index: string]: any; } -type DecryptSecretType = 'text' | 'object' | 'expanded'; - /** * Push secrets for user with id [userId] to workspace * with id [workspaceId] with environment [environment]. Follow steps: @@ -68,7 +71,7 @@ const v1PushSecrets = async ({ userId, workspaceId, environment, - secrets + secrets, }: { userId: string; workspaceId: string; @@ -78,7 +81,7 @@ const v1PushSecrets = async ({ // TODO: clean up function and fix up types try { // construct useful data structures - const oldSecrets = await pullSecrets({ + const oldSecrets = await getSecrets({ userId, workspaceId, environment @@ -101,11 +104,9 @@ const v1PushSecrets = async ({ await Secret.deleteMany({ _id: { $in: toDelete } }); - - await SecretVersion.updateMany({ - secret: { $in: toDelete } - }, { - isDeleted: true + + await EESecretService.markDeletedSecretVersions({ + secretIds: toDelete }); } @@ -188,6 +189,10 @@ const v1PushSecrets = async ({ return ({ secret: _id, version: version ? version + 1 : 1, + workspace: new Types.ObjectId(workspaceId), + type: newSecret.type, + user: new Types.ObjectId(userId), + environment, isDeleted: false, secretKeyCiphertext: newSecret.ciphertextKey, secretKeyIV: newSecret.ivKey, @@ -239,6 +244,11 @@ const v1PushSecrets = async ({ EESecretService.addSecretVersions({ secretVersions: newSecrets.map(({ _id, + version, + workspace, + type, + user, + environment, secretKeyCiphertext, secretKeyIV, secretKeyTag, @@ -249,7 +259,11 @@ const v1PushSecrets = async ({ secretValueHash }) => ({ secret: _id, - version: 1, + version, + workspace, + type, + user, + environment, isDeleted: false, secretKeyCiphertext, secretKeyIV, @@ -284,22 +298,30 @@ const v1PushSecrets = async ({ * @param {String} obj.workspaceId - id of workspace to push to * @param {String} obj.environment - environment for secrets * @param {Object[]} obj.secrets - secrets to push + * @param {String} obj.channel - channel (web/cli/auto) + * @param {String} obj.ipAddress - ip address of request to push secrets */ const v2PushSecrets = async ({ userId, workspaceId, environment, - secrets + secrets, + channel, + ipAddress }: { userId: string; workspaceId: string; environment: string; secrets: V2PushSecret[]; + channel: string; + ipAddress: string; }): Promise => { // TODO: clean up function and fix up types try { + const actions: IAction[] = []; + // construct useful data structures - const oldSecrets = await pullSecrets({ + const oldSecrets = await getSecrets({ userId, workspaceId, environment @@ -322,12 +344,19 @@ const v1PushSecrets = async ({ await Secret.deleteMany({ _id: { $in: toDelete } }); - - await SecretVersion.updateMany({ - secret: { $in: toDelete } - }, { - isDeleted: true + + await EESecretService.markDeletedSecretVersions({ + secretIds: toDelete }); + + const deleteAction = await EELogService.createActionSecret({ + name: ACTION_DELETE_SECRETS, + userId, + workspaceId, + secretIds: toDelete + }); + + deleteAction && actions.push(deleteAction); } const toUpdate = oldSecrets @@ -348,118 +377,10 @@ const v1PushSecrets = async ({ return false; }); - const operations = toUpdate - .map((s) => { - const { - secretValueCiphertext, - secretValueIV, - secretValueTag, - secretValueHash, - secretCommentCiphertext, - secretCommentIV, - secretCommentTag, - secretCommentHash, - } = newSecretsObj[`${s.type}-${s.secretKeyHash}`]; - - const update: Update = { - secretValueCiphertext, - secretValueIV, - secretValueTag, - secretValueHash, - secretCommentCiphertext, - secretCommentIV, - secretCommentTag, - secretCommentHash, - } - - if (!s.version) { - // case: (legacy) secret was not versioned - update.version = 1; - } else { - update['$inc'] = { - version: 1 - } - } - - if (s.type === SECRET_PERSONAL) { - // attach user associated with the personal secret - update['user'] = userId; - } - - return { - updateOne: { - filter: { - _id: oldSecretsObj[`${s.type}-${s.secretKeyHash}`]._id - }, - update - } - }; - }); - await Secret.bulkWrite(operations as any); - - // (EE) add secret versions for updated secrets - await EESecretService.addSecretVersions({ - secretVersions: toUpdate.map((s) => { - const { - secretKeyCiphertext, - secretKeyIV, - secretKeyTag, - secretKeyHash, - secretValueCiphertext, - secretValueIV, - secretValueTag, - secretValueHash, - secretCommentCiphertext, - secretCommentIV, - secretCommentTag, - secretCommentHash, - } = newSecretsObj[`${s.type}-${s.secretKeyHash}`]; - - return ({ - secret: s._id, - version: s.version ? s.version + 1 : 1, - isDeleted: false, - secretKeyCiphertext, - secretKeyIV, - secretKeyTag, - secretKeyHash, - secretValueCiphertext, - secretValueIV, - secretValueTag, - secretValueHash - }) - }) - }); - - // handle adding new secrets - const toAdd = secrets.filter((s) => !(`${s.type}-${s.secretKeyHash}` in oldSecretsObj)); - - if (toAdd.length > 0) { - // add secrets - const newSecrets = await Secret.insertMany( - toAdd.map(({ - secretKeyCiphertext, - secretKeyIV, - secretKeyTag, - secretKeyHash, - secretValueCiphertext, - secretValueIV, - secretValueTag, - secretValueHash, - secretCommentCiphertext, - secretCommentIV, - secretCommentTag, - secretCommentHash, - }, idx) => { - const obj: any = { - version: 1, - workspace: workspaceId, - type: toAdd[idx].type, - environment, - secretKeyCiphertext, - secretKeyIV, - secretKeyTag, - secretKeyHash, + if (toUpdate.length > 0) { + const operations = toUpdate + .map((s) => { + const { secretValueCiphertext, secretValueIV, secretValueTag, @@ -467,49 +388,120 @@ const v1PushSecrets = async ({ secretCommentCiphertext, secretCommentIV, secretCommentTag, - secretCommentHash - }; + secretCommentHash, + } = newSecretsObj[`${s.type}-${s.secretKeyHash}`]; - if (toAdd[idx].type === 'personal') { - obj['user' as keyof typeof obj] = userId; + const update: Update = { + secretValueCiphertext, + secretValueIV, + secretValueTag, + secretValueHash, + secretCommentCiphertext, + secretCommentIV, + secretCommentTag, + secretCommentHash, } - return obj; - }) + if (!s.version) { + // case: (legacy) secret was not versioned + update.version = 1; + } else { + update['$inc'] = { + version: 1 + } + } + + if (s.type === SECRET_PERSONAL) { + // attach user associated with the personal secret + update['user'] = userId; + } + + return { + updateOne: { + filter: { + _id: oldSecretsObj[`${s.type}-${s.secretKeyHash}`]._id + }, + update + } + }; + }); + await Secret.bulkWrite(operations as any); + + // (EE) add secret versions for updated secrets + await EESecretService.addSecretVersions({ + secretVersions: toUpdate.map((s) => { + return ({ + ...newSecretsObj[`${s.type}-${s.secretKeyHash}`], + secret: s._id, + version: s.version ? s.version + 1 : 1, + workspace: new Types.ObjectId(workspaceId), + user: s.user, + environment: s.environment, + isDeleted: false + }) + }) + }); + + const updateAction = await EELogService.createActionSecret({ + name: ACTION_UPDATE_SECRETS, + userId, + workspaceId, + secretIds: toUpdate.map((u) => u._id) + }); + + updateAction && actions.push(updateAction); + } + + // handle adding new secrets + const toAdd = secrets.filter((s) => !(`${s.type}-${s.secretKeyHash}` in oldSecretsObj)); + + if (toAdd.length > 0) { + // add secrets + const newSecrets = await Secret.insertMany( + toAdd.map((s, idx) => ({ + ...s, + version: 1, + workspace: workspaceId, + type: toAdd[idx].type, + environment, + ...( toAdd[idx].type === 'personal' ? { user: userId } : {}) + })) ); // (EE) add secret versions for new secrets EESecretService.addSecretVersions({ - secretVersions: newSecrets.map(({ - _id, - secretKeyCiphertext, - secretKeyIV, - secretKeyTag, - secretKeyHash, - secretValueCiphertext, - secretValueIV, - secretValueTag, - secretValueHash - }) => ({ - secret: _id, - version: 1, - isDeleted: false, - secretKeyCiphertext, - secretKeyIV, - secretKeyTag, - secretKeyHash, - secretValueCiphertext, - secretValueIV, - secretValueTag, - secretValueHash - })) + secretVersions: newSecrets.map((secretDocument) => { + return { + ...secretDocument.toObject(), + secret: secretDocument._id, + isDeleted: false + }}) }); + + const addAction = await EELogService.createActionSecret({ + name: ACTION_ADD_SECRETS, + userId, + workspaceId, + secretIds: newSecrets.map((n) => n._id) + }); + addAction && actions.push(addAction); } // (EE) take a secret snapshot await EESecretService.takeSecretSnapshot({ workspaceId }) + + // (EE) create (audit) log + if (actions.length > 0) { + await EELogService.createLog({ + userId, + workspaceId, + actions, + channel, + ipAddress + }); + } } catch (err) { Sentry.setUser(null); Sentry.captureException(err); @@ -518,15 +510,14 @@ const v1PushSecrets = async ({ }; /** - * Pull secrets for user with id [userId] for workspace + * Get secrets for user with id [userId] for workspace * with id [workspaceId] with environment [environment] * @param {Object} obj * @param {String} obj.userId -id of user to pull secrets for * @param {String} obj.workspaceId - id of workspace to pull from * @param {String} obj.environment - environment for secrets - * */ -const pullSecrets = async ({ + const getSecrets = async ({ userId, workspaceId, environment @@ -563,9 +554,64 @@ const pullSecrets = async ({ return secrets; }; +/** + * Pull secrets for user with id [userId] for workspace + * with id [workspaceId] with environment [environment] + * @param {Object} obj + * @param {String} obj.userId -id of user to pull secrets for + * @param {String} obj.workspaceId - id of workspace to pull from + * @param {String} obj.environment - environment for secrets + * @param {String} obj.channel - channel (web/cli/auto) + * @param {String} obj.ipAddress - ip address of request to push secrets + */ +const pullSecrets = async ({ + userId, + workspaceId, + environment, + channel, + ipAddress +}: { + userId: string; + workspaceId: string; + environment: string; + channel: string; + ipAddress: string; +}): Promise => { + let secrets: any; + + try { + secrets = await getSecrets({ + userId, + workspaceId, + environment + }) + + const readAction = await EELogService.createActionSecret({ + name: ACTION_READ_SECRETS, + userId, + workspaceId, + secretIds: secrets.map((n: any) => n._id) + }); + + readAction && await EELogService.createLog({ + userId, + workspaceId, + actions: [readAction], + channel, + ipAddress + }); + } catch (err) { + Sentry.setUser(null); + Sentry.captureException(err); + throw new Error('Failed to pull shared and personal secrets'); + } + + return secrets; +}; + /** * Reformat output of pullSecrets() to be compatible with how existing - * clients handle secrets + * web client handle secrets * @param {Object} obj * @param {Object} obj.secrets */ diff --git a/backend/src/index.ts b/backend/src/index.ts index d182c2655..bc07ec3b9 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -4,12 +4,12 @@ dotenv.config(); import * as Sentry from '@sentry/node'; import { SENTRY_DSN, NODE_ENV, MONGO_URL } from './config'; import { server } from './app'; -import { initDatabase } from './services/database'; +import { DatabaseService } from './services'; import { setUpHealthEndpoint } from './services/health'; import { initSmtp } from './services/smtp'; import { setTransporter } from './helpers/nodemailer'; -initDatabase(MONGO_URL); +DatabaseService.initDatabase(MONGO_URL); setUpHealthEndpoint(server); diff --git a/backend/src/models/user.ts b/backend/src/models/user.ts index aa1c5d239..7ea988c9d 100644 --- a/backend/src/models/user.ts +++ b/backend/src/models/user.ts @@ -11,7 +11,7 @@ export interface IUser { tag?: string; salt?: string; verifier?: string; - refreshVersion?: Number; + refreshVersion?: number; } const userSchema = new Schema( @@ -52,7 +52,8 @@ const userSchema = new Schema( }, refreshVersion: { type: Number, - default: 0 + default: 0, + select: false } }, { diff --git a/backend/src/routes/v1/userAction.ts b/backend/src/routes/v1/userAction.ts index 4caa890c0..b14ab3471 100644 --- a/backend/src/routes/v1/userAction.ts +++ b/backend/src/routes/v1/userAction.ts @@ -4,6 +4,7 @@ import { requireAuth, validateRequest } from '../../middleware'; import { body, query } from 'express-validator'; import { userActionController } from '../../controllers/v1'; +// note: [userAction] will be deprecated in /v2 in favor of [action] router.post( '/', requireAuth({ diff --git a/backend/src/routes/v2/secret.ts b/backend/src/routes/v2/secret.ts index 95ce3e6b0..52e0e316e 100644 --- a/backend/src/routes/v2/secret.ts +++ b/backend/src/routes/v2/secret.ts @@ -2,7 +2,7 @@ import express, { Request, Response } from 'express'; import { requireAuth, requireWorkspaceAuth, validateRequest } from '../../middleware'; import { body, param, query } from 'express-validator'; import { ADMIN, MEMBER } from '../../variables'; -import { CreateSecretRequestBody, ModifySecretRequestBody } from '../../types/secret/types'; +import { CreateSecretRequestBody, ModifySecretRequestBody } from '../../types/secret'; import { secretController } from '../../controllers/v2'; import { fetchAllSecrets } from '../../controllers/v2/secretController'; diff --git a/backend/src/services/DatabaseService.ts b/backend/src/services/DatabaseService.ts new file mode 100644 index 000000000..2e8dc839f --- /dev/null +++ b/backend/src/services/DatabaseService.ts @@ -0,0 +1,16 @@ +import mongoose from 'mongoose'; +import { getLogger } from '../utils/logger'; +import { initDatabaseHelper } from '../helpers/database'; + +/** + * Class to handle database actions + */ +class DatabaseService { + static async initDatabase(MONGO_URL: string) { + return await initDatabaseHelper({ + mongoURL: MONGO_URL + }); + } +} + +export default DatabaseService; \ No newline at end of file diff --git a/backend/src/services/database.ts b/backend/src/services/database.ts deleted file mode 100644 index 85f39c1b2..000000000 --- a/backend/src/services/database.ts +++ /dev/null @@ -1,10 +0,0 @@ -import mongoose from 'mongoose'; -import { getLogger } from '../utils/logger'; - -export const initDatabase = (MONGO_URL: string) => { - mongoose - .connect(MONGO_URL) - .then(() => getLogger("database").info("Database connection established")) - .catch((e) => getLogger("database").error(`Unable to establish Database connection due to the error.\n${e}`)); - return mongoose.connection; -}; diff --git a/backend/src/services/index.ts b/backend/src/services/index.ts index 531033f30..c53829922 100644 --- a/backend/src/services/index.ts +++ b/backend/src/services/index.ts @@ -1,9 +1,11 @@ +import DatabaseService from './DatabaseService'; import postHogClient from './PostHogClient'; import BotService from './BotService'; import EventService from './EventService'; import IntegrationService from './IntegrationService'; export { + DatabaseService, postHogClient, BotService, EventService, diff --git a/backend/src/types/express/index.d.ts b/backend/src/types/express/index.d.ts index 7b98d924f..f43b5fa79 100644 --- a/backend/src/types/express/index.d.ts +++ b/backend/src/types/express/index.d.ts @@ -13,6 +13,7 @@ declare global { integrationAuth: any; bot: any; secret: any; + secretSnapshot: any; serviceToken: any; accessToken: any; serviceTokenData: any; diff --git a/backend/src/types/secret/types.ts b/backend/src/types/secret/index.d.ts similarity index 100% rename from backend/src/types/secret/types.ts rename to backend/src/types/secret/index.d.ts diff --git a/backend/src/utils/errors.ts b/backend/src/utils/errors.ts index 9c8ac852b..e9972edf5 100644 --- a/backend/src/utils/errors.ts +++ b/backend/src/utils/errors.ts @@ -123,6 +123,16 @@ export const SecretNotFoundError = (error?: Partial) => new stack: error?.stack }); +//* ----->[SECRET SNAPSHOT ERRORS]<----- +export const SecretSnapshotNotFoundError = (error?: Partial) => new RequestError({ + logLevel: error?.logLevel ?? LogLevel.ERROR, + statusCode: error?.statusCode ?? 404, + type: error?.type ?? 'secret_snapshot_not_found_error', + message: error?.message ?? 'The requested secret snapshot was not found', + context: error?.context, + stack: error?.stack +}); + //* ----->[ACTION ERRORS]<----- export const ActionNotFoundError = (error?: Partial) => new RequestError({ logLevel: error?.logLevel ?? LogLevel.ERROR, diff --git a/backend/src/variables/action.ts b/backend/src/variables/action.ts new file mode 100644 index 000000000..512eb8e8d --- /dev/null +++ b/backend/src/variables/action.ts @@ -0,0 +1,11 @@ +const ACTION_ADD_SECRETS = 'addSecrets'; +const ACTION_DELETE_SECRETS = 'deleteSecrets'; +const ACTION_UPDATE_SECRETS = 'updateSecrets'; +const ACTION_READ_SECRETS = 'readSecrets'; + +export { + ACTION_ADD_SECRETS, + ACTION_DELETE_SECRETS, + ACTION_UPDATE_SECRETS, + ACTION_READ_SECRETS +} \ No newline at end of file diff --git a/backend/src/variables/index.ts b/backend/src/variables/index.ts index dac4f0646..16c068925 100644 --- a/backend/src/variables/index.ts +++ b/backend/src/variables/index.ts @@ -31,6 +31,12 @@ import { } from './organization'; import { SECRET_SHARED, SECRET_PERSONAL } from './secret'; import { EVENT_PUSH_SECRETS, EVENT_PULL_SECRETS } from './event'; +import { + ACTION_ADD_SECRETS, + ACTION_UPDATE_SECRETS, + ACTION_DELETE_SECRETS, + ACTION_READ_SECRETS +} from './action'; import { SMTP_HOST_SENDGRID, SMTP_HOST_MAILGUN } from './smtp'; import { PLAN_STARTER, PLAN_PRO } from './stripe'; @@ -63,6 +69,10 @@ export { INTEGRATION_GITHUB_API_URL, EVENT_PUSH_SECRETS, EVENT_PULL_SECRETS, + ACTION_ADD_SECRETS, + ACTION_UPDATE_SECRETS, + ACTION_DELETE_SECRETS, + ACTION_READ_SECRETS, INTEGRATION_OPTIONS, SMTP_HOST_SENDGRID, SMTP_HOST_MAILGUN, diff --git a/backend/src/variables/integration.ts b/backend/src/variables/integration.ts index 00e817c57..ed18c5a2a 100644 --- a/backend/src/variables/integration.ts +++ b/backend/src/variables/integration.ts @@ -48,7 +48,7 @@ const INTEGRATION_OPTIONS = [ name: 'Vercel', slug: 'vercel', image: 'Vercel', - isAvailable: true, + isAvailable: false, type: 'vercel', clientId: '', clientSlug: CLIENT_SLUG_VERCEL, @@ -58,7 +58,7 @@ const INTEGRATION_OPTIONS = [ name: 'Netlify', slug: 'netlify', image: 'Netlify', - isAvailable: true, + isAvailable: false, type: 'oauth2', clientId: CLIENT_ID_NETLIFY, docsLink: '' @@ -67,7 +67,7 @@ const INTEGRATION_OPTIONS = [ name: 'GitHub', slug: 'github', image: 'GitHub', - isAvailable: true, + isAvailable: false, type: 'oauth2', clientId: CLIENT_ID_GITHUB, docsLink: '' diff --git a/cli/go.mod b/cli/go.mod index 956e9bb29..6b7d92489 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -13,7 +13,6 @@ require ( require ( github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect - github.com/Luzifer/go-openssl/v4 v4.1.0 // indirect github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -22,6 +21,8 @@ require ( github.com/go-openapi/strfmt v0.21.3 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/mattn/go-colorable v0.1.9 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mitchellh/mapstructure v1.3.3 // indirect github.com/mtibben/percent v0.2.1 // indirect @@ -35,7 +36,7 @@ require ( ) require ( - github.com/Luzifer/go-openssl v2.0.0+incompatible + github.com/fatih/color v1.13.0 github.com/go-resty/resty/v2 v2.7.0 github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jedib0t/go-pretty v4.3.0+incompatible diff --git a/cli/go.sum b/cli/go.sum index 2b8836515..f7e17c62a 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -2,10 +2,6 @@ github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMb github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= -github.com/Luzifer/go-openssl v2.0.0+incompatible h1:EpNNxrPDji4rRzE0KeOeIeV7pHyKe8zF9oNnAXy4mBY= -github.com/Luzifer/go-openssl v2.0.0+incompatible/go.mod h1:t2qnLjT8WQ3usGU1R8uAqjY4T7CK7eMg9vhQ3l9Ue/Y= -github.com/Luzifer/go-openssl/v4 v4.1.0 h1:8qi3Z6f8Aflwub/Cs4FVSmKUEg/lC8GlODbR2TyZ+nM= -github.com/Luzifer/go-openssl/v4 v4.1.0/go.mod h1:3i1T3Pe6eQK19d86WhuQzjLyMwBaNmGmt3ZceWpWVa4= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -26,6 +22,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/go-openapi/errors v0.20.2 h1:dxy7PGTqEh94zj2E3h1cUmQQWiM1+aeCROfAr02EmK8= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= @@ -53,6 +51,11 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= +github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= @@ -100,23 +103,21 @@ github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgk github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= go.mongodb.org/mongo-driver v1.10.0 h1:UtV6N5k14upNp4LTduX0QCufG124fSu25Wz9tu94GLg= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -125,7 +126,6 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/cli/packages/api/api.go b/cli/packages/api/api.go new file mode 100644 index 000000000..782fa143c --- /dev/null +++ b/cli/packages/api/api.go @@ -0,0 +1,136 @@ +package api + +import ( + "fmt" + + "github.com/Infisical/infisical-merge/packages/config" + "github.com/go-resty/resty/v2" +) + +func CallBatchModifySecretsByWorkspaceAndEnv(httpClient *resty.Client, request BatchModifySecretsByWorkspaceAndEnvRequest) error { + endpoint := fmt.Sprintf("%v/v2/secret/batch-modify/workspace/%v/environment/%v", config.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName) + response, err := httpClient. + R(). + SetBody(request). + Patch(endpoint) + + if err != nil { + return fmt.Errorf("CallBatchModifySecretsByWorkspaceAndEnv: Unable to complete api request [err=%s]", err) + } + + if response.StatusCode() > 299 { + return fmt.Errorf("CallBatchModifySecretsByWorkspaceAndEnv: Unsuccessful response: [response=%s]", response) + } + + return nil +} + +func CallBatchCreateSecretsByWorkspaceAndEnv(httpClient *resty.Client, request BatchCreateSecretsByWorkspaceAndEnvRequest) error { + endpoint := fmt.Sprintf("%v/v2/secret/batch-create/workspace/%v/environment/%v", config.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName) + response, err := httpClient. + R(). + SetBody(request). + Post(endpoint) + + if err != nil { + return fmt.Errorf("CallBatchCreateSecretsByWorkspaceAndEnv: Unable to complete api request [err=%s]", err) + } + + if response.StatusCode() > 299 { + return fmt.Errorf("CallBatchCreateSecretsByWorkspaceAndEnv: Unsuccessful response: [response=%s]", response) + } + + return nil +} + +func CallBatchDeleteSecretsByWorkspaceAndEnv(httpClient *resty.Client, request BatchDeleteSecretsBySecretIdsRequest) error { + endpoint := fmt.Sprintf("%v/v2/secret/batch/workspace/%v/environment/%v", config.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName) + response, err := httpClient. + R(). + SetBody(request). + Delete(endpoint) + + if err != nil { + return fmt.Errorf("CallBatchDeleteSecretsByWorkspaceAndEnv: Unable to complete api request [err=%s]", err) + } + + if response.StatusCode() > 299 { + return fmt.Errorf("CallBatchDeleteSecretsByWorkspaceAndEnv: Unsuccessful response: [response=%s]", response) + } + + return nil +} + +func CallGetEncryptedWorkspaceKey(httpClient *resty.Client, request GetEncryptedWorkspaceKeyRequest) (GetEncryptedWorkspaceKeyResponse, error) { + endpoint := fmt.Sprintf("%v/v2/workspace/%v/encrypted-key", config.INFISICAL_URL, request.WorkspaceId) + var result GetEncryptedWorkspaceKeyResponse + response, err := httpClient. + R(). + SetResult(&result). + Get(endpoint) + + if err != nil { + return GetEncryptedWorkspaceKeyResponse{}, fmt.Errorf("CallGetEncryptedWorkspaceKey: Unable to complete api request [err=%s]", err) + } + + if response.StatusCode() > 299 { + return GetEncryptedWorkspaceKeyResponse{}, fmt.Errorf("CallGetEncryptedWorkspaceKey: Unsuccessful response: [response=%s]", response) + } + + return result, nil +} + +func CallGetServiceTokenDetailsV2(httpClient *resty.Client) (GetServiceTokenDetailsResponse, error) { + var tokenDetailsResponse GetServiceTokenDetailsResponse + response, err := httpClient. + R(). + SetResult(&tokenDetailsResponse). + Get(fmt.Sprintf("%v/v2/service-token", config.INFISICAL_URL)) + + if err != nil { + return GetServiceTokenDetailsResponse{}, fmt.Errorf("CallGetServiceTokenDetails: Unable to complete api request [err=%s]", err) + } + + if response.StatusCode() > 299 { + return GetServiceTokenDetailsResponse{}, fmt.Errorf("CallGetServiceTokenDetails: Unsuccessful response: [response=%s]", response) + } + + return tokenDetailsResponse, nil +} + +func CallGetSecretsV2(httpClient *resty.Client, request GetEncryptedSecretsV2Request) (GetEncryptedSecretsV2Response, error) { + var secretsResponse GetEncryptedSecretsV2Response + response, err := httpClient. + R(). + SetResult(&secretsResponse). + SetQueryParam("environment", request.EnvironmentName). + Get(fmt.Sprintf("%v/v2/secret/workspace/%v", config.INFISICAL_URL, request.WorkspaceId)) + + if err != nil { + return GetEncryptedSecretsV2Response{}, fmt.Errorf("CallGetSecretsV2: Unable to complete api request [err=%s]", err) + } + + if response.StatusCode() > 299 { + return GetEncryptedSecretsV2Response{}, fmt.Errorf("CallGetSecretsV2: Unsuccessful response: [response=%s]", response) + } + + return secretsResponse, nil +} + +func CallGetAllWorkSpacesUserBelongsTo(httpClient *resty.Client) (GetWorkSpacesResponse, error) { + var workSpacesResponse GetWorkSpacesResponse + response, err := httpClient. + R(). + SetResult(&workSpacesResponse). + Get(fmt.Sprintf("%v/v1/workspace", config.INFISICAL_URL)) + + if err != nil { + return GetWorkSpacesResponse{}, err + } + + if response.StatusCode() > 299 { + return GetWorkSpacesResponse{}, fmt.Errorf("CallGetAllWorkSpacesUserBelongsTo: Unsuccessful response: [response=%v]", response) + } + + return workSpacesResponse, nil +} diff --git a/cli/packages/models/api.go b/cli/packages/api/model.go similarity index 69% rename from cli/packages/models/api.go rename to cli/packages/api/model.go index d17200b87..b891a4af0 100644 --- a/cli/packages/models/api.go +++ b/cli/packages/api/model.go @@ -1,4 +1,4 @@ -package models +package api import "time" @@ -119,14 +119,13 @@ type PullSecretsByInfisicalTokenResponse struct { } type GetWorkSpacesResponse struct { - Workspaces []Workspace `json:"workspaces"` -} -type Workspace struct { - ID string `json:"_id"` - Name string `json:"name"` - Plan string `json:"plan,omitempty"` - V int `json:"__v"` - Organization string `json:"organization,omitempty"` + Workspaces []struct { + ID string `json:"_id"` + Name string `json:"name"` + Plan string `json:"plan,omitempty"` + V int `json:"__v"` + Organization string `json:"organization,omitempty"` + } `json:"workspaces"` } type Secret struct { @@ -169,30 +168,68 @@ type GetEncryptedWorkspaceKeyRequest struct { } type GetEncryptedWorkspaceKeyResponse struct { - LatestKey struct { - ID string `json:"_id"` - EncryptedKey string `json:"encryptedKey"` - Nonce string `json:"nonce"` - Sender struct { - ID string `json:"_id"` - Email string `json:"email"` - RefreshVersion int `json:"refreshVersion"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - V int `json:"__v"` - FirstName string `json:"firstName"` - LastName string `json:"lastName"` - PublicKey string `json:"publicKey"` - } `json:"sender"` - Receiver string `json:"receiver"` - Workspace string `json:"workspace"` - V int `json:"__v"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - } `json:"latestKey"` + ID string `json:"_id"` + EncryptedKey string `json:"encryptedKey"` + Nonce string `json:"nonce"` + Sender struct { + ID string `json:"_id"` + Email string `json:"email"` + RefreshVersion int `json:"refreshVersion"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + V int `json:"__v"` + FirstName string `json:"firstName"` + LastName string `json:"lastName"` + PublicKey string `json:"publicKey"` + } `json:"sender"` + Receiver string `json:"receiver"` + Workspace string `json:"workspace"` + V int `json:"__v"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` } type GetSecretsByWorkspaceIdAndEnvironmentRequest struct { EnvironmentName string `json:"environmentName"` WorkspaceId string `json:"workspaceId"` } + +type GetEncryptedSecretsV2Request struct { + EnvironmentName string `json:"environmentName"` + WorkspaceId string `json:"workspaceId"` +} + +type GetEncryptedSecretsV2Response []struct { + ID string `json:"_id"` + Version int `json:"version"` + Workspace string `json:"workspace"` + Type string `json:"type"` + Environment string `json:"environment"` + SecretKeyCiphertext string `json:"secretKeyCiphertext"` + SecretKeyIV string `json:"secretKeyIV"` + SecretKeyTag string `json:"secretKeyTag"` + SecretKeyHash string `json:"secretKeyHash"` + SecretValueCiphertext string `json:"secretValueCiphertext"` + SecretValueIV string `json:"secretValueIV"` + SecretValueTag string `json:"secretValueTag"` + SecretValueHash string `json:"secretValueHash"` + SecretCommentCiphertext string `json:"secretCommentCiphertext"` + SecretCommentIV string `json:"secretCommentIV"` + SecretCommentTag string `json:"secretCommentTag"` + SecretCommentHash string `json:"secretCommentHash"` + V int `json:"__v"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + User string `json:"user,omitempty"` +} + +type GetServiceTokenDetailsResponse struct { + ID string `json:"_id"` + Name string `json:"name"` + Workspace string `json:"workspace"` + Environment string `json:"environment"` + User string `json:"user"` + EncryptedKey string `json:"encryptedKey"` + Iv string `json:"iv"` + Tag string `json:"tag"` +} diff --git a/cli/packages/cmd/export.go b/cli/packages/cmd/export.go index f25a726e7..96d8817b5 100644 --- a/cli/packages/cmd/export.go +++ b/cli/packages/cmd/export.go @@ -29,58 +29,46 @@ var exportCmd = &cobra.Command{ DisableFlagsInUseLine: true, Example: "infisical export --env=prod --format=json > secrets.json", Args: cobra.NoArgs, - PreRun: toggleDebug, + PreRun: func(cmd *cobra.Command, args []string) { + toggleDebug(cmd, args) + util.RequireLogin() + util.RequireLocalWorkspaceFile() + }, Run: func(cmd *cobra.Command, args []string) { envName, err := cmd.Flags().GetString("env") if err != nil { - log.Errorln("Unable to parse the environment flag") - log.Debugln(err) - return + util.HandleError(err) } shouldExpandSecrets, err := cmd.Flags().GetBool("expand") if err != nil { - log.Errorln("Unable to parse the substitute flag") - log.Debugln(err) - return - } - - projectId, err := cmd.Flags().GetString("projectId") - if err != nil { - log.Errorln("Unable to parse the project id flag") - log.Debugln(err) - return + util.HandleError(err) } format, err := cmd.Flags().GetString("format") if err != nil { - log.Errorln("Unable to parse the format flag") - log.Debugln(err) - return + util.HandleError(err) } - envsFromApi, err := util.GetAllEnvironmentVariables(projectId, envName) + secrets, err := util.GetAllEnvironmentVariables(envName) if err != nil { - log.Errorln("Something went wrong when pulling secrets using your Infisical token. Double check the token, project id or environment name (dev, prod, ect.)") - log.Debugln(err) - return + util.HandleError(err, "Unable to fetch secrets") } var output string if shouldExpandSecrets { - substitutions := util.SubstituteSecrets(envsFromApi) + substitutions := util.SubstituteSecrets(secrets) output, err = formatEnvs(substitutions, format) if err != nil { - log.Errorln(err) - return + util.HandleError(err) } } else { - output, err = formatEnvs(envsFromApi, format) + output, err = formatEnvs(secrets, format) if err != nil { - log.Errorln(err) - return + util.HandleError(err) } } + fmt.Print(output) }, } @@ -88,7 +76,6 @@ var exportCmd = &cobra.Command{ func init() { rootCmd.AddCommand(exportCmd) exportCmd.Flags().StringP("env", "e", "dev", "Set the environment (dev, prod, etc.) from which your secrets should be pulled from") - exportCmd.Flags().String("projectId", "", "The project ID from which your secrets should be pulled from") exportCmd.Flags().Bool("expand", true, "Parse shell parameter expansions in your secrets") exportCmd.Flags().StringP("format", "f", "dotenv", "Set the format of the output file (dotenv, json, csv)") } diff --git a/cli/packages/cmd/init.go b/cli/packages/cmd/init.go index 2789f220d..a9a2d943d 100644 --- a/cli/packages/cmd/init.go +++ b/cli/packages/cmd/init.go @@ -5,10 +5,13 @@ package cmd import ( "encoding/json" + "fmt" "os" + "github.com/Infisical/infisical-merge/packages/api" "github.com/Infisical/infisical-merge/packages/models" "github.com/Infisical/infisical-merge/packages/util" + "github.com/go-resty/resty/v2" "github.com/manifoldco/promptui" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -21,21 +24,10 @@ var initCmd = &cobra.Command{ DisableFlagsInUseLine: true, Example: "infisical init", Args: cobra.ExactArgs(0), - PreRun: toggleDebug, + PreRun: func(cmd *cobra.Command, args []string) { + util.RequireLogin() + }, Run: func(cmd *cobra.Command, args []string) { - // check if user is logged - hasUserLoggedInbefore, loggedInUserEmail, err := util.IsUserLoggedIn() - if err != nil { - log.Info("Unexpected issue occurred while checking login status. To see more details, add flag --debug") - log.Debugln(err) - return - } - - if !hasUserLoggedInbefore { - log.Infoln("No logged in user. To login, please run command [infisical login]") - return - } - if util.WorkspaceConfigFileExistsInCurrentPath() { shouldOverride, err := shouldOverrideWorkspacePrompt() if err != nil { @@ -49,23 +41,22 @@ var initCmd = &cobra.Command{ } } - userCreds, err := util.GetUserCredsFromKeyRing(loggedInUserEmail) + userCreds, err := util.GetCurrentLoggedInUserDetails() if err != nil { - log.Infoln("Unable to get user creds from key ring") - log.Debug(err) - return + util.HandleError(err, "Unable to get your login details") } - workspaces, err := util.GetWorkSpacesFromAPI(userCreds) + httpClient := resty.New() + httpClient.SetAuthToken(userCreds.UserCredentials.JTWToken) + workspaceResponse, err := api.CallGetAllWorkSpacesUserBelongsTo(httpClient) if err != nil { - log.Errorln("Unable to pull your projects. To see more logs add the --debug flag to this command") - log.Debugln("Unable to get your projects because:", err) - return + util.HandleError(err, "Unable to pull projects that belong to you") } + workspaces := workspaceResponse.Workspaces if len(workspaces) == 0 { - log.Infoln("You don't have any projects created in Infisical. You must first create a project at https://infisical.com") - return + message := fmt.Sprintf("You don't have any projects created in Infisical. You must first create a project at %s", util.INFISICAL_TOKEN_NAME) + util.PrintMessageAndExit(message) } var workspaceNames []string @@ -81,16 +72,12 @@ var initCmd = &cobra.Command{ index, _, err := prompt.Run() if err != nil { - log.Errorln("Unable to parse your response") - log.Debug(err) - return + util.HandleError(err) } err = writeWorkspaceFile(workspaces[index]) if err != nil { - log.Errorln("Something went wrong when creating your workspace file") - log.Debug("Error while writing your workspace file:", err) - return + util.HandleError(err) } }, } diff --git a/cli/packages/cmd/login.go b/cli/packages/cmd/login.go index 9c0c22930..923782e3f 100644 --- a/cli/packages/cmd/login.go +++ b/cli/packages/cmd/login.go @@ -11,6 +11,9 @@ import ( "fmt" "regexp" + "github.com/Infisical/infisical-merge/packages/api" + "github.com/Infisical/infisical-merge/packages/config" + "github.com/Infisical/infisical-merge/packages/crypto" "github.com/Infisical/infisical-merge/packages/models" "github.com/Infisical/infisical-merge/packages/srp" "github.com/Infisical/infisical-merge/packages/util" @@ -27,18 +30,15 @@ var loginCmd = &cobra.Command{ DisableFlagsInUseLine: true, PreRun: toggleDebug, Run: func(cmd *cobra.Command, args []string) { - hasUserLoggedInbefore, currentLoggedInUserEmail, err := util.IsUserLoggedIn() - + currentLoggedInUserDetails, err := util.GetCurrentLoggedInUserDetails() if err != nil { - log.Debugln("Unable to get current logged in user.", err) + util.HandleError(err) } - if hasUserLoggedInbefore { - shouldOverride, err := shouldOverrideLoginPrompt(currentLoggedInUserEmail) + if currentLoggedInUserDetails.IsUserLoggedIn { + shouldOverride, err := shouldOverrideLoginPrompt(currentLoggedInUserDetails.UserCredentials.Email) if err != nil { - log.Errorln("Unable to parse your answer") - log.Debug(err) - return + util.HandleError(err) } if !shouldOverride { @@ -48,14 +48,12 @@ var loginCmd = &cobra.Command{ email, password, err := askForLoginCredentials() if err != nil { - log.Errorln("Unable to parse email and password for authentication") - log.Debugln(err) - return + util.HandleError(err, "Unable to parse email and password for authentication") } userCredentials, err := getFreshUserCredentials(email, password) if err != nil { - log.Errorln("Unable to authenticate with the provided credentials, please try again") + log.Infoln("Unable to authenticate with the provided credentials, please try again") log.Debugln(err) return } @@ -63,24 +61,20 @@ var loginCmd = &cobra.Command{ encryptedPrivateKey, _ := base64.StdEncoding.DecodeString(userCredentials.EncryptedPrivateKey) tag, err := base64.StdEncoding.DecodeString(userCredentials.Tag) if err != nil { - log.Errorln("Unable to decode the auth tag") - log.Debugln(err) + util.HandleError(err) } IV, err := base64.StdEncoding.DecodeString(userCredentials.IV) if err != nil { - log.Errorln("Unable to decode the IV/Nonce") - log.Debugln(err) + util.HandleError(err) } paddedPassword := fmt.Sprintf("%032s", password) key := []byte(paddedPassword) - decryptedPrivateKey, err := util.DecryptSymmetric(key, encryptedPrivateKey, tag, IV) + decryptedPrivateKey, err := crypto.DecryptSymmetric(key, encryptedPrivateKey, tag, IV) if err != nil || len(decryptedPrivateKey) == 0 { - log.Errorln("There was an issue decrypting your keys") - log.Debugln(err) - return + util.HandleError(err) } userCredentialsToBeStored := &models.UserCredentials{ @@ -100,9 +94,7 @@ var loginCmd = &cobra.Command{ err = util.WriteInitalConfig(userCredentialsToBeStored) if err != nil { - log.Errorln("Unable to write write to Infisical Config file. Please try again") - log.Debugln(err) - return + util.HandleError(err, "Unable to write write to Infisical Config file. Please try again") } log.Infoln("Nice! You are loggin as:", email) @@ -156,7 +148,7 @@ func askForLoginCredentials() (email string, password string, err error) { return userEmail, userPassword, nil } -func getFreshUserCredentials(email string, password string) (*models.LoginTwoResponse, error) { +func getFreshUserCredentials(email string, password string) (*api.LoginTwoResponse, error) { log.Debugln("getFreshUserCredentials:", "email", email, "password", password) httpClient := resty.New() httpClient.SetRetryCount(5) @@ -167,18 +159,18 @@ func getFreshUserCredentials(email string, password string) (*models.LoginTwoRes srpA := hex.EncodeToString(srpClient.ComputeA()) // ** Login one - loginOneRequest := models.LoginOneRequest{ + loginOneRequest := api.LoginOneRequest{ Email: email, ClientPublicKey: srpA, } - var loginOneResponseResult models.LoginOneResponse + var loginOneResponseResult api.LoginOneResponse loginOneResponse, err := httpClient. R(). SetBody(loginOneRequest). SetResult(&loginOneResponseResult). - Post(fmt.Sprintf("%v/v1/auth/login1", util.INFISICAL_URL)) + Post(fmt.Sprintf("%v/v1/auth/login1", config.INFISICAL_URL)) if err != nil { return nil, err @@ -204,17 +196,17 @@ func getFreshUserCredentials(email string, password string) (*models.LoginTwoRes srpM1 := srpClient.ComputeM1() - LoginTwoRequest := models.LoginTwoRequest{ + LoginTwoRequest := api.LoginTwoRequest{ Email: email, ClientProof: hex.EncodeToString(srpM1), } - var loginTwoResponseResult models.LoginTwoResponse + var loginTwoResponseResult api.LoginTwoResponse loginTwoResponse, err := httpClient. R(). SetBody(LoginTwoRequest). SetResult(&loginTwoResponseResult). - Post(fmt.Sprintf("%v/v1/auth/login2", util.INFISICAL_URL)) + Post(fmt.Sprintf("%v/v1/auth/login2", config.INFISICAL_URL)) if err != nil { return nil, err diff --git a/cli/packages/cmd/root.go b/cli/packages/cmd/root.go index f09f08800..b1b53d2ff 100644 --- a/cli/packages/cmd/root.go +++ b/cli/packages/cmd/root.go @@ -6,7 +6,7 @@ package cmd import ( "os" - "github.com/Infisical/infisical-merge/packages/util" + "github.com/Infisical/infisical-merge/packages/config" "github.com/spf13/cobra" ) @@ -15,7 +15,7 @@ var rootCmd = &cobra.Command{ Short: "Infisical CLI is used to inject environment variables into any process", Long: `Infisical is a simple, end-to-end encrypted service that enables teams to sync and manage their environment variables across their development life cycle.`, CompletionOptions: cobra.CompletionOptions{HiddenDefaultCmd: true}, - Version: "0.1.16", + Version: "0.2.0", } // Execute adds all child commands to the root command and sets flags appropriately. @@ -30,7 +30,7 @@ func Execute() { func init() { rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") rootCmd.PersistentFlags().BoolVarP(&debugLogging, "debug", "d", false, "Enable verbose logging") - rootCmd.PersistentFlags().StringVar(&util.INFISICAL_URL, "domain", "https://app.infisical.com/api", "Point the CLI to your own backend") + rootCmd.PersistentFlags().StringVar(&config.INFISICAL_URL, "domain", "https://app.infisical.com/api", "Point the CLI to your own backend") // rootCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) { // } } diff --git a/cli/packages/cmd/run.go b/cli/packages/cmd/run.go index 6e0133c8e..87b4cda4e 100644 --- a/cli/packages/cmd/run.go +++ b/cli/packages/cmd/run.go @@ -55,36 +55,26 @@ var runCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { envName, err := cmd.Flags().GetString("env") if err != nil { - log.Errorln("Unable to parse the environment flag") - log.Debugln(err) - return + util.HandleError(err, "Unable to parse flag") + } + + if !util.IsSecretEnvironmentValid(envName) { + util.PrintMessageAndExit("Invalid environment name passed. Environment names can only be prod, dev, test or staging") } secretOverriding, err := cmd.Flags().GetBool("secret-overriding") if err != nil { - log.Errorln("Unable to parse the secret-overriding flag") - log.Debugln(err) - return + util.HandleError(err, "Unable to parse flag") } shouldExpandSecrets, err := cmd.Flags().GetBool("expand") if err != nil { - log.Errorln("Unable to parse the substitute flag") - log.Debugln(err) - return + util.HandleError(err, "Unable to parse flag") } - projectId, err := cmd.Flags().GetString("projectId") + secrets, err := util.GetAllEnvironmentVariables(envName) if err != nil { - log.Errorln("Unable to parse the project id flag") - log.Debugln(err) - return - } - - secrets, err := util.GetAllEnvironmentVariables(projectId, envName) - if err != nil { - log.Debugln(err) - return + util.HandleError(err, "Could not fetch secrets", "If you are using a service token to fetch secrets, please ensure it is valid") } if shouldExpandSecrets { @@ -97,29 +87,26 @@ var runCmd = &cobra.Command{ if cmd.Flags().Changed("command") { command := cmd.Flag("command").Value.String() + err = executeMultipleCommandWithEnvs(command, secrets) if err != nil { - log.Errorf("Something went wrong when executing your command [error=%s]", err) - return + util.HandleError(err, "Unable to execute your chained command") } + } else { err = executeSingleCommandWithEnvs(args, secrets) if err != nil { - log.Errorf("Something went wrong when executing your command [error=%s]", err) - return + util.HandleError(err, "Unable to execute your single command") } - return } - }, } func init() { rootCmd.AddCommand(runCmd) runCmd.Flags().StringP("env", "e", "dev", "Set the environment (dev, prod, etc.) from which your secrets should be pulled from") - runCmd.Flags().String("projectId", "", "The project ID from which your secrets should be pulled from") runCmd.Flags().Bool("expand", true, "Parse shell parameter expansions in your secrets") - runCmd.Flags().Bool("secret-overriding", true, "Prioritizes personal secrets with the same name over shared secrets") + runCmd.Flags().Bool("secret-overriding", true, "Prioritizes personal secrets, if any, with the same name over shared secrets") runCmd.Flags().StringP("command", "c", "", "chained commands to execute (e.g. \"npm install && npm run dev; echo ...\")") } @@ -130,7 +117,7 @@ func executeSingleCommandWithEnvs(args []string, secrets []models.SingleEnvironm numberOfSecretsInjected := fmt.Sprintf("\u2713 Injected %v Infisical secrets into your application process successfully", len(secrets)) log.Infof("\x1b[%dm%s\x1b[0m", 32, numberOfSecretsInjected) log.Debugf("executing command: %s %s \n", command, strings.Join(argsForCommand, " ")) - log.Debugln("Secrets injected:", secrets) + log.Debugf("Secrets injected: %v", secrets) cmd := exec.Command(command, argsForCommand...) cmd.Stdin = os.Stdin @@ -158,7 +145,7 @@ func executeMultipleCommandWithEnvs(fullCommand string, secrets []models.SingleE numberOfSecretsInjected := fmt.Sprintf("\u2713 Injected %v Infisical secrets into your application process successfully", len(secrets)) log.Infof("\x1b[%dm%s\x1b[0m", 32, numberOfSecretsInjected) log.Debugf("executing command: %s %s %s \n", shell[0], shell[1], fullCommand) - log.Debugln("Secrets injected:", secrets) + log.Debugf("Secrets injected: %v", secrets) return execCmd(cmd) } diff --git a/cli/packages/cmd/secrets.go b/cli/packages/cmd/secrets.go index 5e6c4ca16..810da49c4 100644 --- a/cli/packages/cmd/secrets.go +++ b/cli/packages/cmd/secrets.go @@ -11,7 +11,8 @@ import ( "crypto/sha256" - "github.com/Infisical/infisical-merge/packages/http" + "github.com/Infisical/infisical-merge/packages/api" + "github.com/Infisical/infisical-merge/packages/crypto" "github.com/Infisical/infisical-merge/packages/models" "github.com/Infisical/infisical-merge/packages/util" "github.com/Infisical/infisical-merge/packages/visualize" @@ -30,35 +31,23 @@ var secretsCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { environmentName, err := cmd.Flags().GetString("env") if err != nil { - log.Errorln("Unable to parse the environment name flag") - log.Debugln(err) - return + util.HandleError(err) } shouldExpandSecrets, err := cmd.Flags().GetBool("expand") if err != nil { - log.Errorln("Unable to parse the substitute flag") - log.Debugln(err) - return + util.HandleError(err) } - workspaceFileExists := util.WorkspaceConfigFileExistsInCurrentPath() - if !workspaceFileExists { - log.Error("You have not yet connected to an Infisical Project. Please run [infisical init]") - return + secrets, err := util.GetAllEnvironmentVariables(environmentName) + if err != nil { + util.HandleError(err) } - secrets, err := util.GetAllEnvironmentVariables("", environmentName) - if shouldExpandSecrets { secrets = util.SubstituteSecrets(secrets) } - if err != nil { - log.Debugln(err) - return - } - visualize.PrintAllSecretDetails(secrets) }, } @@ -81,85 +70,50 @@ var secretsSetCmd = &cobra.Command{ PreRun: toggleDebug, Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - // secretType, err := cmd.Flags().GetString("type") - // if err != nil { - // log.Errorln("Unable to parse the secret type flag") - // log.Debugln(err) - // return - // } - - // if !util.IsSecretTypeValid(secretType) { - // log.Errorf("secret type can only be `personal` or `shared`. You have entered [%v]", secretType) - // return - // } - environmentName, err := cmd.Flags().GetString("env") if err != nil { - log.Errorln("Unable to parse the environment name flag") - log.Debugln(err) - return + util.HandleError(err, "Unable to parse flag") } if !util.IsSecretEnvironmentValid(environmentName) { - log.Errorln("You have entered a invalid environment name. Environment names can only be prod, dev, test or staging") - return - } - - workspaceFileExists := util.WorkspaceConfigFileExistsInCurrentPath() - if !workspaceFileExists { - log.Error("You have not yet connected to an Infisical Project. Please run [infisical init]") - return + util.PrintMessageAndExit("You have entered a invalid environment name", "Environment names can only be prod, dev, test or staging") } workspaceFile, err := util.GetWorkSpaceFromFile() if err != nil { - log.Error(err) - return + util.HandleError(err, "Unable to get your local config details") } loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails() if err != nil { - log.Error(err) - return - } - - if !loggedInUserDetails.IsUserLoggedIn { - log.Error("You are not logged in yet. Please run [infisical login] then try again") - return - } - - if loggedInUserDetails.IsUserLoggedIn && loggedInUserDetails.LoginExpired { - log.Error("Your login has expired. Please run [infisical login] then try again") - return + util.HandleError(err, "Unable to authenticate") } httpClient := resty.New(). SetAuthToken(loggedInUserDetails.UserCredentials.JTWToken). SetHeader("Accept", "application/json") - request := models.GetEncryptedWorkspaceKeyRequest{ + request := api.GetEncryptedWorkspaceKeyRequest{ WorkspaceId: workspaceFile.WorkspaceId, } - workspaceKeyResponse, err := http.CallGetEncryptedWorkspaceKey(httpClient, request) + workspaceKeyResponse, err := api.CallGetEncryptedWorkspaceKey(httpClient, request) if err != nil { - log.Errorf("unable to get your encrypted workspace key. [err=%v]", err) - return + util.HandleError(err, "unable to get your encrypted workspace key") } - encryptedWorkspaceKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.LatestKey.EncryptedKey) - encryptedWorkspaceKeySenderPublicKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.LatestKey.Sender.PublicKey) - encryptedWorkspaceKeyNonce, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.LatestKey.Nonce) + encryptedWorkspaceKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.EncryptedKey) + encryptedWorkspaceKeySenderPublicKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.Sender.PublicKey) + encryptedWorkspaceKeyNonce, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.Nonce) currentUsersPrivateKey, _ := base64.StdEncoding.DecodeString(loggedInUserDetails.UserCredentials.PrivateKey) // decrypt workspace key - plainTextEncryptionKey := util.DecryptAsymmetric(encryptedWorkspaceKey, encryptedWorkspaceKeyNonce, encryptedWorkspaceKeySenderPublicKey, currentUsersPrivateKey) + plainTextEncryptionKey := crypto.DecryptAsymmetric(encryptedWorkspaceKey, encryptedWorkspaceKeyNonce, encryptedWorkspaceKeySenderPublicKey, currentUsersPrivateKey) // pull current secrets - secrets, err := util.GetAllEnvironmentVariables("", environmentName) + secrets, err := util.GetAllEnvironmentVariables(environmentName) if err != nil { - log.Error("unable to retrieve secrets. Run with -d to see full logs") - log.Debug(err) + util.HandleError(err, "unable to retrieve secrets") } type SecretSetOperation struct { @@ -168,8 +122,8 @@ var secretsSetCmd = &cobra.Command{ SecretOperation string } - secretsToCreate := []models.Secret{} - secretsToModify := []models.Secret{} + secretsToCreate := []api.Secret{} + secretsToModify := []api.Secret{} secretOperations := []SecretSetOperation{} secretByKey := getSecretsByKeys(secrets) @@ -177,13 +131,11 @@ var secretsSetCmd = &cobra.Command{ for _, arg := range args { splitKeyValueFromArg := strings.SplitN(arg, "=", 2) if splitKeyValueFromArg[0] == "" || splitKeyValueFromArg[1] == "" { - log.Error("ensure that each secret has a none empty key and value. Modify the input and try again") - return + util.PrintMessageAndExit("ensure that each secret has a none empty key and value. Modify the input and try again") } if unicode.IsNumber(rune(splitKeyValueFromArg[0][0])) { - log.Error("keys of secrets cannot start with a number. Modify the key name(s) and try again") - return + util.PrintMessageAndExit("keys of secrets cannot start with a number. Modify the key name(s) and try again") } // Key and value from argument @@ -191,20 +143,20 @@ var secretsSetCmd = &cobra.Command{ value := splitKeyValueFromArg[1] hashedKey := fmt.Sprintf("%x", sha256.Sum256([]byte(key))) - encryptedKey, err := util.EncryptSymmetric([]byte(key), []byte(plainTextEncryptionKey)) + encryptedKey, err := crypto.EncryptSymmetric([]byte(key), []byte(plainTextEncryptionKey)) if err != nil { - log.Errorf("unable to encrypt your secrets [err=%v]", err) + util.HandleError(err, "unable to encrypt your secrets") } hashedValue := fmt.Sprintf("%x", sha256.Sum256([]byte(value))) - encryptedValue, err := util.EncryptSymmetric([]byte(value), []byte(plainTextEncryptionKey)) + encryptedValue, err := crypto.EncryptSymmetric([]byte(value), []byte(plainTextEncryptionKey)) if err != nil { - log.Errorf("unable to encrypt your secrets [err=%v]", err) + util.HandleError(err, "unable to encrypt your secrets") } if existingSecret, ok := secretByKey[key]; ok { // case: secret exists in project so it needs to be modified - encryptedSecretDetails := models.Secret{ + encryptedSecretDetails := api.Secret{ ID: existingSecret.ID, SecretValueCiphertext: base64.StdEncoding.EncodeToString(encryptedValue.CipherText), SecretValueIV: base64.StdEncoding.EncodeToString(encryptedValue.Nonce), @@ -231,7 +183,7 @@ var secretsSetCmd = &cobra.Command{ } else { // case: secret doesn't exist in project so it needs to be created - encryptedSecretDetails := models.Secret{ + encryptedSecretDetails := api.Secret{ SecretKeyCiphertext: base64.StdEncoding.EncodeToString(encryptedKey.CipherText), SecretKeyIV: base64.StdEncoding.EncodeToString(encryptedKey.Nonce), SecretKeyTag: base64.StdEncoding.EncodeToString(encryptedKey.AuthTag), @@ -252,29 +204,29 @@ var secretsSetCmd = &cobra.Command{ } if len(secretsToCreate) > 0 { - batchCreateRequest := models.BatchCreateSecretsByWorkspaceAndEnvRequest{ + batchCreateRequest := api.BatchCreateSecretsByWorkspaceAndEnvRequest{ WorkspaceId: workspaceFile.WorkspaceId, EnvironmentName: environmentName, Secrets: secretsToCreate, } - err = http.CallBatchCreateSecretsByWorkspaceAndEnv(httpClient, batchCreateRequest) + err = api.CallBatchCreateSecretsByWorkspaceAndEnv(httpClient, batchCreateRequest) if err != nil { - log.Errorf("Unable to process new secret creations because %v", err) + util.HandleError(err, "Unable to process new secret creations") return } } if len(secretsToModify) > 0 { - batchModifyRequest := models.BatchModifySecretsByWorkspaceAndEnvRequest{ + batchModifyRequest := api.BatchModifySecretsByWorkspaceAndEnvRequest{ WorkspaceId: workspaceFile.WorkspaceId, EnvironmentName: environmentName, Secrets: secretsToModify, } - err = http.CallBatchModifySecretsByWorkspaceAndEnv(httpClient, batchModifyRequest) + err = api.CallBatchModifySecretsByWorkspaceAndEnv(httpClient, batchModifyRequest) if err != nil { - log.Errorf("Unable to process the modifications to your secrets because %v", err) + util.HandleError(err, "Unable to process the modifications to your secrets") return } } @@ -307,36 +259,17 @@ var secretsDeleteCmd = &cobra.Command{ loggedInUserDetails, err := util.GetCurrentLoggedInUserDetails() if err != nil { - log.Error(err) - return - } - - if !loggedInUserDetails.IsUserLoggedIn { - log.Error("You are not logged in yet. Please run [infisical login] then try again") - return - } - - if loggedInUserDetails.IsUserLoggedIn && loggedInUserDetails.LoginExpired { - log.Error("Your login has expired. Please run [infisical login] then try again") - return - } - - workspaceFileExists := util.WorkspaceConfigFileExistsInCurrentPath() - if !workspaceFileExists { - log.Error("You have not yet connected to an Infisical Project. Please run [infisical init]") - return + util.HandleError(err, "Unable to authenticate") } workspaceFile, err := util.GetWorkSpaceFromFile() if err != nil { - log.Error(err) - return + util.HandleError(err, "Unable to get local project details") } - secrets, err := util.GetAllEnvironmentVariables("", environmentName) + secrets, err := util.GetAllEnvironmentVariables(environmentName) if err != nil { - log.Error("Unable to retrieve secrets. Run with -d to see full logs") - log.Debug(err) + util.HandleError(err, "Unable to fetch secrets") } secretByKey := getSecretsByKeys(secrets) @@ -352,11 +285,11 @@ var secretsDeleteCmd = &cobra.Command{ } if len(invalidSecretNamesThatDoNotExist) != 0 { - log.Errorf("secret name(s) [%v] does not exist in your project. To see which secrets exist run [infisical secrets]", strings.Join(invalidSecretNamesThatDoNotExist, ", ")) - return + message := fmt.Sprintf("secret name(s) [%v] does not exist in your project. To see which secrets exist run [infisical secrets]", strings.Join(invalidSecretNamesThatDoNotExist, ", ")) + util.PrintMessageAndExit(message) } - request := models.BatchDeleteSecretsBySecretIdsRequest{ + request := api.BatchDeleteSecretsBySecretIdsRequest{ WorkspaceId: workspaceFile.WorkspaceId, EnvironmentName: environmentName, SecretIds: validSecretIdsToDelete, @@ -366,45 +299,43 @@ var secretsDeleteCmd = &cobra.Command{ SetAuthToken(loggedInUserDetails.UserCredentials.JTWToken). SetHeader("Accept", "application/json") - err = http.CallBatchDeleteSecretsByWorkspaceAndEnv(httpClient, request) + err = api.CallBatchDeleteSecretsByWorkspaceAndEnv(httpClient, request) if err != nil { - log.Errorf("Unable to complete your request because %v", err) - return + util.HandleError(err, "Unable to complete your batch delete request") } - log.Infof("secret name(s) [%v] have been deleted from your project", strings.Join(args, ", ")) + fmt.Printf("secret name(s) [%v] have been deleted from your project \n", strings.Join(args, ", ")) }, } func init() { secretsCmd.AddCommand(secretsGetCmd) - // secretsSetCmd.Flags().String("type", "shared", "Used to set the type for secrets") secretsCmd.AddCommand(secretsSetCmd) secretsCmd.AddCommand(secretsDeleteCmd) secretsCmd.PersistentFlags().String("env", "dev", "Used to define the environment name on which actions should be taken on") secretsCmd.Flags().Bool("expand", true, "Parse shell parameter expansions in your secrets") + secretsCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) { + util.RequireLogin() + util.RequireLocalWorkspaceFile() + } rootCmd.AddCommand(secretsCmd) } func getSecretsByNames(cmd *cobra.Command, args []string) { environmentName, err := cmd.Flags().GetString("env") if err != nil { - log.Errorln("Unable to parse the environment name flag") - log.Debugln(err) - return + util.HandleError(err, "Unable to parse flag") } workspaceFileExists := util.WorkspaceConfigFileExistsInCurrentPath() if !workspaceFileExists { - log.Error("You have not yet connected to an Infisical Project. Please run [infisical init]") - return + util.HandleError(err, "Unable to parse flag") } - secrets, err := util.GetAllEnvironmentVariables("", environmentName) + secrets, err := util.GetAllEnvironmentVariables(environmentName) if err != nil { - log.Error("Unable to retrieve secrets. Run with -d to see full logs") - log.Debug(err) + util.HandleError(err, "To fetch all secrets") } requestedSecrets := []models.SingleEnvironmentVariable{} diff --git a/cli/packages/config/config.go b/cli/packages/config/config.go new file mode 100644 index 000000000..5ceb695e6 --- /dev/null +++ b/cli/packages/config/config.go @@ -0,0 +1,3 @@ +package config + +var INFISICAL_URL = "http://localhost:8080/api" diff --git a/cli/packages/util/crypto.go b/cli/packages/crypto/crypto.go similarity index 99% rename from cli/packages/util/crypto.go rename to cli/packages/crypto/crypto.go index 23e117f4b..f9589347a 100644 --- a/cli/packages/util/crypto.go +++ b/cli/packages/crypto/crypto.go @@ -1,4 +1,4 @@ -package util +package crypto import ( "crypto/aes" diff --git a/cli/packages/http/api.go b/cli/packages/http/api.go deleted file mode 100644 index 01b8a8a40..000000000 --- a/cli/packages/http/api.go +++ /dev/null @@ -1,102 +0,0 @@ -package http - -import ( - "fmt" - - "github.com/Infisical/infisical-merge/packages/models" - "github.com/Infisical/infisical-merge/packages/util" - "github.com/go-resty/resty/v2" -) - -func CallBatchModifySecretsByWorkspaceAndEnv(httpClient *resty.Client, request models.BatchModifySecretsByWorkspaceAndEnvRequest) error { - endpoint := fmt.Sprintf("%v/v2/secret/batch-modify/workspace/%v/environment/%v", util.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName) - response, err := httpClient. - R(). - SetBody(request). - Patch(endpoint) - - if err != nil { - return fmt.Errorf("CallBatchModifySecretsByWorkspaceAndEnv: Unable to complete api request [err=%s]", err) - } - - if response.StatusCode() > 299 { - return fmt.Errorf("CallBatchModifySecretsByWorkspaceAndEnv: Unsuccessful response: [response=%s]", response) - } - - return nil -} - -func CallBatchCreateSecretsByWorkspaceAndEnv(httpClient *resty.Client, request models.BatchCreateSecretsByWorkspaceAndEnvRequest) error { - endpoint := fmt.Sprintf("%v/v2/secret/batch-create/workspace/%v/environment/%v", util.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName) - response, err := httpClient. - R(). - SetBody(request). - Post(endpoint) - - if err != nil { - return fmt.Errorf("CallBatchCreateSecretsByWorkspaceAndEnv: Unable to complete api request [err=%s]", err) - } - - if response.StatusCode() > 299 { - return fmt.Errorf("CallBatchCreateSecretsByWorkspaceAndEnv: Unsuccessful response: [response=%s]", response) - } - - return nil -} - -func CallBatchDeleteSecretsByWorkspaceAndEnv(httpClient *resty.Client, request models.BatchDeleteSecretsBySecretIdsRequest) error { - endpoint := fmt.Sprintf("%v/v2/secret/batch/workspace/%v/environment/%v", util.INFISICAL_URL, request.WorkspaceId, request.EnvironmentName) - response, err := httpClient. - R(). - SetBody(request). - Delete(endpoint) - - if err != nil { - return fmt.Errorf("CallBatchDeleteSecretsByWorkspaceAndEnv: Unable to complete api request [err=%s]", err) - } - - if response.StatusCode() > 299 { - return fmt.Errorf("CallBatchDeleteSecretsByWorkspaceAndEnv: Unsuccessful response: [response=%s]", response) - } - - return nil -} - -func CallGetEncryptedWorkspaceKey(httpClient *resty.Client, request models.GetEncryptedWorkspaceKeyRequest) (models.GetEncryptedWorkspaceKeyResponse, error) { - endpoint := fmt.Sprintf("%v/v1/key/%v/latest", util.INFISICAL_URL, request.WorkspaceId) - var result models.GetEncryptedWorkspaceKeyResponse - response, err := httpClient. - R(). - SetResult(&result). - Get(endpoint) - - if err != nil { - return models.GetEncryptedWorkspaceKeyResponse{}, fmt.Errorf("CallGetEncryptedWorkspaceKey: Unable to complete api request [err=%s]", err) - } - - if response.StatusCode() > 299 { - return models.GetEncryptedWorkspaceKeyResponse{}, fmt.Errorf("CallGetEncryptedWorkspaceKey: Unsuccessful response: [response=%s]", response) - } - - return result, nil -} - -func CallGetEncryptedSecretsByWorkspaceIdAndEnv(httpClient resty.Client, request models.GetSecretsByWorkspaceIdAndEnvironmentRequest) (models.PullSecretsResponse, error) { - var pullSecretsRequestResponse models.PullSecretsResponse - response, err := httpClient. - R(). - SetQueryParam("environment", request.EnvironmentName). - SetQueryParam("channel", "cli"). - SetResult(&pullSecretsRequestResponse). - Get(fmt.Sprintf("%v/v1/secret/%v", util.INFISICAL_URL, request.WorkspaceId)) - - if err != nil { - return models.PullSecretsResponse{}, fmt.Errorf("CallGetEncryptedSecretsByWorkspaceIdAndEnv: Unable to complete api request [err=%s]", err) - } - - if response.StatusCode() > 299 { - return models.PullSecretsResponse{}, fmt.Errorf("CallGetEncryptedSecretsByWorkspaceIdAndEnv: Unsuccessful response: [response=%s]", response) - } - - return pullSecretsRequestResponse, nil -} diff --git a/cli/packages/models/cli.go b/cli/packages/models/cli.go index 70484de81..7bc31cab2 100644 --- a/cli/packages/models/cli.go +++ b/cli/packages/models/cli.go @@ -21,6 +21,14 @@ type SingleEnvironmentVariable struct { ID string `json:"_id"` } +type Workspace struct { + ID string `json:"_id"` + Name string `json:"name"` + Plan string `json:"plan,omitempty"` + V int `json:"__v"` + Organization string `json:"organization,omitempty"` +} + type WorkspaceConfigFile struct { WorkspaceId string `json:"workspaceId"` } diff --git a/cli/packages/util/common.go b/cli/packages/util/common.go index 44f14a12b..2d420ac6f 100644 --- a/cli/packages/util/common.go +++ b/cli/packages/util/common.go @@ -5,17 +5,6 @@ import ( "os" ) -const ( - CONFIG_FILE_NAME = "infisical-config.json" - CONFIG_FOLDER_NAME = ".infisical" - INFISICAL_WORKSPACE_CONFIG_FILE_NAME = ".infisical.json" - INFISICAL_TOKEN_NAME = "INFISICAL_TOKEN" - SECRET_TYPE_PERSONAL = "personal" - SECRET_TYPE_SHARED = "shared" -) - -var INFISICAL_URL = "https://app.infisical.com/api" - func GetHomeDir() (string, error) { directory, err := os.UserHomeDir() return directory, err @@ -25,7 +14,7 @@ func GetHomeDir() (string, error) { func WriteToFile(fileName string, dataToWrite []byte, filePerm os.FileMode) error { err := os.WriteFile(fileName, dataToWrite, filePerm) if err != nil { - return fmt.Errorf("Unable to wrote to file", err) + return fmt.Errorf("unable to wrote to file [err=%v]", err) } return nil diff --git a/cli/packages/util/constants.go b/cli/packages/util/constants.go new file mode 100644 index 000000000..fc7f5d581 --- /dev/null +++ b/cli/packages/util/constants.go @@ -0,0 +1,13 @@ +package util + +const ( + CONFIG_FILE_NAME = "infisical-config.json" + CONFIG_FOLDER_NAME = ".infisical" + INFISICAL_WORKSPACE_CONFIG_FILE_NAME = ".infisical.json" + INFISICAL_TOKEN_NAME = "INFISICAL_TOKEN" + SECRET_TYPE_PERSONAL = "personal" + SECRET_TYPE_SHARED = "shared" + KEYRING_SERVICE_NAME = "infisical" + PERSONAL_SECRET_TYPE_NAME = "personal" + SHARED_SECRET_TYPE_NAME = "shared" +) diff --git a/cli/packages/util/credentials.go b/cli/packages/util/credentials.go index bd0e67deb..6410002c0 100644 --- a/cli/packages/util/credentials.go +++ b/cli/packages/util/credentials.go @@ -5,20 +5,17 @@ import ( "fmt" "github.com/99designs/keyring" + "github.com/Infisical/infisical-merge/packages/config" "github.com/Infisical/infisical-merge/packages/models" "github.com/go-resty/resty/v2" - log "github.com/sirupsen/logrus" ) -const SERVICE_NAME = "infisical" - type LoggedInUserDetails struct { IsUserLoggedIn bool LoginExpired bool UserCredentials models.UserCredentials } -// To do: what happens if the user doesn't have a keyring in their system? func StoreUserCredsInKeyRing(userCred *models.UserCredentials) error { userCredMarshalled, err := json.Marshal(userCred) if err != nil { @@ -69,46 +66,6 @@ func GetUserCredsFromKeyRing(userEmail string) (credentials models.UserCredentia return userCredentials, err } -func IsUserLoggedIn() (hasUserLoggedIn bool, theUsersEmail string, err error) { - if ConfigFileExists() { - configFile, err := GetConfigFile() - if err != nil { - return false, "", fmt.Errorf("IsUserLoggedIn: unable to get logged in user from config file [err=%s]", err) - } - - if configFile.LoggedInUserEmail == "" { - return false, "", nil - } - - userCreds, err := GetUserCredsFromKeyRing(configFile.LoggedInUserEmail) - if err != nil { - return false, "", err - } - - // check to to see if the JWT is still valid - httpClient := resty.New(). - SetAuthToken(userCreds.JTWToken). - SetHeader("Accept", "application/json") - - response, err := httpClient. - R(). - Post(fmt.Sprintf("%v/v1/auth/checkAuth", INFISICAL_URL)) - - if err != nil { - return false, "", err - } - - if response.StatusCode() > 299 { - log.Infoln("Login expired, please login again.") - return false, "", fmt.Errorf("GetUserCredsFromKeyRing: Login expired, please login again.") - } - - return true, configFile.LoggedInUserEmail, nil - } else { - return false, "", nil - } -} - func GetCurrentLoggedInUserDetails() (LoggedInUserDetails, error) { if ConfigFileExists() { configFile, err := GetConfigFile() @@ -132,7 +89,7 @@ func GetCurrentLoggedInUserDetails() (LoggedInUserDetails, error) { response, err := httpClient. R(). - Post(fmt.Sprintf("%v/v1/auth/checkAuth", INFISICAL_URL)) + Post(fmt.Sprintf("%v/v1/auth/checkAuth", config.INFISICAL_URL)) if err != nil { return LoggedInUserDetails{}, err diff --git a/cli/packages/util/errors.go b/cli/packages/util/errors.go new file mode 100644 index 000000000..1761d6f7b --- /dev/null +++ b/cli/packages/util/errors.go @@ -0,0 +1,38 @@ +package util + +import ( + "fmt" + "os" + + "github.com/fatih/color" +) + +func HandleError(err error, messages ...string) { + PrintErrorAndExit(1, err, messages...) +} + +func PrintErrorAndExit(exitCode int, err error, messages ...string) { + printError(err) + + if len(messages) > 0 { + for _, message := range messages { + fmt.Println(message) + } + } + + os.Exit(exitCode) +} + +func PrintMessageAndExit(messages ...string) { + if len(messages) > 0 { + for _, message := range messages { + fmt.Println(message) + } + } + + os.Exit(1) +} + +func printError(e error) { + color.Red("Hmm, we ran into an error: %v", e) +} diff --git a/cli/packages/util/helper.go b/cli/packages/util/helper.go new file mode 100644 index 000000000..a6e7e35fc --- /dev/null +++ b/cli/packages/util/helper.go @@ -0,0 +1,100 @@ +package util + +import ( + "encoding/base64" + "fmt" + "os" +) + +type DecodedSymmetricEncryptionDetails = struct { + Cipher []byte + IV []byte + Tag []byte + Key []byte +} + +func GetBase64DecodedSymmetricEncryptionDetails(key string, cipher string, IV string, tag string) (DecodedSymmetricEncryptionDetails, error) { + cipherx, err := base64.StdEncoding.DecodeString(cipher) + if err != nil { + return DecodedSymmetricEncryptionDetails{}, fmt.Errorf("Base64DecodeSymmetricEncryptionDetails: Unable to decode cipher text [err=%v]", err) + } + + keyx, err := base64.StdEncoding.DecodeString(key) + if err != nil { + return DecodedSymmetricEncryptionDetails{}, fmt.Errorf("Base64DecodeSymmetricEncryptionDetails: Unable to decode key [err=%v]", err) + } + + IVx, err := base64.StdEncoding.DecodeString(IV) + if err != nil { + return DecodedSymmetricEncryptionDetails{}, fmt.Errorf("Base64DecodeSymmetricEncryptionDetails: Unable to decode IV [err=%v]", err) + } + + tagx, err := base64.StdEncoding.DecodeString(tag) + if err != nil { + return DecodedSymmetricEncryptionDetails{}, fmt.Errorf("Base64DecodeSymmetricEncryptionDetails: Unable to decode tag [err=%v]", err) + } + + return DecodedSymmetricEncryptionDetails{ + Key: keyx, + Cipher: cipherx, + IV: IVx, + Tag: tagx, + }, nil +} + +func IsSecretEnvironmentValid(env string) bool { + if env == "prod" || env == "dev" || env == "test" || env == "staging" { + return true + } + return false +} + +func IsSecretTypeValid(s string) bool { + if s == "personal" || s == "shared" { + return true + } + return false +} + +func RequireLogin() { + currentUserDetails, err := GetCurrentLoggedInUserDetails() + + if err != nil { + HandleError(err, "unable to retrieve your login details") + } + + if !currentUserDetails.IsUserLoggedIn { + PrintMessageAndExit("You must be logged in to run this command. To login, run [infisical login]") + } + + if currentUserDetails.LoginExpired { + PrintMessageAndExit("Your login expired, please login in again. To login, run [infisical login]") + } + + if currentUserDetails.UserCredentials.Email == "" && currentUserDetails.UserCredentials.JTWToken == "" && currentUserDetails.UserCredentials.PrivateKey == "" { + PrintMessageAndExit("One or more of your login details is empty. Please try logging in again via by running [infisical login]") + } +} + +func RequireServiceToken() { + serviceToken := os.Getenv(INFISICAL_TOKEN_NAME) + if serviceToken == "" { + PrintMessageAndExit("No service token is found in your terminal") + } +} + +func RequireLocalWorkspaceFile() { + workspaceFileExists := WorkspaceConfigFileExistsInCurrentPath() + if !workspaceFileExists { + PrintMessageAndExit("It looks you have not yet connected this project to Infisical", "To do so, run [infisical init] then run your command again") + } + + workspaceFile, err := GetWorkSpaceFromFile() + if err != nil { + HandleError(err, "Unable to read your project configuration, please try initializing this project again.", "Run [infisical init]") + } + + if workspaceFile.WorkspaceId == "" { + PrintMessageAndExit("Your project id is missing in your local config file. Please add it or run again [infisical init]") + } +} diff --git a/cli/packages/util/secrets.go b/cli/packages/util/secrets.go index 66d2b56e3..131a8e66d 100644 --- a/cli/packages/util/secrets.go +++ b/cli/packages/util/secrets.go @@ -2,284 +2,127 @@ package util import ( "encoding/base64" - "errors" "fmt" "os" "regexp" "strings" + "github.com/Infisical/infisical-merge/packages/api" + "github.com/Infisical/infisical-merge/packages/crypto" "github.com/Infisical/infisical-merge/packages/models" - "github.com/go-resty/resty/v2" log "github.com/sirupsen/logrus" + + "github.com/go-resty/resty/v2" ) -const PERSONAL_SECRET_TYPE_NAME = "personal" -const SHARED_SECRET_TYPE_NAME = "shared" - -func getSecretsByWorkspaceIdAndEnvName(httpClient resty.Client, envName string, workspace models.WorkspaceConfigFile, userCreds models.UserCredentials) (listOfSecrets []models.SingleEnvironmentVariable, err error) { - var pullSecretsRequestResponse models.PullSecretsResponse - response, err := httpClient. - R(). - SetQueryParam("environment", envName). - SetQueryParam("channel", "cli"). - SetResult(&pullSecretsRequestResponse). - Get(fmt.Sprintf("%v/v1/secret/%v", INFISICAL_URL, workspace.WorkspaceId)) // need to change workspace id - - if err != nil { - return nil, err +func GetPlainTextSecretsViaServiceToken(fullServiceToken string) ([]models.SingleEnvironmentVariable, error) { + serviceTokenParts := strings.SplitN(fullServiceToken, ".", 4) + if len(serviceTokenParts) < 4 { + return nil, fmt.Errorf("invalid service token entered. Please double check your service token and try again") } - if response.StatusCode() > 299 { - return nil, fmt.Errorf(response.Status()) - } + serviceToken := fmt.Sprintf("%v.%v.%v", serviceTokenParts[0], serviceTokenParts[1], serviceTokenParts[2]) - // Get workspace key - workspaceKey, err := base64.StdEncoding.DecodeString(pullSecretsRequestResponse.Key.EncryptedKey) - if err != nil { - return nil, err - } - - nonce, err := base64.StdEncoding.DecodeString(pullSecretsRequestResponse.Key.Nonce) - if err != nil { - return nil, err - } - - senderPublicKey, err := base64.StdEncoding.DecodeString(pullSecretsRequestResponse.Key.Sender.PublicKey) - if err != nil { - return nil, err - } - - currentUsersPrivateKey, err := base64.StdEncoding.DecodeString(userCreds.PrivateKey) - if err != nil { - return nil, err - } - - // log.Debugln("workspaceKey", workspaceKey, "nonce", nonce, "senderPublicKey", senderPublicKey, "currentUsersPrivateKey", currentUsersPrivateKey) - workspaceKeyInBytes := DecryptAsymmetric(workspaceKey, nonce, senderPublicKey, currentUsersPrivateKey) - var listOfEnv []models.SingleEnvironmentVariable - - for _, secret := range pullSecretsRequestResponse.Secrets { - key_iv, _ := base64.StdEncoding.DecodeString(secret.SecretKeyIV) - key_tag, _ := base64.StdEncoding.DecodeString(secret.SecretKeyTag) - key_ciphertext, _ := base64.StdEncoding.DecodeString(secret.SecretKeyCiphertext) - - plainTextKey, err := DecryptSymmetric(workspaceKeyInBytes, key_ciphertext, key_tag, key_iv) - if err != nil { - return nil, err - } - - value_iv, _ := base64.StdEncoding.DecodeString(secret.SecretValueIV) - value_tag, _ := base64.StdEncoding.DecodeString(secret.SecretValueTag) - value_ciphertext, _ := base64.StdEncoding.DecodeString(secret.SecretValueCiphertext) - - plainTextValue, err := DecryptSymmetric(workspaceKeyInBytes, value_ciphertext, value_tag, value_iv) - if err != nil { - return nil, err - } - - env := models.SingleEnvironmentVariable{ - Key: string(plainTextKey), - Value: string(plainTextValue), - Type: string(secret.Type), - ID: secret.ID, - } - - listOfEnv = append(listOfEnv, env) - } - - return listOfEnv, nil -} - -func GetSecretsFromAPIUsingCurrentLoggedInUser(envName string, userCreds models.UserCredentials) ([]models.SingleEnvironmentVariable, error) { - log.Debugln("GetSecretsFromAPIUsingCurrentLoggedInUser", "envName", envName, "userCreds", userCreds) - // check if user has configured a workspace - workspaces, err := GetAllWorkSpaceConfigsStartingFromCurrentPath() - if err != nil { - return nil, fmt.Errorf("Unable to read workspace file(s):", err) - } - - // create http client - httpClient := resty.New(). - SetAuthToken(userCreds.JTWToken). + httpClient := resty.New() + httpClient.SetAuthToken(serviceToken). SetHeader("Accept", "application/json") - secrets := []models.SingleEnvironmentVariable{} - for _, workspace := range workspaces { - secretsFromAPI, err := getSecretsByWorkspaceIdAndEnvName(*httpClient, envName, workspace, userCreds) - if err != nil { - return nil, fmt.Errorf("GetSecretsFromAPIUsingCurrentLoggedInUser: Unable to get secrets by workspace id and env name") - } - - secrets = append(secrets, secretsFromAPI...) + serviceTokenDetails, err := api.CallGetServiceTokenDetailsV2(httpClient) + if err != nil { + return nil, fmt.Errorf("unable to get service token details. [err=%v]", err) } - return secrets, nil + encryptedSecrets, err := api.CallGetSecretsV2(httpClient, api.GetEncryptedSecretsV2Request{ + WorkspaceId: serviceTokenDetails.Workspace, + EnvironmentName: serviceTokenDetails.Environment, + }) + + if err != nil { + return nil, err + } + + decodedSymmetricEncryptionDetails, err := GetBase64DecodedSymmetricEncryptionDetails(serviceTokenParts[3], serviceTokenDetails.EncryptedKey, serviceTokenDetails.Iv, serviceTokenDetails.Tag) + if err != nil { + return nil, fmt.Errorf("unable to decode symmetric encryption details [err=%v]", err) + } + + plainTextWorkspaceKey, err := crypto.DecryptSymmetric([]byte(serviceTokenParts[3]), decodedSymmetricEncryptionDetails.Cipher, decodedSymmetricEncryptionDetails.Tag, decodedSymmetricEncryptionDetails.IV) + if err != nil { + return nil, fmt.Errorf("unable to decrypt the required workspace key") + } + + plainTextSecrets, err := GetPlainTextSecrets(plainTextWorkspaceKey, encryptedSecrets) + if err != nil { + return nil, fmt.Errorf("unable to decrypt your secrets [err=%v]", err) + } + + return plainTextSecrets, nil } -func GetSecretsFromAPIUsingInfisicalToken(infisicalToken string, envName string, projectId string) ([]models.SingleEnvironmentVariable, error) { - if infisicalToken == "" || projectId == "" || envName == "" { - return nil, errors.New("infisical token, project id and or environment name cannot be empty") - } - splitToken := strings.Split(infisicalToken, ",") - JTWToken := splitToken[0] - temPrivateKey := splitToken[1] - - // create http client - httpClient := resty.New(). - SetAuthToken(JTWToken). +func GetPlainTextSecretsViaJTW(JTWToken string, receiversPrivateKey string, workspaceId string, environmentName string) ([]models.SingleEnvironmentVariable, error) { + httpClient := resty.New() + httpClient.SetAuthToken(JTWToken). SetHeader("Accept", "application/json") - var pullSecretsByInfisicalTokenResponse models.PullSecretsByInfisicalTokenResponse - response, err := httpClient. - R(). - SetQueryParam("environment", envName). - SetQueryParam("channel", "cli"). - SetResult(&pullSecretsByInfisicalTokenResponse). - Get(fmt.Sprintf("%v/v1/secret/%v/service-token", INFISICAL_URL, projectId)) + request := api.GetEncryptedWorkspaceKeyRequest{ + WorkspaceId: workspaceId, + } + + workspaceKeyResponse, err := api.CallGetEncryptedWorkspaceKey(httpClient, request) + if err != nil { + return nil, fmt.Errorf("unable to get your encrypted workspace key. [err=%v]", err) + } + + encryptedWorkspaceKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.EncryptedKey) + encryptedWorkspaceKeySenderPublicKey, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.Sender.PublicKey) + encryptedWorkspaceKeyNonce, _ := base64.StdEncoding.DecodeString(workspaceKeyResponse.Nonce) + currentUsersPrivateKey, _ := base64.StdEncoding.DecodeString(receiversPrivateKey) + plainTextWorkspaceKey := crypto.DecryptAsymmetric(encryptedWorkspaceKey, encryptedWorkspaceKeyNonce, encryptedWorkspaceKeySenderPublicKey, currentUsersPrivateKey) + + encryptedSecrets, err := api.CallGetSecretsV2(httpClient, api.GetEncryptedSecretsV2Request{ + WorkspaceId: workspaceId, + EnvironmentName: environmentName, + }) if err != nil { return nil, err } - if response.StatusCode() > 299 { - return nil, fmt.Errorf(response.Status()) - } - - // Get workspace key - workspaceKey, err := base64.StdEncoding.DecodeString(pullSecretsByInfisicalTokenResponse.Key.EncryptedKey) + plainTextSecrets, err := GetPlainTextSecrets(plainTextWorkspaceKey, encryptedSecrets) if err != nil { - return nil, err + return nil, fmt.Errorf("unable to decrypt your secrets [err=%v]", err) } - nonce, err := base64.StdEncoding.DecodeString(pullSecretsByInfisicalTokenResponse.Key.Nonce) - if err != nil { - return nil, err - } - - senderPublicKey, err := base64.StdEncoding.DecodeString(pullSecretsByInfisicalTokenResponse.Key.Sender.PublicKey) - if err != nil { - return nil, err - } - - currentUsersPrivateKey, err := base64.StdEncoding.DecodeString(temPrivateKey) - if err != nil { - return nil, err - } - - // workspaceKeyInBytes, _ := box.Open(nil, workspaceKey, (*[24]byte)(nonce), (*[32]byte)(senderPublicKey), (*[32]byte)(currentUsersPrivateKey)) - workspaceKeyInBytes := DecryptAsymmetric(workspaceKey, nonce, senderPublicKey, currentUsersPrivateKey) - var listOfEnv []models.SingleEnvironmentVariable - - for _, secret := range pullSecretsByInfisicalTokenResponse.Secrets { - key_iv, _ := base64.StdEncoding.DecodeString(secret.SecretKey.Iv) - key_tag, _ := base64.StdEncoding.DecodeString(secret.SecretKey.Tag) - key_ciphertext, _ := base64.StdEncoding.DecodeString(secret.SecretKey.Ciphertext) - - plainTextKey, err := DecryptSymmetric(workspaceKeyInBytes, key_ciphertext, key_tag, key_iv) - if err != nil { - return nil, err - } - - value_iv, _ := base64.StdEncoding.DecodeString(secret.SecretValue.Iv) - value_tag, _ := base64.StdEncoding.DecodeString(secret.SecretValue.Tag) - value_ciphertext, _ := base64.StdEncoding.DecodeString(secret.SecretValue.Ciphertext) - - plainTextValue, err := DecryptSymmetric(workspaceKeyInBytes, value_ciphertext, value_tag, value_iv) - if err != nil { - return nil, err - } - - env := models.SingleEnvironmentVariable{ - Key: string(plainTextKey), - Value: string(plainTextValue), - Type: string(secret.Type), - ID: secret.ID, - } - - listOfEnv = append(listOfEnv, env) - } - - return listOfEnv, nil + return plainTextSecrets, nil } -func GetAllEnvironmentVariables(projectId string, envName string) ([]models.SingleEnvironmentVariable, error) { +func GetAllEnvironmentVariables(envName string) ([]models.SingleEnvironmentVariable, error) { infisicalToken := os.Getenv(INFISICAL_TOKEN_NAME) if infisicalToken == "" { - hasUserLoggedInbefore, loggedInUserEmail, err := IsUserLoggedIn() + RequireLocalWorkspaceFile() + RequireLogin() + log.Debug("Trying to fetch secrets using logged in details") + + loggedInUserDetails, err := GetCurrentLoggedInUserDetails() if err != nil { - log.Info("Unexpected issue occurred while checking login status. To see more details, add flag --debug") - log.Debugln(err) return nil, err } - if !hasUserLoggedInbefore { - log.Infoln("No logged in user. To login, please run command [infisical login]") - return nil, fmt.Errorf("user not logged in") - } - - userCreds, err := GetUserCredsFromKeyRing(loggedInUserEmail) + workspaceFile, err := GetWorkSpaceFromFile() if err != nil { - log.Infoln("Unable to get user creds from key ring") - log.Debug(err) return nil, err } - // TODO: Should be based on flag. I.e only get all workspaces if desired, otherwise only get the one in the current root of project - workspaceConfigs, err := GetAllWorkSpaceConfigsStartingFromCurrentPath() - if err != nil { - return nil, fmt.Errorf("unable to check if you have a %s file in your current directory", INFISICAL_WORKSPACE_CONFIG_FILE_NAME) - } - - if len(workspaceConfigs) == 0 { - log.Infoln("Your local project is not connected to a Infisical project yet. Run command [infisical init]") - return nil, fmt.Errorf("project not initialized") - } - - envsFromApi, err := GetSecretsFromAPIUsingCurrentLoggedInUser(envName, userCreds) - if err != nil { - log.Errorln("Something went wrong when pulling secrets using your logged in credentials. If the issue persists, double check your project id/try logging in again.") - log.Debugln(err) - return nil, err - } - - return envsFromApi, nil + secrets, err := GetPlainTextSecretsViaJTW(loggedInUserDetails.UserCredentials.JTWToken, loggedInUserDetails.UserCredentials.PrivateKey, workspaceFile.WorkspaceId, envName) + return secrets, err } else { - envsFromApi, err := GetSecretsFromAPIUsingInfisicalToken(infisicalToken, envName, projectId) - if err != nil { - log.Errorln("Something went wrong when pulling secrets using your Infisical token. Double check the token, project id or environment name (dev, prod, ect.)") - log.Debugln(err) - return nil, err - } - - return envsFromApi, nil + log.Debug("Trying to fetch secrets using service token") + return GetPlainTextSecretsViaServiceToken(infisicalToken) } } -func GetWorkSpacesFromAPI(userCreds models.UserCredentials) (workspaces []models.Workspace, err error) { - // create http client - httpClient := resty.New(). - SetAuthToken(userCreds.JTWToken). - SetHeader("Accept", "application/json") - - var getWorkSpacesResponse models.GetWorkSpacesResponse - response, err := httpClient. - R(). - SetResult(&getWorkSpacesResponse). - Get(fmt.Sprintf("%v/v1/workspace", INFISICAL_URL)) - - if err != nil { - return nil, err - } - - if response.StatusCode() > 299 { - return nil, fmt.Errorf("ops, unsuccessful response code. [response=%v]", response) - } - - return getWorkSpacesResponse.Workspaces, nil -} - func getExpandedEnvVariable(secrets []models.SingleEnvironmentVariable, variableWeAreLookingFor string, hashMapOfCompleteVariables map[string]string, hashMapOfSelfRefs map[string]string) string { if value, found := hashMapOfCompleteVariables[variableWeAreLookingFor]; found { return value @@ -351,6 +194,8 @@ func SubstituteSecrets(secrets []models.SingleEnvironmentVariable) []models.Sing return expandedSecrets } +// + // if two secrets with the same name are found, the one that has type `personal` will be in the returned list func OverrideWithPersonalSecrets(secrets []models.SingleEnvironmentVariable) []models.SingleEnvironmentVariable { personalSecret := make(map[string]models.SingleEnvironmentVariable) @@ -359,46 +204,80 @@ func OverrideWithPersonalSecrets(secrets []models.SingleEnvironmentVariable) []m for _, secret := range secrets { if secret.Type == PERSONAL_SECRET_TYPE_NAME { - personalSecret[secret.Key] = models.SingleEnvironmentVariable{ - Key: secret.Key, - Value: secret.Value, - Type: secret.Type, - } + personalSecret[secret.Key] = secret } if secret.Type == SHARED_SECRET_TYPE_NAME { - sharedSecret[secret.Key] = models.SingleEnvironmentVariable{ - Key: secret.Key, - Value: secret.Value, - Type: secret.Type, - } + sharedSecret[secret.Key] = secret } } - for _, secret := range secrets { + for _, secret := range sharedSecret { personalValue, personalExists := personalSecret[secret.Key] - sharedValue, sharedExists := sharedSecret[secret.Key] - - if personalExists && sharedExists || personalExists && !sharedExists { + if personalExists { secretsToReturn = append(secretsToReturn, personalValue) } else { - secretsToReturn = append(secretsToReturn, sharedValue) + secretsToReturn = append(secretsToReturn, secret) } } return secretsToReturn } -func IsSecretEnvironmentValid(env string) bool { - if env == "prod" || env == "dev" || env == "test" || env == "staging" { - return true - } - return false -} +func GetPlainTextSecrets(key []byte, encryptedSecrets api.GetEncryptedSecretsV2Response) ([]models.SingleEnvironmentVariable, error) { + plainTextSecrets := []models.SingleEnvironmentVariable{} + for _, secret := range encryptedSecrets { + // Decrypt key + key_iv, err := base64.StdEncoding.DecodeString(secret.SecretKeyIV) + if err != nil { + return nil, fmt.Errorf("unable to decode secret IV for secret key") + } -func IsSecretTypeValid(s string) bool { - if s == "personal" || s == "shared" { - return true + key_tag, err := base64.StdEncoding.DecodeString(secret.SecretKeyTag) + if err != nil { + return nil, fmt.Errorf("unable to decode secret authentication tag for secret key") + } + + key_ciphertext, err := base64.StdEncoding.DecodeString(secret.SecretKeyCiphertext) + if err != nil { + return nil, fmt.Errorf("unable to decode secret cipher text for secret key") + } + + plainTextKey, err := crypto.DecryptSymmetric(key, key_ciphertext, key_tag, key_iv) + if err != nil { + return nil, fmt.Errorf("unable to symmetrically decrypt secret key") + } + + // Decrypt value + value_iv, err := base64.StdEncoding.DecodeString(secret.SecretValueIV) + if err != nil { + return nil, fmt.Errorf("unable to decode secret IV for secret value") + } + + value_tag, err := base64.StdEncoding.DecodeString(secret.SecretValueTag) + if err != nil { + return nil, fmt.Errorf("unable to decode secret authentication tag for secret value") + } + + value_ciphertext, _ := base64.StdEncoding.DecodeString(secret.SecretValueCiphertext) + if err != nil { + return nil, fmt.Errorf("unable to decode secret cipher text for secret key") + } + + plainTextValue, err := crypto.DecryptSymmetric(key, value_ciphertext, value_tag, value_iv) + if err != nil { + return nil, fmt.Errorf("unable to symmetrically decrypt secret value") + } + + plainTextSecret := models.SingleEnvironmentVariable{ + Key: string(plainTextKey), + Value: string(plainTextValue), + Type: string(secret.Type), + ID: secret.ID, + } + + plainTextSecrets = append(plainTextSecrets, plainTextSecret) } - return false + + return plainTextSecrets, nil } diff --git a/cli/packages/util/vault.go b/cli/packages/util/vault.go index 03d03b360..63a014af1 100644 --- a/cli/packages/util/vault.go +++ b/cli/packages/util/vault.go @@ -29,13 +29,13 @@ func GetKeyRing() (keyring.Keyring, error) { keyringInstanceConfig := keyring.Config{ FilePasswordFunc: fileKeyringPassphrasePrompt, - ServiceName: SERVICE_NAME, - LibSecretCollectionName: SERVICE_NAME, - KWalletAppID: SERVICE_NAME, - KWalletFolder: SERVICE_NAME, + ServiceName: KEYRING_SERVICE_NAME, + LibSecretCollectionName: KEYRING_SERVICE_NAME, + KWalletAppID: KEYRING_SERVICE_NAME, + KWalletFolder: KEYRING_SERVICE_NAME, KeychainTrustApplication: true, - WinCredPrefix: SERVICE_NAME, - FileDir: fmt.Sprintf("~/%s-file-vault", SERVICE_NAME), + WinCredPrefix: KEYRING_SERVICE_NAME, + FileDir: fmt.Sprintf("~/%s-file-vault", KEYRING_SERVICE_NAME), KeychainAccessibleWhenUnlocked: true, } diff --git a/docs/getting-started/dashboard/audit-logs.mdx b/docs/getting-started/dashboard/audit-logs.mdx new file mode 100644 index 000000000..bb31423b4 --- /dev/null +++ b/docs/getting-started/dashboard/audit-logs.mdx @@ -0,0 +1,9 @@ +--- +title: "Activity Logs" +--- + +Activity logs record all actions going through Infisical including CRUD operations applied to environment variables. They help answer questions like: + +- Who added or updated environment variables recently? +- Did Bob read environment variables last week (if at all)? +- What IP address was used for that action? diff --git a/docs/getting-started/dashboard/integrations.mdx b/docs/getting-started/dashboard/integrations.mdx index de25fa861..ce2904e38 100644 --- a/docs/getting-started/dashboard/integrations.mdx +++ b/docs/getting-started/dashboard/integrations.mdx @@ -4,11 +4,10 @@ title: "Integrations" Integrations allow environment variables to be synced across your entire infrastructure from local development to CI/CD and production. -We're still early with integrations, but expect more soon. +We're still early with integrations, but expect more soon. - - View all available integrations and their guide + + View all available integrations and their guides ![integrations](../../images/project-integrations.png) - diff --git a/docs/getting-started/dashboard/pit-recovery.mdx b/docs/getting-started/dashboard/pit-recovery.mdx new file mode 100644 index 000000000..534cc2718 --- /dev/null +++ b/docs/getting-started/dashboard/pit-recovery.mdx @@ -0,0 +1,5 @@ +--- +title: "Point-in-Time Recovery" +--- + +Point-in-time (PIT) recovery allows environment variables to be rolled back to any point in time. It's powered by snapshots that get captured after mutations to environment variables. diff --git a/docs/getting-started/dashboard/versioning.mdx b/docs/getting-started/dashboard/versioning.mdx new file mode 100644 index 000000000..3a6ba2e2c --- /dev/null +++ b/docs/getting-started/dashboard/versioning.mdx @@ -0,0 +1,5 @@ +--- +title: "Secret Versioning" +--- + +Secret versioning allows an individual environment variable to be rolled back without touching other project environment variables. diff --git a/docs/getting-started/features.mdx b/docs/getting-started/features.mdx index c520dd905..0205f0a46 100644 --- a/docs/getting-started/features.mdx +++ b/docs/getting-started/features.mdx @@ -4,14 +4,14 @@ title: "Features" This is a non-exhaustive list of features that Infisical offers: -## Web UI +## Platform -The Web UI is used to manage teams and environment variables. - -- Provision access to organizations and projects. -- Add/delete/update, scope, search, sort, hide-unhide environment variables. -- Separate environment variables by environment. -- Import environment variables via drag-and-drop, export them as a .env file. +- Provision members access to organizations and projects. +- Manage secrets by adding, deleting, updating them across environments; search, sort, hide/un-hide, export/import them. +- Sync secrets to platforms via integrations to platforms like GitHub, Vercel, and Netlify. +- Rollback secrets to any point in time. +- Rollback each secrets to any version. +- Track actions through activity logs. ## CLI diff --git a/docs/mint.json b/docs/mint.json index 2fe6355c6..d4146ff9b 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -85,6 +85,9 @@ "getting-started/dashboard/organization", "getting-started/dashboard/project", "getting-started/dashboard/integrations", + "getting-started/dashboard/pit-recovery", + "getting-started/dashboard/versioning", + "getting-started/dashboard/audit-logs", "getting-started/dashboard/token" ] }, diff --git a/frontend/components/analytics/posthog.js b/frontend/components/analytics/posthog.js deleted file mode 100644 index 8b8e88a22..000000000 --- a/frontend/components/analytics/posthog.js +++ /dev/null @@ -1,16 +0,0 @@ -import posthog from 'posthog-js'; - -import { ENV, POSTHOG_API_KEY, POSTHOG_HOST } from '../utilities/config'; - -export const initPostHog = () => { - if (typeof window !== 'undefined') { - // eslint-disable-next-line - if (ENV == 'production' && TELEMETRY_CAPTURING_ENABLED) { - posthog.init(POSTHOG_API_KEY, { - api_host: POSTHOG_HOST - }); - } - } - - return posthog; -}; diff --git a/frontend/components/analytics/posthog.ts b/frontend/components/analytics/posthog.ts index e0d6e7c09..4735a9fa9 100644 --- a/frontend/components/analytics/posthog.ts +++ b/frontend/components/analytics/posthog.ts @@ -5,14 +5,21 @@ import posthog from 'posthog-js'; import { ENV, POSTHOG_API_KEY, POSTHOG_HOST } from '../utilities/config'; export const initPostHog = () => { - if (typeof window !== 'undefined') { - // @ts-ignore - if (ENV == 'production' && TELEMETRY_CAPTURING_ENABLED) { - posthog.init(POSTHOG_API_KEY, { - api_host: POSTHOG_HOST - }); - } - } + try { + if (typeof window !== 'undefined') { + // @ts-ignore + if (ENV == 'production' && TELEMETRY_CAPTURING_ENABLED) { + console.log("Outside of posthog", "POSTHOG_API_KEY", POSTHOG_API_KEY, "POSTHOG_HOST", POSTHOG_HOST) + posthog.init(POSTHOG_API_KEY, { + api_host: POSTHOG_HOST + }); + } - return posthog; + console.log("Outside of posthog") + } + + return posthog; + } catch (e) { + console.log("posthog err", e) + } }; diff --git a/frontend/components/basic/EventFilter.tsx b/frontend/components/basic/EventFilter.tsx new file mode 100644 index 000000000..c9b31fd43 --- /dev/null +++ b/frontend/components/basic/EventFilter.tsx @@ -0,0 +1,106 @@ +import React from 'react'; +import { Fragment } from 'react'; +import { useTranslation } from "next-i18next"; +import { + faAngleDown, + faEye, + faPlus, + faShuffle, + faTrash, + faX +} from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Listbox, Transition } from '@headlessui/react'; + +interface ListBoxProps { + selected: string; + select: (event: string) => void; +} + +const eventOptions = [ + { + name: 'addSecrets', + icon: faPlus + }, + { + name: 'readSecrets', + icon: faEye + }, + { + name: 'updateSecrets', + icon: faShuffle + }, + { + name: 'deleteSecrets', + icon: faTrash + } +]; + +/** + * This is the component that we use for the event picker in the activity logs tab. + * @param {object} obj + * @param {string} obj.selected - the event that is currently selected + * @param {function} obj.select - an action that happens when an item is selected + */ +export default function EventFilter({ + selected, + select +}: ListBoxProps): JSX.Element { + const { t } = useTranslation(); + + return ( + +
+ + {selected != '' ? ( +

{t("activity:event." + selected)}

+ ) : ( +

Select an event

+ )} + {selected != '' ? ( + select('')} + /> + ) : ( + + )} +
+ + + {eventOptions.map((event, id) => { + return ( + + {({ selected }) => ( + <> + + {' '} + {t("activity:event." + event.name)} + + + )} + + ); + })} + + +
+
+ ); +} diff --git a/frontend/components/basic/Layout.tsx b/frontend/components/basic/Layout.tsx index 5a8d4098c..8ac9ec92b 100644 --- a/frontend/components/basic/Layout.tsx +++ b/frontend/components/basic/Layout.tsx @@ -6,10 +6,12 @@ import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; import { faBookOpen, + faFileLines, faGear, faKey, faMobile, faPlug, + faTimeline, faUser, } from "@fortawesome/free-solid-svg-icons"; import { faPlus } from "@fortawesome/free-solid-svg-icons"; @@ -119,7 +121,7 @@ export default function Layout({ children }: LayoutProps) { } }); } - router.push("/dashboard/" + newWorkspaceId + "?Development"); + router.push("/dashboard/" + newWorkspaceId); setIsOpen(false); setNewWorkspaceName(""); } else { @@ -139,8 +141,7 @@ export default function Layout({ children }: LayoutProps) { { href: "/dashboard/" + - workspaceMapping[workspaceSelected as any] + - "?Development", + workspaceMapping[workspaceSelected as any], title: t("nav:menu.secrets"), emoji: , }, @@ -154,6 +155,11 @@ export default function Layout({ children }: LayoutProps) { title: t("nav:menu.integrations"), emoji: , }, + { + href: '/activity/' + workspaceMapping[workspaceSelected as any], + title: 'Activity Logs', + emoji: + }, { href: "/settings/project/" + workspaceMapping[workspaceSelected as any], title: t("nav:menu.project-settings"), @@ -192,7 +198,7 @@ export default function Layout({ children }: LayoutProps) { .map((workspace: { _id: string }) => workspace._id) .includes(intendedWorkspaceId) ) { - router.push("/dashboard/" + userWorkspaces[0]._id + "?Development"); + router.push("/dashboard/" + userWorkspaces[0]._id); } else { setWorkspaceList( userWorkspaces.map((workspace: any) => workspace.name) @@ -235,8 +241,7 @@ export default function Layout({ children }: LayoutProps) { ) { router.push( "/dashboard/" + - workspaceMapping[workspaceSelected as any] + - "?Development" + workspaceMapping[workspaceSelected as any] ); localStorage.setItem( "projectData.id", diff --git a/frontend/components/basic/Listbox.tsx b/frontend/components/basic/Listbox.tsx index e726b7f56..95e3f33c6 100644 --- a/frontend/components/basic/Listbox.tsx +++ b/frontend/components/basic/Listbox.tsx @@ -1,12 +1,12 @@ -import React from "react"; -import { Fragment } from "react"; +import React from 'react'; +import { Fragment } from 'react'; import { faAngleDown, faCheck, - faPlus, -} from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Listbox, Transition } from "@headlessui/react"; + faPlus +} from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Listbox, Transition } from '@headlessui/react'; interface ListBoxProps { selected: string; @@ -34,20 +34,20 @@ export default function ListBox({ data, text, buttonAction, - isFull, + isFull }: ListBoxProps): JSX.Element { return (
{text} - {" "} + {' '} {selected}
@@ -70,11 +70,11 @@ export default function ListBox({ key={personIdx} className={({ active, selected }) => `my-0.5 relative cursor-default select-none py-2 pl-10 pr-4 rounded-md ${ - selected ? "bg-white/10 text-gray-400 font-bold" : "" + selected ? 'bg-white/10 text-gray-400 font-bold' : '' } ${ active && !selected - ? "bg-white/5 text-mineshaft-200 cursor-pointer" - : "text-gray-400" + ? 'bg-white/5 text-mineshaft-200 cursor-pointer' + : 'text-gray-400' } ` } value={person} @@ -83,7 +83,7 @@ export default function ListBox({ <> {person} diff --git a/frontend/components/basic/buttons/Button.tsx b/frontend/components/basic/buttons/Button.tsx index 9197ccf13..939d9b17d 100644 --- a/frontend/components/basic/buttons/Button.tsx +++ b/frontend/components/basic/buttons/Button.tsx @@ -115,7 +115,7 @@ export default function Button(props: ButtonProps): JSX.Element { )} diff --git a/frontend/components/basic/dialog/AddServiceTokenDialog.js b/frontend/components/basic/dialog/AddServiceTokenDialog.js index b02a804b7..f9ef6d27c 100644 --- a/frontend/components/basic/dialog/AddServiceTokenDialog.js +++ b/frontend/components/basic/dialog/AddServiceTokenDialog.js @@ -12,6 +12,7 @@ import { envMapping } from "../../../public/data/frequentConstants"; import { decryptAssymmetric, encryptAssymmetric, + encryptSymmetric, } from "../../utilities/cryptography/crypto"; import Button from "../buttons/Button"; import InputField from "../InputField"; @@ -25,11 +26,15 @@ const expiryMapping = { "12 months": 31104000, }; +const crypto = require('crypto'); + const AddServiceTokenDialog = ({ isOpen, closeModal, workspaceId, workspaceName, + serviceTokens, + setServiceTokens }) => { const [serviceToken, setServiceToken] = useState(""); const [serviceTokenName, setServiceTokenName] = useState(""); @@ -48,16 +53,14 @@ const AddServiceTokenDialog = ({ privateKey: localStorage.getItem("PRIVATE_KEY"), }); - // generate new public/private key pair - const pair = nacl.box.keyPair(); - const publicKey = nacl.util.encodeBase64(pair.publicKey); - const privateKey = nacl.util.encodeBase64(pair.secretKey); - - // encrypt workspace key under newly-generated public key - const { ciphertext: encryptedKey, nonce } = encryptAssymmetric({ + const randomBytes = crypto.randomBytes(16).toString('hex'); + const { + ciphertext, + iv, + tag, + } = encryptSymmetric({ plaintext: key, - publicKey, - privateKey, + key: randomBytes, }); let newServiceToken = await addServiceToken({ @@ -65,13 +68,15 @@ const AddServiceTokenDialog = ({ workspaceId, environment: envMapping[serviceTokenEnv], expiresIn: expiryMapping[serviceTokenExpiresIn], - publicKey, - encryptedKey, - nonce, + encryptedKey: ciphertext, + iv, + tag }); + + console.log('newServiceToken', newServiceToken); - const serviceToken = newServiceToken + "," + privateKey; - setServiceToken(serviceToken); + setServiceTokens(serviceTokens.concat([newServiceToken.serviceTokenData])); + setServiceToken(newServiceToken.serviceToken + "." + randomBytes); }; function copyToClipboard() { @@ -161,7 +166,7 @@ const AddServiceTokenDialog = ({ "Production", "Testing", ]} - width="full" + isFull={true} text={`${t("common:environment")}: `} />
@@ -176,7 +181,7 @@ const AddServiceTokenDialog = ({ "6 months", "12 months", ]} - width="full" + isFull={true} text={`${t("common:expired-in")}: `} /> @@ -211,7 +216,7 @@ const AddServiceTokenDialog = ({
-
+
- {t("common.click-to-copy")} + {t("common:click-to-copy")}
diff --git a/frontend/components/basic/table/ServiceTokenTable.js b/frontend/components/basic/table/ServiceTokenTable.tsx similarity index 54% rename from frontend/components/basic/table/ServiceTokenTable.js rename to frontend/components/basic/table/ServiceTokenTable.tsx index 6e5cc65ea..412a0dbfb 100644 --- a/frontend/components/basic/table/ServiceTokenTable.js +++ b/frontend/components/basic/table/ServiceTokenTable.tsx @@ -1,36 +1,53 @@ -import { useEffect, useState } from 'react'; -import { useRouter } from 'next/router'; import { faX } from '@fortawesome/free-solid-svg-icons'; +import { useNotificationContext } from '~/components/context/Notifications/NotificationProvider'; + +import deleteServiceToken from "../../../pages/api/serviceToken/deleteServiceToken"; import { reverseEnvMapping } from '../../../public/data/frequentConstants'; import guidGenerator from '../../utilities/randomId'; import Button from '../buttons/Button'; +interface TokenProps { + _id: string; + name: string; + environment: string; + expiresAt: string; +} + +interface ServiceTokensProps { + data: TokenProps[]; + workspaceName: string; + setServiceTokens: (value: TokenProps[]) => void; +} + /** - * This is the component that we utilize for the user table - in future, can reuse it for some other purposes too. + * This is the component that we utilize for the service token table * #TODO: add the possibility of choosing and doing operations on multiple users. - * @param {*} props + * @param {object} obj + * @param {any[]} obj.data - current state of the service token table + * @param {string} obj.workspaceName - name of the current project + * @param {function} obj.setServiceTokens - updating the state of the service token table * @returns */ -const ServiceTokenTable = ({ data, workspaceName }) => { - const router = useRouter(); +const ServiceTokenTable = ({ data, workspaceName, setServiceTokens }: ServiceTokensProps) => { + const { createNotification } = useNotificationContext(); return (
- + - - - - + + + + {data?.length > 0 ? ( - data.map((row, index) => { + data?.map((row) => { return ( { - diff --git a/frontend/components/context/Notifications/Notification.tsx b/frontend/components/context/Notifications/Notification.tsx index ad556a6f5..6635c795e 100644 --- a/frontend/components/context/Notifications/Notification.tsx +++ b/frontend/components/context/Notifications/Notification.tsx @@ -36,7 +36,7 @@ const Notification = ({ return (
{notification.type === 'error' && ( @@ -56,7 +56,7 @@ const Notification = ({ onClick={() => clearNotification(notification.text)} > diff --git a/frontend/components/context/Notifications/NotificationProvider.tsx b/frontend/components/context/Notifications/NotificationProvider.tsx index 05f9eee19..aa694a1d0 100644 --- a/frontend/components/context/Notifications/NotificationProvider.tsx +++ b/frontend/components/context/Notifications/NotificationProvider.tsx @@ -38,7 +38,7 @@ const NotificationProvider = ({ children }: NotificationProviderProps) => { const createNotification = ({ text, type = 'success', - timeoutMs = 5000 + timeoutMs = 4000 }: Notification) => { const doesNotifExist = notifications.some((notif) => notif.text === text); diff --git a/frontend/components/dashboard/DashboardInputField.tsx b/frontend/components/dashboard/DashboardInputField.tsx index 29761bf07..a667c39d0 100644 --- a/frontend/components/dashboard/DashboardInputField.tsx +++ b/frontend/components/dashboard/DashboardInputField.tsx @@ -53,7 +53,7 @@ const DashboardInputField = ({ return (
@@ -85,7 +85,7 @@ const DashboardInputField = ({ return (
{override == true &&
Override enabled
} - {value.split(REGEX).map((word, id) => { + {value?.split(REGEX).map((word, id) => { if (word.match(REGEX) !== null) { return ( @@ -139,7 +139,7 @@ const DashboardInputField = ({ })}
{blurred && ( -
+
{value.split('').map(() => ( void; modifyKey: (value: string, position: number) => void; modifyValue: (value: string, position: number) => void; isBlurred: boolean; isDuplicate: boolean; toggleSidebar: (id: string) => void; sidebarSecretId: string; + isSnapshot: boolean; } /** * This component represent a single row for an environemnt variable on the dashboard * @param {object} obj * @param {String[]} obj.keyPair - data related to the environment variable (id, pos, key, value, public/private) - * @param {function} obj.deleteRow - a function to delete a certain keyPair * @param {function} obj.modifyKey - modify the key of a certain environment variable * @param {function} obj.modifyValue - modify the value of a certain environment variable * @param {boolean} obj.isBlurred - if the blurring setting is turned on * @param {boolean} obj.isDuplicate - list of all the duplicates secret names on the dashboard * @param {function} obj.toggleSidebar - open/close/switch sidebar * @param {string} obj.sidebarSecretId - the id of a secret for the side bar is displayed + * @param {boolean} obj.isSnapshot - whether this keyPair is in a snapshot. If so, it won't have some features like sidebar * @returns */ const KeyPair = ({ keyPair, - deleteRow, modifyKey, modifyValue, isBlurred, isDuplicate, toggleSidebar, - sidebarSecretId + sidebarSecretId, + isSnapshot }: KeyPairProps) => { return ( -
+
{keyPair.type == "personal" &&
@@ -57,7 +57,7 @@ const KeyPair = ({
}
-
+
-
-
+
+
-
toggleSidebar(keyPair.id)} className="cursor-pointer w-9 h-9 bg-mineshaft-700 hover:bg-chicago-700 rounded-md flex flex-row justify-center items-center duration-200"> + {!isSnapshot &&
toggleSidebar(keyPair.id)} className="cursor-pointer w-[2.35rem] h-[2.35rem] bg-mineshaft-700 hover:bg-chicago-700 rounded-md flex flex-row justify-center items-center duration-200"> -
-
-
-
+
}
); }; -export default React.memo(KeyPair); \ No newline at end of file +export default KeyPair; \ No newline at end of file diff --git a/frontend/components/dashboard/SideBar.tsx b/frontend/components/dashboard/SideBar.tsx index 0a9fca6a1..41ac9c144 100644 --- a/frontend/components/dashboard/SideBar.tsx +++ b/frontend/components/dashboard/SideBar.tsx @@ -1,4 +1,5 @@ import { useState } from 'react'; +import Image from 'next/image'; import { useTranslation } from "next-i18next"; import { faX } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -40,6 +41,7 @@ interface SideBarProps { savePush: () => void; sharedToHide: string[]; setSharedToHide: (values: string[]) => void; + deleteRow: any; } /** @@ -54,6 +56,7 @@ interface SideBarProps { * @param {function} obj.savePush - save changes andp ush secrets * @param {string[]} obj.sharedToHide - an array of shared secrets that we want to hide visually because they are overriden. * @param {function} obj.setSharedToHide - a function that updates the array of secrets that we want to hide visually + * @param {function} obj.deleteRow - a function to delete a certain keyPair * @returns the sidebar with 'secret's settings' */ const SideBar = ({ @@ -67,93 +70,97 @@ const SideBar = ({ buttonReady, savePush, sharedToHide, - setSharedToHide + setSharedToHide, + deleteRow }: SideBarProps) => { + const [isLoading, setIsLoading] = useState(false); const [overrideEnabled, setOverrideEnabled] = useState(data.map(secret => secret.type).includes("personal")); const { t } = useTranslation(); return
-
-
-

{t("dashboard:sidebar.secret")}

-
toggleSidebar("None")}> - + {isLoading ? ( +
+ +
+ ) : ( +
+
+

{t("dashboard:sidebar.secret")}

+
toggleSidebar("None")}> + +
-
-
-

{t("dashboard:sidebar.key")}

- -
- {data.filter(secret => secret.type == "shared")[0]?.value - ?
-

{t("dashboard:sidebar.value")}

- secret.type == "shared")[0]?.pos} - value={data.filter(secret => secret.type == "shared")[0]?.value} - isDuplicate={false} - blurred={true} - /> -
- secret.type == "shared")[0]?.pos} /> -
-
- :
- {t("common:note")}: - {t("dashboard:sidebar.personal-explanation")} -
} -
- {data.filter(secret => secret.type == "shared")[0]?.value && -
-

{t("dashboard:sidebar.override")}

- +

{t("dashboard:sidebar.key")}

+ -
} -
+
+ {data.filter(secret => secret.type == "shared")[0]?.value + ?
+

{t("dashboard:sidebar.value")}

secret.type == "personal")[0]?.pos : data[0]?.pos} - value={overrideEnabled ? data.filter(secret => secret.type == "personal")[0]?.value : data[0]?.value} + position={data.filter(secret => secret.type == "shared")[0]?.pos} + value={data.filter(secret => secret.type == "shared")[0]?.value} isDuplicate={false} - blurred={true} + blurred={true} /> -
- secret.type == "personal")[0]?.pos : data[0]?.pos} /> +
+ secret.type == "shared")[0]?.pos} />
+ :
+ {t("common:note")}: + {t("dashboard:sidebar.personal-explanation")} +
} +
+ {data.filter(secret => secret.type == "shared")[0]?.value && +
+

{t("dashboard:sidebar.override")}

+ +
} +
+ secret.type == "personal")[0]?.pos : data[0]?.pos} + value={overrideEnabled ? data.filter(secret => secret.type == "personal")[0]?.value : data[0]?.value} + isDuplicate={false} + blurred={true} + /> +
+ secret.type == "personal")[0]?.pos : data[0]?.pos} /> +
+
+
+ + secret.type == "shared")[0]?.comment} modifyComment={modifyComment} position={data[0]?.pos} />
- {/*
-

Group

- {}} - data={["Group1"]} - isFull={true} - /> -
*/} - - secret.type == "shared")[0]?.comment} modifyComment={modifyComment} position={data[0]?.pos} /> -
+ )}
}; diff --git a/frontend/components/utilities/telemetry/Telemetry.js b/frontend/components/utilities/telemetry/Telemetry.js index 92bdc078e..e4f7283f8 100644 --- a/frontend/components/utilities/telemetry/Telemetry.js +++ b/frontend/components/utilities/telemetry/Telemetry.js @@ -10,7 +10,7 @@ class Capturer { capture(item) { if (ENV == "production" && TELEMETRY_CAPTURING_ENABLED) { try { - api.capture(item); + this.api.capture(item); } catch (error) { console.error("PostHog", error); } @@ -20,7 +20,7 @@ class Capturer { identify(id) { if (ENV == "production" && TELEMETRY_CAPTURING_ENABLED) { try { - api.identify(id); + this.api.identify(id); } catch (error) { console.error("PostHog", error); } diff --git a/frontend/ee/api/secrets/GetActionData.ts b/frontend/ee/api/secrets/GetActionData.ts new file mode 100644 index 000000000..122870d69 --- /dev/null +++ b/frontend/ee/api/secrets/GetActionData.ts @@ -0,0 +1,32 @@ +import SecurityClient from '~/utilities/SecurityClient'; + + +interface workspaceProps { + actionId: string; +} + +/** + * This function fetches the data for a certain action performed by a user + * @param {object} obj + * @param {string} obj.actionId - id of an action for which we are trying to get data + * @returns + */ +const getActionData = async ({ actionId }: workspaceProps) => { + return SecurityClient.fetchCall( + '/api/v1/action/' + actionId, { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + } + ).then(async (res) => { + console.log(188, res) + if (res && res.status == 200) { + return (await res.json()).action; + } else { + console.log('Failed to get the info about an action'); + } + }); +}; + +export default getActionData; diff --git a/frontend/ee/api/secrets/GetProjectLogs.ts b/frontend/ee/api/secrets/GetProjectLogs.ts new file mode 100644 index 000000000..e127be815 --- /dev/null +++ b/frontend/ee/api/secrets/GetProjectLogs.ts @@ -0,0 +1,72 @@ +import SecurityClient from '~/utilities/SecurityClient'; + + +interface workspaceProps { + workspaceId: string; + offset: number; + limit: number; + userId: string; + actionNames: string; +} + +/** + * This function fetches the activity logs for a certain project + * @param {object} obj + * @param {string} obj.workspaceId - workspace id for which we are trying to get project log + * @param {object} obj.offset - teh starting point of logs that we want to pull + * @param {object} obj.limit - how many logs will we output + * @param {object} obj.userId - optional userId filter - will only query logs for that user + * @param {string} obj.actionNames - optional actionNames filter - will only query logs for those actions + * @returns + */ +const getProjectLogs = async ({ workspaceId, offset, limit, userId, actionNames }: workspaceProps) => { + let payload; + if (userId != "" && actionNames != '') { + payload = { + offset: String(offset), + limit: String(limit), + sortBy: 'recent', + userId: JSON.stringify(userId), + actionNames: actionNames + } + } else if (userId != "") { + payload = { + offset: String(offset), + limit: String(limit), + sortBy: 'recent', + userId: JSON.stringify(userId) + } + } else if (actionNames != "") { + payload = { + offset: String(offset), + limit: String(limit), + sortBy: 'recent', + actionNames: actionNames + } + } else { + payload = { + offset: String(offset), + limit: String(limit), + sortBy: 'recent' + } + } + + return SecurityClient.fetchCall( + '/api/v1/workspace/' + workspaceId + '/logs?' + + new URLSearchParams(payload), + { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + } + ).then(async (res) => { + if (res && res.status == 200) { + return (await res.json()).logs; + } else { + console.log('Failed to get project logs'); + } + }); +}; + +export default getProjectLogs; diff --git a/frontend/ee/api/secrets/GetProjectSercetShanpshots.ts b/frontend/ee/api/secrets/GetProjectSercetShanpshots.ts new file mode 100644 index 000000000..21c2ac801 --- /dev/null +++ b/frontend/ee/api/secrets/GetProjectSercetShanpshots.ts @@ -0,0 +1,39 @@ +import SecurityClient from '~/utilities/SecurityClient'; + + +interface workspaceProps { + workspaceId: string; + offset: number; + limit: number; +} + +/** + * This function fetches the secret snapshots for a certain project + * @param {object} obj + * @param {string} obj.workspaceId - project id for which we are trying to get project secret snapshots + * @param {object} obj.offset - teh starting point of snapshots that we want to pull + * @param {object} obj.limit - how many snapshots will we output + * @returns + */ +const getProjectSecretShanpshots = async ({ workspaceId, offset, limit }: workspaceProps) => { + return SecurityClient.fetchCall( + '/api/v1/workspace/' + workspaceId + '/secret-snapshots?' + + new URLSearchParams({ + offset: String(offset), + limit: String(limit) + }), { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + } + ).then(async (res) => { + if (res && res.status == 200) { + return (await res.json()).secretSnapshots; + } else { + console.log('Failed to get project secret snapshots'); + } + }); +}; + +export default getProjectSecretShanpshots; diff --git a/frontend/ee/api/secrets/GetProjectSercetSnapshotsCount.ts b/frontend/ee/api/secrets/GetProjectSercetSnapshotsCount.ts new file mode 100644 index 000000000..19389026b --- /dev/null +++ b/frontend/ee/api/secrets/GetProjectSercetSnapshotsCount.ts @@ -0,0 +1,31 @@ +import SecurityClient from '~/utilities/SecurityClient'; + + +interface workspaceProps { + workspaceId: string; +} + +/** + * This function fetches the count of secret snapshots for a certain project + * @param {object} obj + * @param {string} obj.workspaceId - project id for which we are trying to get project secret snapshots + * @returns + */ +const getProjectSercetSnapshotsCount = async ({ workspaceId }: workspaceProps) => { + return SecurityClient.fetchCall( + '/api/v1/workspace/' + workspaceId + '/secret-snapshots/count', { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + } + ).then(async (res) => { + if (res && res.status == 200) { + return (await res.json()).count; + } else { + console.log('Failed to get the count of project secret snapshots'); + } + }); +}; + +export default getProjectSercetSnapshotsCount; diff --git a/frontend/ee/api/secrets/GetSecretSnapshotData.ts b/frontend/ee/api/secrets/GetSecretSnapshotData.ts new file mode 100644 index 000000000..181fa85ce --- /dev/null +++ b/frontend/ee/api/secrets/GetSecretSnapshotData.ts @@ -0,0 +1,31 @@ +import SecurityClient from '~/utilities/SecurityClient'; + + +interface SnapshotProps { + secretSnapshotId: string; +} + +/** + * This function fetches the secrets for a certain secret snapshot + * @param {object} obj + * @param {string} obj.secretSnapshotId - snapshot id for which we are trying to get secrets + * @returns + */ +const getSecretSnapshotData = async ({ secretSnapshotId }: SnapshotProps) => { + return SecurityClient.fetchCall( + '/api/v1/secret-snapshot/' + secretSnapshotId, { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + } + ).then(async (res) => { + if (res && res.status == 200) { + return (await res.json()).secretSnapshot; + } else { + console.log('Failed to get the secrets of a certain snapshot'); + } + }); +}; + +export default getSecretSnapshotData; diff --git a/frontend/ee/api/secrets/GetSecretVersions.ts b/frontend/ee/api/secrets/GetSecretVersions.ts index 8185234e6..7b3840399 100644 --- a/frontend/ee/api/secrets/GetSecretVersions.ts +++ b/frontend/ee/api/secrets/GetSecretVersions.ts @@ -17,7 +17,7 @@ interface secretVersionProps { */ const getSecretVersions = async ({ secretId, offset, limit }: secretVersionProps) => { return SecurityClient.fetchCall( - '/api/v1/secret/' + secretId + '/secret-versions?'+ + '/api/v1/secret/' + secretId + '/secret-versions?' + new URLSearchParams({ offset: String(offset), limit: String(limit) @@ -32,7 +32,7 @@ const getSecretVersions = async ({ secretId, offset, limit }: secretVersionProps if (res && res.status == 200) { return await res.json(); } else { - console.log('Failed to get project secrets'); + console.log('Failed to get secret version history'); } }); }; diff --git a/frontend/ee/components/ActivitySideBar.tsx b/frontend/ee/components/ActivitySideBar.tsx new file mode 100644 index 000000000..e0a634d45 --- /dev/null +++ b/frontend/ee/components/ActivitySideBar.tsx @@ -0,0 +1,185 @@ +import { useEffect, useState } from "react"; +import Image from "next/image"; +import { useRouter } from "next/router"; +import { useTranslation } from "next-i18next"; +import { faX } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import getActionData from "ee/api/secrets/GetActionData"; +import patienceDiff from 'ee/utilities/findTextDifferences'; + +import getLatestFileKey from "~/pages/api/workspace/getLatestFileKey"; + +import DashboardInputField from '../../components/dashboard/DashboardInputField'; + + +const { + decryptAssymmetric, + decryptSymmetric +} = require('../../components/utilities/cryptography/crypto'); +const nacl = require('tweetnacl'); +nacl.util = require('tweetnacl-util'); + + +interface SideBarProps { + toggleSidebar: (value: string) => void; + currentAction: string; +} + +interface SecretProps { + secret: string; + secretKeyCiphertext: string; + secretKeyHash: string; + secretKeyIV: string; + secretKeyTag: string; + secretValueCiphertext: string; + secretValueHash: string; + secretValueIV: string; + secretValueTag: string; +} + +interface DecryptedSecretProps { + newSecretVersion: { + key: string; + value: string; + } + oldSecretVersion: { + key: string; + value: string; + } +} + +interface ActionProps { + name: string; +} + +/** + * @param {object} obj + * @param {function} obj.toggleSidebar - function that opens or closes the sidebar + * @param {string} obj.currentAction - the action id for which a sidebar is being displayed + * @returns the sidebar with the payload of user activity logs + */ +const ActivitySideBar = ({ + toggleSidebar, + currentAction +}: SideBarProps) => { + const { t } = useTranslation(); + const router = useRouter(); + const [actionData, setActionData] = useState(); + const [actionMetaData, setActionMetaData] = useState(); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + const getLogData = async () => { + setIsLoading(true); + const tempActionData = await getActionData({ actionId: currentAction }); + const latestKey = await getLatestFileKey({ workspaceId: String(router.query.id) }) + const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY'); + + // #TODO: make this a separate function and reuse across the app + let decryptedLatestKey: string; + if (latestKey) { + // assymmetrically decrypt symmetric key with local private key + decryptedLatestKey = decryptAssymmetric({ + ciphertext: latestKey.latestKey.encryptedKey, + nonce: latestKey.latestKey.nonce, + publicKey: latestKey.latestKey.sender.publicKey, + privateKey: String(PRIVATE_KEY) + }); + } + + const decryptedSecretVersions = tempActionData.payload.secretVersions.map((encryptedSecretVersion: { + newSecretVersion?: SecretProps; + oldSecretVersion?: SecretProps; + }) => { + return { + newSecretVersion: { + key: decryptSymmetric({ + ciphertext: encryptedSecretVersion.newSecretVersion!.secretKeyCiphertext, + iv: encryptedSecretVersion.newSecretVersion!.secretKeyIV, + tag: encryptedSecretVersion.newSecretVersion!.secretKeyTag, + key: decryptedLatestKey + }), + value: decryptSymmetric({ + ciphertext: encryptedSecretVersion.newSecretVersion!.secretValueCiphertext, + iv: encryptedSecretVersion.newSecretVersion!.secretValueIV, + tag: encryptedSecretVersion.newSecretVersion!.secretValueTag, + key: decryptedLatestKey + }) + }, + oldSecretVersion: { + key: encryptedSecretVersion.oldSecretVersion?.secretKeyCiphertext + ? decryptSymmetric({ + ciphertext: encryptedSecretVersion.oldSecretVersion?.secretKeyCiphertext, + iv: encryptedSecretVersion.oldSecretVersion?.secretKeyIV, + tag: encryptedSecretVersion.oldSecretVersion?.secretKeyTag, + key: decryptedLatestKey + }): undefined, + value: encryptedSecretVersion.oldSecretVersion?.secretValueCiphertext + ? decryptSymmetric({ + ciphertext: encryptedSecretVersion.oldSecretVersion?.secretValueCiphertext, + iv: encryptedSecretVersion.oldSecretVersion?.secretValueIV, + tag: encryptedSecretVersion.oldSecretVersion?.secretValueTag, + key: decryptedLatestKey + }): undefined + } + } + }) + + setActionData(decryptedSecretVersions); + setActionMetaData({name: tempActionData.name}); + setIsLoading(false); + } + getLogData(); + }, [currentAction]); + + return
+ {isLoading ? ( +
+ +
+ ) : ( +
+
+

{t("activity:event." + actionMetaData?.name)}

+
toggleSidebar("")}> + +
+
+
+ {(actionMetaData?.name == 'readSecrets' + || actionMetaData?.name == 'addSecrets' + || actionMetaData?.name == 'deleteSecrets') && actionData?.map((item, id) => +
+
{item.newSecretVersion.key}
+ {}} + type="value" + position={1} + value={item.newSecretVersion.value} + isDuplicate={false} + blurred={false} + /> +
+ )} + {actionMetaData?.name == 'updateSecrets' && actionData?.map((item, id) => + <> +
{item.newSecretVersion.key}
+
+
- {patienceDiff(item.oldSecretVersion.value.split(''), item.newSecretVersion.value.split(''), false).lines.map((character, id) => character.bIndex != -1 && {character.line})}
+
+ {patienceDiff(item.oldSecretVersion.value.split(''), item.newSecretVersion.value.split(''), false).lines.map((character, id) => character.aIndex != -1 && {character.line})}
+
+ + )} +
+
+ )} +
+}; + +export default ActivitySideBar; diff --git a/frontend/ee/components/ActivityTable.tsx b/frontend/ee/components/ActivityTable.tsx new file mode 100644 index 000000000..607b25c5d --- /dev/null +++ b/frontend/ee/components/ActivityTable.tsx @@ -0,0 +1,129 @@ +import React, { useEffect, useState } from 'react'; +import { useRouter } from 'next/router'; +import { useTranslation } from "next-i18next"; +import { + faAngleDown, + faAngleRight, + faUpRightFromSquare +} from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import timeSince from 'ee/utilities/timeSince'; + +import guidGenerator from '../../components/utilities/randomId'; + + +interface PayloadProps { + _id: string; + name: string; + secretVersions: string[]; +} + +interface logData { + _id: string; + channel: string; + createdAt: string; + ipAddress: string; + user: string; + payload: PayloadProps[]; +} + + +/** + * This is a single row of the activity table + * @param obj + * @param {logData} obj.row - data for a certain event + * @param {function} obj.toggleSidebar - open and close sidebar that displays data for a specific event + * @returns + */ +const ActivityLogsRow = ({ row, toggleSidebar }: { row: logData, toggleSidebar: (value: string) => void; }) => { + const [payloadOpened, setPayloadOpened] = useState(false); + const { t } = useTranslation(); + + return ( + <> +
+ + + + + + + {payloadOpened && + + + + + } + {payloadOpened && + row.payload?.map((action, index) => + + + + + )} + {payloadOpened && + + + + + } + + ); +}; + +/** + * This is the table for activity logs (one of the tabs) + * @param {object} obj + * @param {logData} obj.data - data for user activity logs + * @param {function} obj.toggleSidebar - function that opens or closes the sidebar + * @returns + */ +const ActivityTable = ({ data, toggleSidebar }: { data: logData[], toggleSidebar: (value: string) => void; }) => { + return ( +
+
+
+
Token nameProjectEnvironmentValid untilTOKEN NAMEPROJECTENVIRONMENTVAILD UNTIL
+ No service tokens yet
setPayloadOpened(!payloadOpened)} + className="border-mineshaft-700 border-t text-gray-300 flex items-center cursor-pointer" + > + + + {row.payload?.map(action => String(action.secretVersions.length) + " " + t("activity:event." + action.name)).join(" and ")} + + {row.user} + + {row.channel} + + {timeSince(new Date(row.createdAt))} +
Timestamp{row.createdAt}
{t("activity:event." + action.name)} toggleSidebar(action._id)}> + {action.secretVersions.length + (action.secretVersions.length != 1 ? " secrets" : " secret")} + +
IP Address{row.ipAddress}
+ + + + + + + + + + + + {data?.map((row, index) => { + return ; + })} + +
EVENTUSERSOURCETIME
+
+
+ ); +}; + +export default ActivityTable; diff --git a/frontend/ee/components/PITRecoverySidebar.tsx b/frontend/ee/components/PITRecoverySidebar.tsx new file mode 100644 index 000000000..e763d695b --- /dev/null +++ b/frontend/ee/components/PITRecoverySidebar.tsx @@ -0,0 +1,158 @@ +import { useEffect, useState } from "react"; +import Image from "next/image"; +import { useRouter } from "next/router"; +import { useTranslation } from "next-i18next"; +import { faX } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import getProjectSecretShanpshots from "ee/api/secrets/GetProjectSercetShanpshots"; +import getSecretSnapshotData from "ee/api/secrets/GetSecretSnapshotData"; +import timeSince from "ee/utilities/timeSince"; + +import Button from "~/components/basic/buttons/Button"; +import { decryptAssymmetric, decryptSymmetric } from "~/components/utilities/cryptography/crypto"; +import getLatestFileKey from "~/pages/api/workspace/getLatestFileKey"; + + +interface SideBarProps { + toggleSidebar: (value: boolean) => void; + setSnapshotData: (value: any) => void; + chosenSnapshot: string; +} + +interface SnaphotProps { + _id: string; + createdAt: string; + secretVersions: string[]; +} + +interface EncrypetedSecretVersionListProps { + _id: string; + createdAt: string; + secretValueCiphertext: string; + secretValueIV: string; + secretValueTag: string; + secretKeyCiphertext: string; + secretKeyIV: string; + secretKeyTag: string; + environment: string; + type: "personal" | "shared"; +} + +/** + * @param {object} obj + * @param {function} obj.toggleSidebar - function that opens or closes the sidebar + * @param {function} obj.setSnapshotData - state manager for snapshot data + * @param {string} obj.chosenSnaphshot - the snapshot id which is currently selected + * + * + * @returns the sidebar with the options for point-in-time recovery (commits) + */ +const PITRecoverySidebar = ({ + toggleSidebar, + setSnapshotData, + chosenSnapshot +}: SideBarProps) => { + const { t } = useTranslation(); + const router = useRouter(); + const [isLoading, setIsLoading] = useState(false); + const [secretSnapshotsMetadata, setSecretSnapshotsMetadata] = useState([]); + const [currentOffset, setCurrentOffset] = useState(0); + const currentLimit = 15; + + const loadMoreSnapshots = () => { + setCurrentOffset(currentOffset + currentLimit); + } + + useEffect(() => { + const getLogData = async () => { + setIsLoading(true); + const results = await getProjectSecretShanpshots({ workspaceId: String(router.query.id), limit: currentLimit, offset: currentOffset }) + setSecretSnapshotsMetadata(secretSnapshotsMetadata.concat(results)); + setIsLoading(false); + } + getLogData(); + }, [currentOffset]); + + const exploreSnapshot = async ({ snapshotId }: { snapshotId: string; }) => { + const secretSnapshotData = await getSecretSnapshotData({ secretSnapshotId: snapshotId }); + + const latestKey = await getLatestFileKey({ workspaceId: String(router.query.id) }) + const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY'); + + let decryptedLatestKey: string; + if (latestKey) { + // assymmetrically decrypt symmetric key with local private key + decryptedLatestKey = decryptAssymmetric({ + ciphertext: latestKey.latestKey.encryptedKey, + nonce: latestKey.latestKey.nonce, + publicKey: latestKey.latestKey.sender.publicKey, + privateKey: String(PRIVATE_KEY) + }); + } + + const decryptedSecretVersions = secretSnapshotData.secretVersions.map((encryptedSecretVersion: EncrypetedSecretVersionListProps, pos: number) => { + return { + id: encryptedSecretVersion._id, + pos: pos, + type: encryptedSecretVersion.type, + environment: encryptedSecretVersion.environment, + key: decryptSymmetric({ + ciphertext: encryptedSecretVersion.secretKeyCiphertext, + iv: encryptedSecretVersion.secretKeyIV, + tag: encryptedSecretVersion.secretKeyTag, + key: decryptedLatestKey + }), + value: decryptSymmetric({ + ciphertext: encryptedSecretVersion.secretValueCiphertext, + iv: encryptedSecretVersion.secretValueIV, + tag: encryptedSecretVersion.secretValueTag, + key: decryptedLatestKey + }) + } + }) + + setSnapshotData({ id: secretSnapshotData._id, createdAt: secretSnapshotData.createdAt, secretVersions: decryptedSecretVersions }) + } + + return
+ {isLoading ? ( +
+ infisical loading indicator +
+ ) : ( +
+
+

{t("Point-in-time Recovery")}

+
toggleSidebar(false)}> + +
+
+
+ {secretSnapshotsMetadata?.map((snapshot: SnaphotProps, id: number) =>
+
+
{timeSince(new Date(snapshot.createdAt))}
+
{" - " + snapshot.secretVersions.length + " Secrets"}
+
+
exploreSnapshot({ snapshotId: snapshot._id })} + className={`${chosenSnapshot == snapshot._id || (id == 0 && chosenSnapshot === "") ? "text-bunker-800 pointer-events-none" : "text-bunker-200 hover:text-primary duration-200 cursor-pointer"} text-sm`}> + {id == 0 ? "Current Version" : chosenSnapshot == snapshot._id ? "Currently Viewing" : "Explore"} +
+
)} +
+
+
+
+
+
+ )} +
+}; + +export default PITRecoverySidebar; diff --git a/frontend/ee/components/SecretVersionList.tsx b/frontend/ee/components/SecretVersionList.tsx index 6cf7bd9b2..3eb40005f 100644 --- a/frontend/ee/components/SecretVersionList.tsx +++ b/frontend/ee/components/SecretVersionList.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from 'react'; +import Image from 'next/image'; import { useRouter } from 'next/router'; import { useTranslation } from "next-i18next"; import { faCircle, faDotCircle } from '@fortawesome/free-solid-svg-icons'; @@ -22,15 +23,18 @@ interface EncrypetedSecretVersionListProps { /** + * @param {string} secretId - the id of a secret for which are querying version history * @returns a list of versions for a specific secret */ const SecretVersionList = ({ secretId }: { secretId: string; }) => { const router = useRouter(); + const [isLoading, setIsLoading] = useState(false); const { t } = useTranslation(); - const [secretVersions, setSecretVersions] = useState([{createdAt: "123", value: "124"}]); + const [secretVersions, setSecretVersions] = useState([]); useEffect(() => { const getSecretVersionHistory = async () => { + setIsLoading(true); try { const encryptedSecretVersions = await getSecretVersions({ secretId, offset: 0, limit: 10}); const latestKey = await getLatestFileKey({ workspaceId: String(router.query.id) }) @@ -61,43 +65,54 @@ const SecretVersionList = ({ secretId }: { secretId: string; }) => { }) setSecretVersions(decryptedSecretVersions); + setIsLoading(false); } catch (error) { console.log(error) } }; getSecretVersionHistory(); - }, []); + }, [secretId]); return
-

{t("dashboard:sidebar.version-history")}

-
-
- {secretVersions?.sort((a, b) => b.createdAt.localeCompare(a.createdAt)) - .map((version: DecryptedSecretVersionListProps, index: number) => -
-
-
-
-
-
-
- {(new Date(version.createdAt)).toLocaleDateString('en-US', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit' - })} +

{t("dashboard:sidebar.version-history")}

+
+ {isLoading ? ( +
+ infisical loading indicator +
+ ) : ( +
+ {secretVersions?.sort((a, b) => b.createdAt.localeCompare(a.createdAt)) + .map((version: DecryptedSecretVersionListProps, index: number) => +
+
+
+
+
+
+
+ {(new Date(version.createdAt)).toLocaleDateString('en-US', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + })} +
+

Value:{version.value}

+
-

Value:{version.value}

- {/*

Updated by:{version.user}

*/} -
+ )}
)}
-
}; export default SecretVersionList; diff --git a/frontend/ee/utilities/findTextDifferences.ts b/frontend/ee/utilities/findTextDifferences.ts new file mode 100644 index 000000000..ffd847a77 --- /dev/null +++ b/frontend/ee/utilities/findTextDifferences.ts @@ -0,0 +1,346 @@ +/** + * + * @param textOld - old secret + * @param textNew - new (updated) secret + * @param diffPlusFlag - a flag for whether we want to detect moving segments + * - doesn't work in some examples (e.g., when we have a full reverse ordering of the text) + * @returns + */ +function patienceDiff(textOld: string[], textNew: string[], diffPlusFlag?: boolean) { + + /** + * findUnique finds all unique values in arr[lo..hi], inclusive. This + * function is used in preparation for determining the longest common + * subsequence. Specifically, it first reduces the array range in question + * to unique values. + * @param chars - an array of characters + * @param lo + * @param hi + * @returns - an ordered Map, with the arr[i] value as the Map key and the + * array index i as the Map value. + */ + function findUnique(chars: string[], lo: number, hi: number) { + const characterMap = new Map(); + + for (let i=lo; i<=hi; i++) { + const character = chars[i]; + + if (characterMap.has(character)) { + characterMap.get(character).count++; + characterMap.get(character).index = i; + } else { + characterMap.set(character, { count: 1, index: i }); + } + } + + characterMap.forEach((val, key, map) => { + if (val.count !== 1) { + map.delete(key); + } else { + map.set(key, val.index); + } + }); + + return characterMap; + } + + /** + * @param aArray + * @param aLo + * @param aHi + * @param bArray + * @param bLo + * @param bHi + * @returns an ordered Map, with the Map key as the common line between aArray + * and bArray, with the Map value as an object containing the array indexes of + * the matching unique lines. + * + */ + function uniqueCommon(aArray: string[], aLo: number, aHi: number, bArray: string[], bLo: number, bHi: number) { + const ma = findUnique(aArray, aLo, aHi); + const mb = findUnique(bArray, bLo, bHi); + + ma.forEach((val, key, map) => { + if (mb.has(key)) { + map.set(key, { + indexA: val, + indexB: mb.get(key) + }); + } else { + map.delete(key); + } + }); + + return ma; + } + + /** + * longestCommonSubsequence takes an ordered Map from the function uniqueCommon + * and determines the Longest Common Subsequence (LCS). + * @param abMap + * @returns an ordered array of objects containing the array indexes of the + * matching lines for a LCS. + */ + function longestCommonSubsequence(abMap: Map) { + const ja: any = []; + + // First, walk the list creating the jagged array. + abMap.forEach((val, key, map) => { + let i = 0; + + while (ja[i] && ja[i][ja[i].length - 1].indexB < val.indexB) { + i++; + } + + if (!ja[i]) { + ja[i] = []; + } + + if (0 < i) { + val.prev = ja[i-1][ja[i - 1].length - 1]; + } + ja[i].push(val); + }); + + // Now, pull out the longest common subsequence. + let lcs: any[] = []; + + if (0 < ja.length) { + const n = ja.length - 1; + lcs = [ja[n][ja[n].length - 1]]; + + while (lcs[lcs.length - 1].prev) { + lcs.push(lcs[lcs.length - 1].prev); + } + } + + return lcs.reverse(); + } + + // "result" is the array used to accumulate the textOld that are deleted, the + // lines that are shared between textOld and textNew, and the textNew that were + // inserted. + + const result: any[] = []; + let deleted = 0; + let inserted = 0; + + // aMove and bMove will contain the lines that don't match, and will be returned + // for possible searching of lines that moved. + + const aMove: any[] = []; + const aMoveIndex: any[] = []; + const bMove: any[] = []; + const bMoveIndex: any[] = []; + + /** + * addToResult simply pushes the latest value onto the "result" array. This + * array captures the diff of the line, aIndex, and bIndex from the textOld + * and textNew array. + * @param aIndex + * @param bIndex + */ + function addToResult(aIndex: number, bIndex: number) { + if (bIndex < 0) { + aMove.push(textOld[aIndex]); + aMoveIndex.push(result.length); + deleted++; + } else if (aIndex < 0) { + bMove.push(textNew[bIndex]); + bMoveIndex.push(result.length); + inserted++; + } + + result.push({ + line: 0 <= aIndex ? textOld[aIndex] : textNew[bIndex], + aIndex: aIndex, + bIndex: bIndex, + }); + } + + /** + * addSubMatch handles the lines between a pair of entries in the LCS. Thus, + * this function might recursively call recurseLCS to further match the lines + * between textOld and textNew. + * @param aLo + * @param aHi + * @param bLo + * @param bHi + */ + function addSubMatch(aLo: number, aHi: number, bLo: number, bHi: number) { + // Match any lines at the beginning of textOld and textNew. + while (aLo <= aHi && bLo <= bHi && textOld[aLo] === textNew[bLo]) { + addToResult(aLo++, bLo++); + } + + // Match any lines at the end of textOld and textNew, but don't place them + // in the "result" array just yet, as the lines between these matches at + // the beginning and the end need to be analyzed first. + + const aHiTemp = aHi; + while (aLo <= aHi && bLo <= bHi && textOld[aHi] === textNew[bHi]) { + aHi--; + bHi--; + } + + // Now, check to determine with the remaining lines in the subsequence + // whether there are any unique common lines between textOld and textNew. + // + // If not, add the subsequence to the result (all textOld having been + // deleted, and all textNew having been inserted). + // + // If there are unique common lines between textOld and textNew, then let's + // recursively perform the patience diff on the subsequence. + + const uniqueCommonMap = uniqueCommon(textOld, aLo, aHi, textNew, bLo, bHi); + + if (uniqueCommonMap.size === 0) { + while (aLo <= aHi) { + addToResult(aLo++, -1); + } + + while (bLo <= bHi) { + addToResult(-1, bLo++); + } + } else { + recurseLCS(aLo, aHi, bLo, bHi, uniqueCommonMap); + } + + // Finally, let's add the matches at the end to the result. + while (aHi < aHiTemp) { + addToResult(++aHi, ++bHi); + } + } + + /** + * recurseLCS finds the longest common subsequence (LCS) between the arrays + * textOld[aLo..aHi] and textNew[bLo..bHi] inclusive. Then for each subsequence + * recursively performs another LCS search (via addSubMatch), until there are + * none found, at which point the subsequence is dumped to the result. + * @param aLo + * @param aHi + * @param bLo + * @param bHi + * @param uniqueCommonMap + */ + function recurseLCS(aLo: number, aHi: number, bLo: number, bHi: number, uniqueCommonMap?: any) { + const x = longestCommonSubsequence(uniqueCommonMap || uniqueCommon(textOld, aLo, aHi, textNew, bLo, bHi)); + + if (x.length === 0) { + addSubMatch(aLo, aHi, bLo, bHi); + } else { + if (aLo < x[0].indexA || bLo < x[0].indexB) { + addSubMatch(aLo, x[0].indexA - 1, bLo, x[0].indexB - 1); + } + + let i; + for (i = 0; i < x.length - 1; i++) { + addSubMatch(x[i].indexA, x[i+1].indexA - 1, x[i].indexB, x[i+1].indexB - 1); + } + + if (x[i].indexA <= aHi || x[i].indexB <= bHi) { + addSubMatch(x[i].indexA, aHi, x[i].indexB, bHi); + } + } + } + + recurseLCS(0, textOld.length - 1, 0, textNew.length - 1); + + if (diffPlusFlag) { + return { + lines: result, + lineCountDeleted: deleted, + lineCountInserted: inserted, + lineCountMoved: 0, + aMove: aMove, + aMoveIndex: aMoveIndex, + bMove: bMove, + bMoveIndex: bMoveIndex, + }; + } + + return { + lines: result, + lineCountDeleted: deleted, + lineCountInserted: inserted, + lineCountMoved: 0, + }; +} + +/** + * use: patienceDiffPlus( textOld[], textNew[] ) + * + * where: + * textOld[] contains the original text lines. + * textNew[] contains the new text lines. + * + * returns an object with the following properties: + * lines[] with properties of: + * line containing the line of text from textOld or textNew. + * aIndex referencing the index in aLine[]. + * bIndex referencing the index in textNew[]. + * (Note: The line is text from either textOld or textNew, with aIndex and bIndex + * referencing the original index. If aIndex === -1 then the line is new from textNew, + * and if bIndex === -1 then the line is old from textOld.) + * moved is true if the line was moved from elsewhere in textOld[] or textNew[]. + * lineCountDeleted is the number of lines from textOld[] not appearing in textNew[]. + * lineCountInserted is the number of lines from textNew[] not appearing in textOld[]. + * lineCountMoved is the number of lines that moved. + */ + +function patienceDiffPlus(textOld: string[], textNew: string[]) { + + const difference = patienceDiff(textOld, textNew, true); + + let aMoveNext = difference.aMove; + let aMoveIndexNext = difference.aMoveIndex; + let bMoveNext = difference.bMove; + let bMoveIndexNext = difference.bMoveIndex; + + delete difference.aMove; + delete difference.aMoveIndex; + delete difference.bMove; + delete difference.bMoveIndex; + + let lastLineCountMoved; + + do { + const aMove = aMoveNext; + const aMoveIndex = aMoveIndexNext; + const bMove = bMoveNext; + const bMoveIndex = bMoveIndexNext; + + aMoveNext = []; + aMoveIndexNext = []; + bMoveNext = []; + bMoveIndexNext = []; + + const subDiff = patienceDiff(aMove!, bMove!); + + lastLineCountMoved = difference.lineCountMoved; + + subDiff.lines.forEach((v, i) => { + + if (0 <= v.aIndex && 0 <= v.bIndex) { + + difference.lines[aMoveIndex![v.aIndex]].moved = true; + difference.lines[bMoveIndex![v.bIndex]].aIndex = aMoveIndex![v.aIndex]; + difference.lines[bMoveIndex![v.bIndex]].moved = true; + difference.lineCountInserted--; + difference.lineCountDeleted--; + difference.lineCountMoved++; + } else if (v.bIndex < 0) { + aMoveNext!.push(aMove![v.aIndex]); + aMoveIndexNext!.push(aMoveIndex![v.aIndex]); + } else { + bMoveNext!.push(bMove![v.bIndex]); + bMoveIndexNext!.push(bMoveIndex![v.bIndex]); + } + }); + } while (0 < difference.lineCountMoved - lastLineCountMoved); + + return difference; + +} + +export default patienceDiff; diff --git a/frontend/ee/utilities/timeSince.ts b/frontend/ee/utilities/timeSince.ts new file mode 100644 index 000000000..b79249967 --- /dev/null +++ b/frontend/ee/utilities/timeSince.ts @@ -0,0 +1,35 @@ +/** + * Time since a certain date + * @param {Date} date - the timestamp got which we want to understand how long ago it happened + * @returns {String} text - how much time has passed since a certain timestamp + */ +function timeSince(date: Date) { + const seconds = Math.floor( + ((new Date() as any) - (date as any)) / 1000 + ) as number; + + let interval = seconds / 31536000; + + if (interval > 1) { + return Math.floor(interval) + ' years ago'; + } + interval = seconds / 2592000; + if (interval > 1) { + return Math.floor(interval) + ' months ago'; + } + interval = seconds / 86400; + if (interval > 1) { + return Math.floor(interval) + ' days ago'; + } + interval = seconds / 3600; + if (interval > 1) { + return Math.floor(interval) + ' hours ago'; + } + interval = seconds / 60; + if (interval > 1) { + return Math.floor(interval) + ' minutes ago'; + } + return Math.floor(seconds) + ' seconds ago'; +} + +export default timeSince; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index eeed48eef..6d201f5ea 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,5 +1,5 @@ { - "name": "npm-proj-1671831898059-0.69127202445261186TgV0L", + "name": "frontend", "lockfileVersion": 2, "requires": true, "packages": { @@ -80,19 +80,6 @@ "node": ">=6.0.0" } }, - "node_modules/@ampproject/remapping/node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "peer": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", @@ -105,34 +92,34 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", - "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "peer": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.5", - "@babel/parser": "^7.20.5", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" }, "engines": { @@ -143,44 +130,12 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "peer": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/core/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "peer": true - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/generator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", - "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "dependencies": { - "@babel/types": "^7.20.5", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -188,6 +143,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", @@ -200,14 +168,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "peer": true, "dependencies": { - "@babel/compat-data": "^7.20.0", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" }, "engines": { @@ -217,15 +186,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/helper-environment-visitor": { "version": "7.18.9", "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", @@ -269,9 +229,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "peer": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", @@ -279,18 +239,18 @@ "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "engines": { "node": ">=6.9.0" } @@ -344,14 +304,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", - "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", + "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", "peer": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -371,9 +331,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", - "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -407,44 +367,44 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.1.tgz", - "integrity": "sha512-CGulbEDcg/ND1Im7fUNRZdGXmX2MTWVVZacQi/6DiKE5HNwZ3aVTm5PV4lO8HHz0B2h8WQyvKKjbX5XgTtydsg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.7.tgz", + "integrity": "sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg==", "dev": true, "dependencies": { "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.10" + "regenerator-runtime": "^0.13.11" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", - "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz", + "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==", "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.5", - "@babel/types": "^7.20.5", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -452,31 +412,10 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/@babel/types": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", - "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dependencies": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", @@ -487,69 +426,48 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.10.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", - "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", + "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.0", + "@emotion/serialize": "^1.1.1", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.0.13" + "stylis": "4.1.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, - "node_modules/@emotion/babel-plugin/node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@emotion/cache": { - "version": "11.10.3", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", - "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", "dependencies": { "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.0", + "@emotion/sheet": "^1.2.1", "@emotion/utils": "^1.2.0", "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.0.13" + "stylis": "4.1.3" } }, - "node_modules/@emotion/cache/node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, "node_modules/@emotion/css": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/@emotion/css/-/css-11.10.0.tgz", - "integrity": "sha512-dH9f+kSCucc8ilMg0MUA1AemabcyzYpe5EKX24F528PJjD7HyIY/VBNJHxfUdc8l400h2ncAjR6yEDu+DBj2cg==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/css/-/css-11.10.5.tgz", + "integrity": "sha512-maJy0wG82hWsiwfJpc3WrYsyVwUbdu+sdIseKUB+/OLjB8zgc3tqkT6eO0Yt0AhIkJwGGnmMY/xmQwEAgQ4JHA==", "dependencies": { - "@emotion/babel-plugin": "^11.10.0", - "@emotion/cache": "^11.10.0", - "@emotion/serialize": "^1.1.0", - "@emotion/sheet": "^1.2.0", + "@emotion/babel-plugin": "^11.10.5", + "@emotion/cache": "^11.10.5", + "@emotion/serialize": "^1.1.1", + "@emotion/sheet": "^1.2.1", "@emotion/utils": "^1.2.0" }, "peerDependencies": { @@ -567,22 +485,22 @@ "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.3.tgz", - "integrity": "sha512-RFg04p6C+1uO19uG8N+vqanzKqiM9eeV1LDOG3bmkYmuOj7NbKNlFC/4EZq5gnwAIlcC/jOT24f8Td0iax2SXA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", "dependencies": { - "@emotion/memoize": "^0.7.4" + "@emotion/memoize": "^0.8.0" } }, "node_modules/@emotion/memoize": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", - "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "node_modules/@emotion/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", "dependencies": { "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", @@ -591,16 +509,6 @@ "csstype": "^3.0.2" } }, - "node_modules/@emotion/serialize/node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" - }, "node_modules/@emotion/server": { "version": "11.10.0", "resolved": "https://registry.npmjs.org/@emotion/server/-/server-11.10.0.tgz", @@ -621,9 +529,9 @@ } }, "node_modules/@emotion/sheet": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", - "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", + "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" }, "node_modules/@emotion/stylis": { "version": "0.8.5", @@ -631,9 +539,9 @@ "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" }, "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, "node_modules/@emotion/utils": { "version": "1.2.0", @@ -646,15 +554,15 @@ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -668,33 +576,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -706,76 +591,58 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.2.tgz", - "integrity": "sha512-wBaAPGz1Awxg05e0PBRkDRuTsy4B3dpBm+zreTTyd9TH4uUM27cAL4xWyWR0rLJCrRwzVsQ4hF3FvM6rqydKPA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", + "integrity": "sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==", "hasInstallScript": true, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.2.tgz", - "integrity": "sha512-853G/Htp0BOdXnPoeCPTjFrVwyrJHpe8MhjB/DYE9XjwhnNDfuBCd3aKc2YUYbEfHEcBws4UAA0kA9dymZKGjA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz", + "integrity": "sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.1.2" + "@fortawesome/fontawesome-common-types": "6.2.1" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-brands-svg-icons": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.1.2.tgz", - "integrity": "sha512-b2eMfXQBsSxh52pcPtYchURQs6BWNh3zVTG8XH8Lv6V4kDhEg7D0kHN+K1SZniDiPb/e5tBlaygsinMUvetITA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.1.tgz", + "integrity": "sha512-L8l4MfdHPmZlJ72PvzdfwOwbwcCAL0vx48tJRnI6u1PJXh+j2f3yDoKyQgO3qjEsgD5Fr2tQV/cPP8F/k6aUig==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.1.2" + "@fortawesome/fontawesome-common-types": "6.2.1" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-regular-svg-icons": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.1.2.tgz", - "integrity": "sha512-xR4hA+tAwsaTHGfb+25H1gVU/aJ0Rzu+xIUfnyrhaL13yNQ7TWiI2RvzniAaB+VGHDU2a+Pk96Ve+pkN3/+TTQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.1.tgz", + "integrity": "sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.1.2" + "@fortawesome/fontawesome-common-types": "6.2.1" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-solid-svg-icons": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.2.tgz", - "integrity": "sha512-lTgZz+cMpzjkHmCwOG3E1ilUZrnINYdqMmrkv30EC3XbRsGlbIOL8H9LaNp5SV4g0pNJDfQ4EdTWWaMvdwyLiQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.1.tgz", + "integrity": "sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.1.2" + "@fortawesome/fontawesome-common-types": "6.2.1" }, "engines": { "node": ">=6" @@ -794,9 +661,12 @@ } }, "node_modules/@headlessui/react": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.6.6.tgz", - "integrity": "sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.7.tgz", + "integrity": "sha512-BqDOd/tB9u2tA0T3Z0fn18ktw+KbVwMnkxxsGPIH2hzssrQhKB5n/6StZOyvLYP/FsYtvuXfi9I0YowKPv2c1w==", + "dependencies": { + "client-only": "^0.0.1" + }, "engines": { "node": ">=10" }, @@ -806,9 +676,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -819,29 +689,6 @@ "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -862,13 +709,13 @@ "dev": true }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "peer": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" }, "engines": { "node": ">=6.0.0" @@ -896,12 +743,12 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", - "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@next/env": { @@ -910,9 +757,9 @@ "integrity": "sha512-H/69Lc5Q02dq3o+dxxy5O/oNxFsZpdL6WREtOOtOM1B/weonIwDXkekr1KV5DPVPr12IHFPrMrcJQ6bgPMfn7A==" }, "node_modules/@next/eslint-plugin-next": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.0.5.tgz", - "integrity": "sha512-H9U9B1dFnCDmylDZ6/dYt95Ie1Iu+SLBMcO6rkIGIDcj5UK+DNyMiWm83xWBZ1gREM8cfp5Srv1g6wqf8pM4lw==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.1.1.tgz", + "integrity": "sha512-SBrOFS8PC3nQ5aeZmawJkjKkWjwK9RoxvBSv/86nZp0ubdoVQoko8r8htALd9ufp16NhacCdqhu9bzZLDWtALQ==", "dev": true, "dependencies": { "glob": "7.1.7" @@ -1169,14 +1016,14 @@ } }, "node_modules/@reduxjs/toolkit": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.3.tgz", - "integrity": "sha512-lU/LDIfORmjBbyDLaqFN2JB9YmAT1BElET9y0ZszwhSBa5Ef3t6o5CrHupw5J1iOXwd+o92QfQZ8OJpwXvsssg==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.1.tgz", + "integrity": "sha512-HikrdY+IDgRfRYlCTGUQaiCxxDDgM1mQrRbZ6S1HFZX5ZYuJ4o8EstNmhTwHdPl2rTmLxzwSu0b3AyeyTlR+RA==", "dependencies": { - "immer": "^9.0.7", - "redux": "^4.1.2", - "redux-thunk": "^2.4.1", - "reselect": "^4.1.5" + "immer": "^9.0.16", + "redux": "^4.2.0", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.7" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18", @@ -1198,30 +1045,30 @@ "dev": true }, "node_modules/@sentry/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.15.0.tgz", - "integrity": "sha512-MN9haDRh9ZOsTotoDTHu2BT3sT8Vs1F0alhizUpDyjN2YgBCqR6JV+AbAE1XNHwS2+5zbppch1PwJUVeE58URQ==", + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.22.0.tgz", + "integrity": "sha512-LhCL+wb1Jch+OesB2CIt6xpfO1Ab6CRvoNYRRzVumWPLns1T3ZJkarYfhbLaOEIb38EIbPgREdxn2AJT560U4Q==", "engines": { "node": ">=8" } }, "node_modules/@stripe/react-stripe-js": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-1.10.0.tgz", - "integrity": "sha512-vuIjJUZJ3nyiaGa5z5iyMCzZfGGsgzOOjWjqknbbhkNsewyyginfeky9EZLSz9+iSAsgC9K6MeNOTLKVGcMycQ==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-1.16.2.tgz", + "integrity": "sha512-RTL3rE6eNosRb2AhxHBWN0HQgigSo/cfZu8vPAqB9/dZEAjYcEoiDYtjI9Zj1MAh58c5RyQNn3HU3M4hIqUdAg==", "dependencies": { "prop-types": "^15.7.2" }, "peerDependencies": { - "@stripe/stripe-js": "^1.34.0", + "@stripe/stripe-js": "^1.44.1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/@stripe/stripe-js": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.36.0.tgz", - "integrity": "sha512-m45BD9JxOfIBT0Tz4MupiKzM8M58NX/We8wKlf+54TCZpW1RVAyFpJ58CbtyU/LxAM+opT6cewHRVfs7bTUtBA==" + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.46.0.tgz", + "integrity": "sha512-dkm0zCEoRLu5rTnsIgwDf/QG2DKcalOT2dk1IVgMySOHWTChLyOvQwMYhEduGgLvyYWTwNhAUV4WOLPQvjwLwA==" }, "node_modules/@swc/helpers": { "version": "0.4.11", @@ -1232,9 +1079,9 @@ } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.7.tgz", - "integrity": "sha512-JTTSTrgZfp6Ki4svhPA4mkd9nmQ/j9EfE7SbHJ1cLtthKkpW2OxsFXzSmxbhYbEkfNIyAyhle5p4SYyKRbz/jg==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.8.tgz", + "integrity": "sha512-xGQEp8KXN8Sd8m6R4xYmwxghmswrd0cPnNI2Lc6fmrC3OojysTBJJGSIVwPV56q4t6THFUK3HJ0EaWwpglSxWw==", "dev": true, "dependencies": { "lodash.castarray": "^4.4.0", @@ -1291,11 +1138,6 @@ "@types/unist": "*" } }, - "node_modules/@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" - }, "node_modules/@types/ms": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", @@ -1334,9 +1176,9 @@ } }, "node_modules/@types/react-redux": { - "version": "7.1.24", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz", - "integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==", + "version": "7.1.25", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz", + "integrity": "sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg==", "dependencies": { "@types/hoist-non-react-statics": "^3.3.0", "@types/react": "*", @@ -1371,14 +1213,14 @@ "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", - "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.0.tgz", + "integrity": "sha512-SVLafp0NXpoJY7ut6VFVUU9I+YeFsDzeQwtK0WZ+xbRN3mtxJ08je+6Oi2N89qDn087COdO0u3blKZNv9VetRQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/type-utils": "5.47.1", - "@typescript-eslint/utils": "5.47.1", + "@typescript-eslint/scope-manager": "5.48.0", + "@typescript-eslint/type-utils": "5.48.0", + "@typescript-eslint/utils": "5.48.0", "debug": "^4.3.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", @@ -1403,85 +1245,48 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" + "yallist": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=10" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=10" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.0.tgz", - "integrity": "sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.0.tgz", + "integrity": "sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.45.0", - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/typescript-estree": "5.45.0", + "@typescript-eslint/scope-manager": "5.48.0", + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/typescript-estree": "5.48.0", "debug": "^4.3.4" }, "engines": { @@ -1500,37 +1305,14 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz", - "integrity": "sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz", + "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/visitor-keys": "5.45.0" + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/visitor-keys": "5.48.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1541,13 +1323,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", - "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.0.tgz", + "integrity": "sha512-vbtPO5sJyFjtHkGlGK4Sthmta0Bbls4Onv0bEqOGm7hP9h8UpRsHJwsrCiWtCUndTRNQO/qe6Ijz9rnT/DB+7g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.47.1", - "@typescript-eslint/utils": "5.47.1", + "@typescript-eslint/typescript-estree": "5.48.0", + "@typescript-eslint/utils": "5.48.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1567,90 +1349,10 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", - "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@typescript-eslint/types": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.0.tgz", - "integrity": "sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz", + "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1661,13 +1363,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz", - "integrity": "sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz", + "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/visitor-keys": "5.45.0", + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/visitor-keys": "5.48.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1687,40 +1389,50 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "yallist": "^4.0.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=10" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.1.tgz", - "integrity": "sha512-l90SdwqfmkuIVaREZ2ykEfCezepCLxzWMo5gVfcJsJCaT4jHT+QjgSkYhs5BMQmWqE9k3AtIfk4g211z/sTMVw==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.0.tgz", + "integrity": "sha512-x2jrMcPaMfsHRRIkL+x96++xdzvrdBCnYRd5QiW5Wgo1OB4kDYPbC1XjWP/TNqlfK93K/lUL92erq5zPLgFScQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/typescript-estree": "5.47.1", + "@typescript-eslint/scope-manager": "5.48.0", + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/typescript-estree": "5.48.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -1736,132 +1448,46 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", + "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" + "yallist": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=10" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", - "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=10" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/@typescript-eslint/utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz", - "integrity": "sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", + "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/types": "5.48.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1873,9 +1499,9 @@ } }, "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1904,6 +1530,18 @@ "xtend": "^4.0.2" } }, + "node_modules/acorn-node/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/acorn-walk": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", @@ -1954,23 +1592,10 @@ "node": ">=4" } }, - "node_modules/ansi-styles/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/ansi-styles/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -1987,12 +1612,9 @@ "dev": true }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/aria-query": { "version": "4.2.2", @@ -2107,9 +1729,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz", - "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==", + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", "dev": true, "funding": [ { @@ -2122,8 +1744,8 @@ } ], "dependencies": { - "browserslist": "^4.21.3", - "caniuse-lite": "^1.0.30001373", + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -2139,10 +1761,22 @@ "postcss": "^8.1.0" } }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axe-core": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", - "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.2.tgz", + "integrity": "sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==", "dev": true, "engines": { "node": ">=4" @@ -2158,9 +1792,9 @@ } }, "node_modules/axios-auth-refresh": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/axios-auth-refresh/-/axios-auth-refresh-3.3.3.tgz", - "integrity": "sha512-2IbDhJ/h6ddNBBnnzn1VFK/qx17pE9aVqiafB8rx5LVHsJ1HtFpUGkbXY7PzTG+8P9HJWcyA3fNZl9BikSuilg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/axios-auth-refresh/-/axios-auth-refresh-3.3.4.tgz", + "integrity": "sha512-cGq3bZu+lip5j+byaQRZaZ3wpCUxs93jGV0614VYP5k2H1vbdoaw6HGazaUJxcRsFMctR3DItCAx1Dn7KerlcA==", "peerDependencies": { "axios": ">= 0.18 < 0.19.0 || >= 0.19.1" } @@ -2267,6 +1901,27 @@ "readable-stream": "^3.4.0" } }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2290,9 +1945,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "funding": [ { "type": "opencollective", @@ -2304,10 +1959,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "update-browserslist-db": "^1.0.9" }, "bin": { "browserslist": "cli.js" @@ -2386,14 +2041,17 @@ } }, "node_modules/camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/caniuse-lite": { - "version": "1.0.30001418", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", - "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==", + "version": "1.0.30001442", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz", + "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==", "funding": [ { "type": "opencollective", @@ -2437,6 +2095,14 @@ "node": ">=4" } }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/character-entities": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", @@ -2500,9 +2166,14 @@ } }, "node_modules/classnames": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", - "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, "node_modules/clsx": { "version": "1.2.1", @@ -2525,6 +2196,28 @@ } }, "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -2535,20 +2228,11 @@ "node": ">=7.0.0" } }, - "node_modules/color-name": { + "node_modules/color/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2561,9 +2245,9 @@ } }, "node_modules/comma-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", - "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2576,17 +2260,9 @@ "dev": true }, "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/cookies": { "version": "0.8.0", @@ -2601,9 +2277,9 @@ } }, "node_modules/core-js": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", - "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==", + "version": "3.27.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz", + "integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -2611,9 +2287,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", - "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==", + "version": "3.27.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.27.1.tgz", + "integrity": "sha512-BS2NHgwwUppfeoqOXqi08mUqS5FiZpuRuJJpKsaME7kJz0xxuk0xkhDdfMIlP/zLa80krBqss1LtD7f889heAw==", "dev": true, "hasInstallScript": true, "funding": { @@ -2627,9 +2303,9 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -2715,9 +2391,9 @@ } }, "node_modules/csstype": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", - "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -2726,11 +2402,19 @@ "dev": true }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { - "ms": "2.0.0" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decode-named-character-reference": { @@ -2806,20 +2490,14 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-properties/node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/delayed-stream": { "version": "1.0.0", @@ -2928,6 +2606,11 @@ "readable-stream": "^2.0.2" } }, + "node_modules/duplexer2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "node_modules/duplexer2/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -2956,9 +2639,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.206", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz", - "integrity": "sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA==" + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -3006,41 +2689,44 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/error-ex/node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, "node_modules/es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.0.tgz", + "integrity": "sha512-GUGtW7eXQay0c+PRq0sGIKSdaBorfVqsCMhGHo4elP7YVqZu9nCZS4UkK4gv71gOWNMra/PaSKD3ao1oWExO0g==", "dev": true, "dependencies": { "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.0", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.0", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", "object-inspect": "^1.12.2", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" }, "engines": { "node": ">= 0.4" @@ -3049,11 +2735,15 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-abstract/node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/es-set-tostringtag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.0.tgz", + "integrity": "sha512-vZVAIWss0FcR/+a08s6e2/GjGjjYBCZJXDrOnj6l5kJCKhQvJs4cnVqUxkVepIhqHbKHm3uwOvPb8lRcqA3DSg==", "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" } @@ -3093,21 +2783,24 @@ } }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz", - "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", + "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -3126,7 +2819,7 @@ "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", @@ -3157,12 +2850,12 @@ } }, "node_modules/eslint-config-next": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.0.5.tgz", - "integrity": "sha512-lge94W7ME6kNCO96eCykq5GbKbllzmcDNDhh1/llMCRgNPl0+GIQ8dOoM0I7uRQVW56VmTXFybJFXgow11a5pg==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.1.1.tgz", + "integrity": "sha512-/5S2XGWlGaiqrRhzpn51ux5JUSLwx8PVK2keLi5xk7QmhfYB8PqE6R6SlVw6hgnf/VexvUXSrlNJ/su00NhtHQ==", "dev": true, "dependencies": { - "@next/eslint-plugin-next": "13.0.5", + "@next/eslint-plugin-next": "13.1.1", "@rushstack/eslint-patch": "^1.1.3", "@typescript-eslint/parser": "^5.42.0", "eslint-import-resolver-node": "^0.3.6", @@ -3201,12 +2894,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/eslint-import-resolver-typescript": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.2.tgz", @@ -3232,27 +2919,10 @@ "eslint-plugin-import": "*" } }, - "node_modules/eslint-import-resolver-typescript/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/eslint-import-resolver-typescript/node_modules/globby": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", - "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", + "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", "dev": true, "dependencies": { "dir-glob": "^3.0.1", @@ -3268,12 +2938,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-import-resolver-typescript/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/eslint-import-resolver-typescript/node_modules/slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -3312,12 +2976,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-module-utils/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/eslint-plugin-import": { "version": "2.26.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", @@ -3345,6 +3003,15 @@ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -3357,6 +3024,12 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, "node_modules/eslint-plugin-jsx-a11y": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", @@ -3384,15 +3057,6 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" } }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-plugin-react": { "version": "7.31.11", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", @@ -3463,15 +3127,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-plugin-simple-import-sort": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-8.0.0.tgz", @@ -3482,16 +3137,25 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "estraverse": "^4.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" } }, "node_modules/eslint-utils": { @@ -3545,12 +3209,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3567,39 +3225,41 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "color-name": "~1.1.4" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=7.0.0" } }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/eslint/node_modules/globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3620,24 +3280,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3667,18 +3309,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/espree/node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -3769,9 +3399,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3809,9 +3439,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -3895,9 +3525,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "funding": [ { "type": "individual", @@ -3913,6 +3543,15 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -4041,18 +3680,18 @@ } }, "node_modules/get-tsconfig": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.2.0.tgz", - "integrity": "sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.3.0.tgz", + "integrity": "sha512-YCcF28IqSay3fqpIu5y3Krg/utCBHBeoflkZyHj/QcqI2nrLPC3ZegS9CmIo+hJb8K7aiGsuUl7PwWVjNG2HQQ==", "dev": true, "funding": { "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, "node_modules/github-buttons": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.22.0.tgz", - "integrity": "sha512-N5bk01s1WgK1FVtoeSUVkRkJpkaSu8yHMPcjye+PTa0jsRjMRNrYqVLgpUf2RA5Kvec05DfHYAT6/68fwkdqPw==" + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.22.2.tgz", + "integrity": "sha512-5oBDfkizyehPc0pfa07uttIvl9QlrdwruMv18ccD/T2/tlZPMDVFxv8MOxH0Rt/gxi/756/btaKwTAlfRB69Ew==" }, "node_modules/github-from-package": { "version": "0.0.0", @@ -4099,6 +3738,21 @@ "node": ">=4" } }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globalyzer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", @@ -4131,6 +3785,18 @@ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -4157,6 +3823,26 @@ "node": ">=6.0" } }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -4197,6 +3883,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -4237,6 +3935,27 @@ "node": ">=4" } }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/hast-util-whitespace": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz", @@ -4254,6 +3973,11 @@ "react-is": "^16.7.0" } }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/html-parse-stringify": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", @@ -4277,27 +4001,6 @@ "html-tokenize": "bin/cmd.js" } }, - "node_modules/html-tokenize/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/html-tokenize/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/html-tokenize/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" - }, "node_modules/html2canvas": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", @@ -4325,9 +4028,9 @@ } }, "node_modules/i18next": { - "version": "22.4.6", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.4.6.tgz", - "integrity": "sha512-9Tm1ezxWyzV+306CIDMBbYBitC1jedQyYuuLtIv7oxjp2ohh8eyxP9xytIf+2bbQfhH784IQKPSYp+Zq9+YSbw==", + "version": "22.4.8", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.4.8.tgz", + "integrity": "sha512-XSOy17ZWqflOiJRYE/dzv6vDle2Se32dnHREHb93UnZzZ1+UnvQ8yKtt1fpNL3zvXz5AwCqqixrtTVZmRetaiQ==", "funding": [ { "type": "individual", @@ -4371,18 +4074,18 @@ ] }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/immer": { - "version": "9.0.15", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", - "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==", + "version": "9.0.17", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.17.tgz", + "integrity": "sha512-+hBruaLSQvkPfxRiTLK/mi4vLH+/VQS6z2KJahdoxlleFOI8ARqzOF17uy12eFDlqWmPoygwc5evgwcp+dlHhg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -4438,12 +4141,12 @@ "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", + "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.1.3", "has": "^1.0.3", "side-channel": "^1.0.4" }, @@ -4451,10 +4154,23 @@ "node": ">= 0.4" } }, + "node_modules/is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-TI2hnvT6dPUnn/jARFCJBKL1eeabAfLnKZ2lmW5Uh317s1Ii2IMroL1yMciEk/G+OETykVzlsH6x/L4q/avhgw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-bigint": { "version": "1.0.4", @@ -4714,6 +4430,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -4739,9 +4474,9 @@ } }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "node_modules/isexe": { "version": "2.0.0", @@ -4765,12 +4500,12 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -4810,9 +4545,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "peer": true, "bin": { "json5": "lib/cli.js" @@ -4829,6 +4564,19 @@ "debug": "^2.1.3" } }, + "node_modules/jsonp/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/jsonp/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/jspdf": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz", @@ -4903,12 +4651,12 @@ "dev": true }, "node_modules/language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.7.tgz", + "integrity": "sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw==", "dev": true, "dependencies": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" } }, "node_modules/levn": { @@ -5001,14 +4749,12 @@ } }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "peer": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/markdown-it": { @@ -5026,11 +4772,6 @@ "markdown-it": "bin/markdown-it.js" } }, - "node_modules/markdown-it/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -5079,16 +4820,14 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "12.2.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.2.2.tgz", - "integrity": "sha512-lVkUttV9wqmdXFtEBXKcepvU/zfwbhjbkM5rxrquLW55dS1DfOrnAXCk5mg1be1sfY/WfMmayGy1NsbK1GLCYQ==", + "version": "12.2.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.2.5.tgz", + "integrity": "sha512-EFNhT35ZR/VZ85/EedDdCNTq0oFM+NM/+qBomVGQ0+Lcg0nhI8xIwmdCzNMlVlCJNXRprpobtKP/IUh8cfz6zQ==", "dependencies": { "@types/hast": "^2.0.0", "@types/mdast": "^3.0.0", - "@types/mdurl": "^1.0.0", "mdast-util-definitions": "^5.0.0", - "mdurl": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-sanitize-uri": "^1.1.0", "trim-lines": "^3.0.0", "unist-builder": "^3.0.0", "unist-util-generated": "^2.0.0", @@ -5129,9 +4868,9 @@ } }, "node_modules/micromark": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.0.10.tgz", - "integrity": "sha512-ryTDy6UUunOXy2HPjelppgJ2sNfcPz1pLlMdA6Rz9jPzhLikWXv/irpWV/I2jd68Uhmny7hHxAlAhk4+vWggpg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz", + "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==", "funding": [ { "type": "GitHub Sponsors", @@ -5480,9 +5219,9 @@ } }, "node_modules/micromark-util-sanitize-uri": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz", - "integrity": "sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz", + "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==", "funding": [ { "type": "GitHub Sponsors", @@ -5550,27 +5289,6 @@ } ] }, - "node_modules/micromark/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/micromark/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -5627,9 +5345,12 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/mkdirp-classic": { "version": "0.5.3", @@ -5645,9 +5366,9 @@ } }, "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/multipipe": { "version": "1.0.2", @@ -5739,9 +5460,9 @@ } }, "node_modules/next-i18next": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/next-i18next/-/next-i18next-13.0.2.tgz", - "integrity": "sha512-aUHyKT2kztMgEP44zDB5KoW8XZUQawIdOYWXcrMH6lxAcS0kBsKX0uKMzGS5XlgLW88gvOVc3D7NdfCznLgyyg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/next-i18next/-/next-i18next-13.0.3.tgz", + "integrity": "sha512-7AA8J6WbkxRBtSf1+97LSAE7btxWZHsBIJEJ3FuTSBgYtpRiO5NGjcb8XbNAlz6yGU0TtS+yZE+/Wu83KhIT1Q==", "funding": [ { "type": "individual", @@ -5777,6 +5498,29 @@ "react-i18next": "^12.1.1" } }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/node-abi": { "version": "3.30.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.30.0.tgz", @@ -5788,15 +5532,45 @@ "node": ">=10" } }, + "node_modules/node-abi/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/node-addon-api": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -5843,9 +5617,13 @@ } }, "node_modules/object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } }, "node_modules/object.assign": { "version": "4.1.4", @@ -5865,15 +5643,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.assign/node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/object.entries": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", @@ -6107,9 +5876,10 @@ } }, "node_modules/postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "version": "8.4.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", + "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "dev": true, "funding": [ { "type": "opencollective", @@ -6195,12 +5965,12 @@ } }, "node_modules/postcss-nested": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", - "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.6" + "postcss-selector-parser": "^6.0.10" }, "engines": { "node": ">=12.0" @@ -6232,11 +6002,11 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/posthog-js": { - "version": "1.34.0", - "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.34.0.tgz", - "integrity": "sha512-HkRwwzdz31N5ykQIO3SIkSS8nwhdqqnuDZ/qltitX4FhxrV9/tSRavEXz0YLvioOXeNVmQWtsN3krKajErwkwg==", + "version": "1.39.1", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.39.1.tgz", + "integrity": "sha512-ZbLs0iSv4nCdcY9cy85lejCQtTh8JmXVzSegCVJweRCmGf4lFEJSsfrezm1j7kww4yCn0dFdVr0A245MIfsZuw==", "dependencies": { - "@sentry/types": "^7.2.0", + "@sentry/types": "7.22.0", "fflate": "^0.4.1", "rrweb-snapshot": "^1.1.14" } @@ -6290,10 +6060,15 @@ "react-is": "^16.13.1" } }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/property-information": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.1.1.tgz", - "integrity": "sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz", + "integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -6446,9 +6221,9 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "node_modules/react-beautiful-dnd/node_modules/react-redux": { - "version": "7.2.8", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.8.tgz", - "integrity": "sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==", + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", + "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", "dependencies": { "@babel/runtime": "^7.15.4", "@types/react-redux": "^7.1.20", @@ -6594,9 +6369,9 @@ } }, "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/react-mailchimp-subscribe": { "version": "2.1.3", @@ -6612,9 +6387,9 @@ } }, "node_modules/react-markdown": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.3.tgz", - "integrity": "sha512-We36SfqaKoVNpN1QqsZwWSv/OZt5J15LNgTLWynwAN5b265hrQrsjMtlRNwUvS+YyR3yDM8HpTNc4pK9H/Gc0A==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.4.tgz", + "integrity": "sha512-2oxHa6oDxc1apg/Gnc1Goh06t3B617xeywqI/92wmDV9FELI6ayRkwge7w7DoEqM0gRpZGTNU6xQG+YpJISnVg==", "dependencies": { "@types/hast": "^2.0.0", "@types/prop-types": "^15.0.0", @@ -6641,15 +6416,10 @@ "react": ">=16" } }, - "node_modules/react-markdown/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - }, "node_modules/react-redux": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.2.tgz", - "integrity": "sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", + "integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==", "dependencies": { "@babel/runtime": "^7.12.1", "@types/hoist-non-react-statics": "^3.3.1", @@ -6684,11 +6454,6 @@ } } }, - "node_modules/react-redux/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - }, "node_modules/react-resizable": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-3.0.4.tgz", @@ -6723,16 +6488,14 @@ } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, "node_modules/readdirp": { @@ -6756,9 +6519,9 @@ } }, "node_modules/redux-thunk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", - "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", "peerDependencies": { "redux": "^4" } @@ -6832,9 +6595,9 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/reselect": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.6.tgz", - "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==" + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz", + "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==" }, "node_modules/resolve": { "version": "1.22.1", @@ -6997,17 +6760,11 @@ } }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, "node_modules/set-cookie-parser": { @@ -7033,9 +6790,9 @@ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, "node_modules/sharp": { - "version": "0.31.2", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.2.tgz", - "integrity": "sha512-DUdNVEXgS5A97cTagSLIIp8dUZ/lZtk78iNVZgHdHbx1qnQR7JAHY0BnXnwwH39Iw+VKhO08CTYhIg0p98vQ5Q==", + "version": "0.31.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", + "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", "hasInstallScript": true, "dependencies": { "color": "^4.2.3", @@ -7054,6 +6811,36 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/sharp/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -7140,6 +6927,11 @@ "is-arrayish": "^0.3.1" } }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -7166,9 +6958,9 @@ } }, "node_modules/space-separated-tokens": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", - "integrity": "sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -7205,12 +6997,9 @@ } }, "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, "node_modules/string.prototype.matchall": { "version": "4.0.8", @@ -7309,9 +7098,9 @@ } }, "node_modules/styled-components": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.5.tgz", - "integrity": "sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg==", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz", + "integrity": "sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==", "hasInstallScript": true, "dependencies": { "@babel/helper-module-imports": "^7.0.0", @@ -7338,6 +7127,11 @@ "react-is": ">= 16.8.0" } }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, "node_modules/styled-jsx": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.7.tgz", @@ -7358,9 +7152,9 @@ } }, "node_modules/stylis": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" }, "node_modules/supports-color": { "version": "5.5.0", @@ -7410,9 +7204,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.7.tgz", - "integrity": "sha512-r7mgumZ3k0InfVPpGWcX8X/Ut4xBfv+1O/+C73ar/m01LxGVzWvPxF/w6xIUPEztrCoz7axfx0SMdh8FH8ZvRQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", + "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", "dev": true, "dependencies": { "arg": "^5.0.2", @@ -7421,18 +7215,19 @@ "detective": "^5.2.1", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.2.11", + "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.14", + "postcss": "^8.4.18", "postcss-import": "^14.1.0", "postcss-js": "^4.0.0", "postcss-load-config": "^3.1.4", - "postcss-nested": "5.0.6", + "postcss-nested": "6.0.0", "postcss-selector-parser": "^6.0.10", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", @@ -7449,6 +7244,12 @@ "postcss": "^8.0.9" } }, + "node_modules/tailwindcss/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -7484,6 +7285,27 @@ "node": ">=6" } }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/text-segmentation": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", @@ -7513,26 +7335,10 @@ "xtend": "~2.1.1" } }, - "node_modules/through2/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "node_modules/through2/node_modules/object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==" }, "node_modules/through2/node_modules/xtend": { "version": "2.1.2", @@ -7556,9 +7362,9 @@ } }, "node_modules/tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -7616,9 +7422,9 @@ } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -7628,9 +7434,9 @@ } }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -7706,10 +7512,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -7839,9 +7659,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", - "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "funding": [ { "type": "opencollective", @@ -7937,9 +7757,9 @@ } }, "node_modules/vfile": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.5.tgz", - "integrity": "sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.6.tgz", + "integrity": "sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA==", "dependencies": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -7952,9 +7772,9 @@ } }, "node_modules/vfile-message": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", - "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.3.tgz", + "integrity": "sha512-0yaU+rj2gKAyEk12ffdSbBfjnnj+b1zqTBv3OQCTn8yEB02bsPizwdBPrLJjHnK+cU9EMMcUnNv938XcZIkmdA==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^3.0.0" @@ -8003,6 +7823,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -8027,9 +7867,10 @@ } }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "peer": true }, "node_modules/yaml": { "version": "1.10.2", @@ -8061,18 +7902,6 @@ "requires": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "peer": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } } }, "@babel/code-frame": { @@ -8084,65 +7913,54 @@ } }, "@babel/compat-data": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", "peer": true }, "@babel/core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", - "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "peer": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.5", - "@babel/parser": "^7.20.5", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "peer": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "peer": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "peer": true - } } }, "@babel/generator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", - "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "requires": { - "@babel/types": "^7.20.5", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } } }, "@babel/helper-annotate-as-pure": { @@ -8154,23 +7972,16 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "peer": true, "requires": { - "@babel/compat-data": "^7.20.0", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "peer": true - } } }, "@babel/helper-environment-visitor": { @@ -8204,9 +8015,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "peer": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", @@ -8214,15 +8025,15 @@ "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" } }, "@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==" + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" }, "@babel/helper-simple-access": { "version": "7.20.2", @@ -8258,14 +8069,14 @@ "peer": true }, "@babel/helpers": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", - "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", + "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", "peer": true, "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/highlight": { @@ -8279,9 +8090,9 @@ } }, "@babel/parser": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", - "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==" }, "@babel/plugin-syntax-jsx": { "version": "7.18.6", @@ -8300,61 +8111,46 @@ } }, "@babel/runtime-corejs3": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.1.tgz", - "integrity": "sha512-CGulbEDcg/ND1Im7fUNRZdGXmX2MTWVVZacQi/6DiKE5HNwZ3aVTm5PV4lO8HHz0B2h8WQyvKKjbX5XgTtydsg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.7.tgz", + "integrity": "sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg==", "dev": true, "requires": { "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.10" + "regenerator-runtime": "^0.13.11" } }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "requires": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", - "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz", + "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==", "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.5", - "@babel/types": "^7.20.5", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "@babel/types": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", - "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "requires": { "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", @@ -8362,64 +8158,45 @@ } }, "@emotion/babel-plugin": { - "version": "11.10.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", - "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", + "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", "requires": { "@babel/helper-module-imports": "^7.16.7", "@babel/plugin-syntax-jsx": "^7.17.12", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.0", + "@emotion/serialize": "^1.1.1", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.0.13" - }, - "dependencies": { - "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - } + "stylis": "4.1.3" } }, "@emotion/cache": { - "version": "11.10.3", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", - "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", "requires": { "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.0", + "@emotion/sheet": "^1.2.1", "@emotion/utils": "^1.2.0", "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.0.13" - }, - "dependencies": { - "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - } + "stylis": "4.1.3" } }, "@emotion/css": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/@emotion/css/-/css-11.10.0.tgz", - "integrity": "sha512-dH9f+kSCucc8ilMg0MUA1AemabcyzYpe5EKX24F528PJjD7HyIY/VBNJHxfUdc8l400h2ncAjR6yEDu+DBj2cg==", + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/css/-/css-11.10.5.tgz", + "integrity": "sha512-maJy0wG82hWsiwfJpc3WrYsyVwUbdu+sdIseKUB+/OLjB8zgc3tqkT6eO0Yt0AhIkJwGGnmMY/xmQwEAgQ4JHA==", "requires": { - "@emotion/babel-plugin": "^11.10.0", - "@emotion/cache": "^11.10.0", - "@emotion/serialize": "^1.1.0", - "@emotion/sheet": "^1.2.0", + "@emotion/babel-plugin": "^11.10.5", + "@emotion/cache": "^11.10.5", + "@emotion/serialize": "^1.1.1", + "@emotion/sheet": "^1.2.1", "@emotion/utils": "^1.2.0" } }, @@ -8429,40 +8206,28 @@ "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" }, "@emotion/is-prop-valid": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.3.tgz", - "integrity": "sha512-RFg04p6C+1uO19uG8N+vqanzKqiM9eeV1LDOG3bmkYmuOj7NbKNlFC/4EZq5gnwAIlcC/jOT24f8Td0iax2SXA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", "requires": { - "@emotion/memoize": "^0.7.4" + "@emotion/memoize": "^0.8.0" } }, "@emotion/memoize": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", - "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "@emotion/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", "requires": { "@emotion/hash": "^0.9.0", "@emotion/memoize": "^0.8.0", "@emotion/unitless": "^0.8.0", "@emotion/utils": "^1.2.0", "csstype": "^3.0.2" - }, - "dependencies": { - "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "@emotion/unitless": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" - } } }, "@emotion/server": { @@ -8477,9 +8242,9 @@ } }, "@emotion/sheet": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", - "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", + "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" }, "@emotion/stylis": { "version": "0.8.5", @@ -8487,9 +8252,9 @@ "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" }, "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, "@emotion/utils": { "version": "1.2.0", @@ -8502,15 +8267,15 @@ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" }, "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -8518,82 +8283,52 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "requires": { "type-fest": "^0.20.2" } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } } }, "@fortawesome/fontawesome-common-types": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.2.tgz", - "integrity": "sha512-wBaAPGz1Awxg05e0PBRkDRuTsy4B3dpBm+zreTTyd9TH4uUM27cAL4xWyWR0rLJCrRwzVsQ4hF3FvM6rqydKPA==" + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", + "integrity": "sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==" }, "@fortawesome/fontawesome-svg-core": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.2.tgz", - "integrity": "sha512-853G/Htp0BOdXnPoeCPTjFrVwyrJHpe8MhjB/DYE9XjwhnNDfuBCd3aKc2YUYbEfHEcBws4UAA0kA9dymZKGjA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz", + "integrity": "sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==", "requires": { - "@fortawesome/fontawesome-common-types": "6.1.2" + "@fortawesome/fontawesome-common-types": "6.2.1" } }, "@fortawesome/free-brands-svg-icons": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.1.2.tgz", - "integrity": "sha512-b2eMfXQBsSxh52pcPtYchURQs6BWNh3zVTG8XH8Lv6V4kDhEg7D0kHN+K1SZniDiPb/e5tBlaygsinMUvetITA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.1.tgz", + "integrity": "sha512-L8l4MfdHPmZlJ72PvzdfwOwbwcCAL0vx48tJRnI6u1PJXh+j2f3yDoKyQgO3qjEsgD5Fr2tQV/cPP8F/k6aUig==", "requires": { - "@fortawesome/fontawesome-common-types": "6.1.2" + "@fortawesome/fontawesome-common-types": "6.2.1" } }, "@fortawesome/free-regular-svg-icons": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.1.2.tgz", - "integrity": "sha512-xR4hA+tAwsaTHGfb+25H1gVU/aJ0Rzu+xIUfnyrhaL13yNQ7TWiI2RvzniAaB+VGHDU2a+Pk96Ve+pkN3/+TTQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.1.tgz", + "integrity": "sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA==", "requires": { - "@fortawesome/fontawesome-common-types": "6.1.2" + "@fortawesome/fontawesome-common-types": "6.2.1" } }, "@fortawesome/free-solid-svg-icons": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.2.tgz", - "integrity": "sha512-lTgZz+cMpzjkHmCwOG3E1ilUZrnINYdqMmrkv30EC3XbRsGlbIOL8H9LaNp5SV4g0pNJDfQ4EdTWWaMvdwyLiQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.1.tgz", + "integrity": "sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw==", "requires": { - "@fortawesome/fontawesome-common-types": "6.1.2" + "@fortawesome/fontawesome-common-types": "6.2.1" } }, "@fortawesome/react-fontawesome": { @@ -8605,37 +8340,22 @@ } }, "@headlessui/react": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.6.6.tgz", - "integrity": "sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q==", - "requires": {} + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.7.tgz", + "integrity": "sha512-BqDOd/tB9u2tA0T3Z0fn18ktw+KbVwMnkxxsGPIH2hzssrQhKB5n/6StZOyvLYP/FsYtvuXfi9I0YowKPv2c1w==", + "requires": { + "client-only": "^0.0.1" + } }, "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", "minimatch": "^3.0.5" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "@humanwhocodes/module-importer": { @@ -8651,13 +8371,13 @@ "dev": true }, "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "peer": true, "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, "@jridgewell/resolve-uri": { @@ -8676,12 +8396,12 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", - "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@next/env": { @@ -8690,9 +8410,9 @@ "integrity": "sha512-H/69Lc5Q02dq3o+dxxy5O/oNxFsZpdL6WREtOOtOM1B/weonIwDXkekr1KV5DPVPr12IHFPrMrcJQ6bgPMfn7A==" }, "@next/eslint-plugin-next": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.0.5.tgz", - "integrity": "sha512-H9U9B1dFnCDmylDZ6/dYt95Ie1Iu+SLBMcO6rkIGIDcj5UK+DNyMiWm83xWBZ1gREM8cfp5Srv1g6wqf8pM4lw==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.1.1.tgz", + "integrity": "sha512-SBrOFS8PC3nQ5aeZmawJkjKkWjwK9RoxvBSv/86nZp0ubdoVQoko8r8htALd9ufp16NhacCdqhu9bzZLDWtALQ==", "dev": true, "requires": { "glob": "7.1.7" @@ -8817,14 +8537,14 @@ } }, "@reduxjs/toolkit": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.8.3.tgz", - "integrity": "sha512-lU/LDIfORmjBbyDLaqFN2JB9YmAT1BElET9y0ZszwhSBa5Ef3t6o5CrHupw5J1iOXwd+o92QfQZ8OJpwXvsssg==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.1.tgz", + "integrity": "sha512-HikrdY+IDgRfRYlCTGUQaiCxxDDgM1mQrRbZ6S1HFZX5ZYuJ4o8EstNmhTwHdPl2rTmLxzwSu0b3AyeyTlR+RA==", "requires": { - "immer": "^9.0.7", - "redux": "^4.1.2", - "redux-thunk": "^2.4.1", - "reselect": "^4.1.5" + "immer": "^9.0.16", + "redux": "^4.2.0", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.7" } }, "@rushstack/eslint-patch": { @@ -8834,22 +8554,22 @@ "dev": true }, "@sentry/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.15.0.tgz", - "integrity": "sha512-MN9haDRh9ZOsTotoDTHu2BT3sT8Vs1F0alhizUpDyjN2YgBCqR6JV+AbAE1XNHwS2+5zbppch1PwJUVeE58URQ==" + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.22.0.tgz", + "integrity": "sha512-LhCL+wb1Jch+OesB2CIt6xpfO1Ab6CRvoNYRRzVumWPLns1T3ZJkarYfhbLaOEIb38EIbPgREdxn2AJT560U4Q==" }, "@stripe/react-stripe-js": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-1.10.0.tgz", - "integrity": "sha512-vuIjJUZJ3nyiaGa5z5iyMCzZfGGsgzOOjWjqknbbhkNsewyyginfeky9EZLSz9+iSAsgC9K6MeNOTLKVGcMycQ==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-1.16.2.tgz", + "integrity": "sha512-RTL3rE6eNosRb2AhxHBWN0HQgigSo/cfZu8vPAqB9/dZEAjYcEoiDYtjI9Zj1MAh58c5RyQNn3HU3M4hIqUdAg==", "requires": { "prop-types": "^15.7.2" } }, "@stripe/stripe-js": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.36.0.tgz", - "integrity": "sha512-m45BD9JxOfIBT0Tz4MupiKzM8M58NX/We8wKlf+54TCZpW1RVAyFpJ58CbtyU/LxAM+opT6cewHRVfs7bTUtBA==" + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.46.0.tgz", + "integrity": "sha512-dkm0zCEoRLu5rTnsIgwDf/QG2DKcalOT2dk1IVgMySOHWTChLyOvQwMYhEduGgLvyYWTwNhAUV4WOLPQvjwLwA==" }, "@swc/helpers": { "version": "0.4.11", @@ -8860,9 +8580,9 @@ } }, "@tailwindcss/typography": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.7.tgz", - "integrity": "sha512-JTTSTrgZfp6Ki4svhPA4mkd9nmQ/j9EfE7SbHJ1cLtthKkpW2OxsFXzSmxbhYbEkfNIyAyhle5p4SYyKRbz/jg==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.8.tgz", + "integrity": "sha512-xGQEp8KXN8Sd8m6R4xYmwxghmswrd0cPnNI2Lc6fmrC3OojysTBJJGSIVwPV56q4t6THFUK3HJ0EaWwpglSxWw==", "dev": true, "requires": { "lodash.castarray": "^4.4.0", @@ -8916,11 +8636,6 @@ "@types/unist": "*" } }, - "@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" - }, "@types/ms": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", @@ -8959,9 +8674,9 @@ } }, "@types/react-redux": { - "version": "7.1.24", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz", - "integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==", + "version": "7.1.25", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz", + "integrity": "sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg==", "requires": { "@types/hoist-non-react-statics": "^3.3.0", "@types/react": "*", @@ -8996,14 +8711,14 @@ "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" }, "@typescript-eslint/eslint-plugin": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", - "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.0.tgz", + "integrity": "sha512-SVLafp0NXpoJY7ut6VFVUU9I+YeFsDzeQwtK0WZ+xbRN3mtxJ08je+6Oi2N89qDn087COdO0u3blKZNv9VetRQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/type-utils": "5.47.1", - "@typescript-eslint/utils": "5.47.1", + "@typescript-eslint/scope-manager": "5.48.0", + "@typescript-eslint/type-utils": "5.48.0", + "@typescript-eslint/utils": "5.48.0", "debug": "^4.3.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", @@ -9012,162 +8727,80 @@ "tsutils": "^3.21.0" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" + "yallist": "^4.0.0" } }, - "@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" + "lru-cache": "^6.0.0" } }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "@typescript-eslint/parser": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.0.tgz", - "integrity": "sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.0.tgz", + "integrity": "sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.45.0", - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/typescript-estree": "5.45.0", + "@typescript-eslint/scope-manager": "5.48.0", + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/typescript-estree": "5.48.0", "debug": "^4.3.4" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "@typescript-eslint/scope-manager": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz", - "integrity": "sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz", + "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==", "dev": true, "requires": { - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/visitor-keys": "5.45.0" + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/visitor-keys": "5.48.0" } }, "@typescript-eslint/type-utils": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", - "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.0.tgz", + "integrity": "sha512-vbtPO5sJyFjtHkGlGK4Sthmta0Bbls4Onv0bEqOGm7hP9h8UpRsHJwsrCiWtCUndTRNQO/qe6Ijz9rnT/DB+7g==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.47.1", - "@typescript-eslint/utils": "5.47.1", + "@typescript-eslint/typescript-estree": "5.48.0", + "@typescript-eslint/utils": "5.48.0", "debug": "^4.3.4", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", - "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "@typescript-eslint/types": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.0.tgz", - "integrity": "sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz", + "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz", - "integrity": "sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz", + "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.45.0", - "@typescript-eslint/visitor-keys": "5.45.0", + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/visitor-keys": "5.48.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9175,127 +8808,88 @@ "tsutils": "^3.21.0" }, "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "ms": "2.1.2" + "yallist": "^4.0.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "@typescript-eslint/utils": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.1.tgz", - "integrity": "sha512-l90SdwqfmkuIVaREZ2ykEfCezepCLxzWMo5gVfcJsJCaT4jHT+QjgSkYhs5BMQmWqE9k3AtIfk4g211z/sTMVw==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.0.tgz", + "integrity": "sha512-x2jrMcPaMfsHRRIkL+x96++xdzvrdBCnYRd5QiW5Wgo1OB4kDYPbC1XjWP/TNqlfK93K/lUL92erq5zPLgFScQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/typescript-estree": "5.47.1", + "@typescript-eslint/scope-manager": "5.48.0", + "@typescript-eslint/types": "5.48.0", + "@typescript-eslint/typescript-estree": "5.48.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" + "yallist": "^4.0.0" } }, - "@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", - "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "lru-cache": "^6.0.0" } }, - "@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "@typescript-eslint/visitor-keys": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz", - "integrity": "sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==", + "version": "5.48.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz", + "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/types": "5.48.0", "eslint-visitor-keys": "^3.3.0" } }, "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true }, "acorn-jsx": { @@ -9314,6 +8908,14 @@ "acorn": "^7.0.0", "acorn-walk": "^7.0.0", "xtend": "^4.0.2" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } } }, "acorn-walk": { @@ -9351,27 +8953,12 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { "color-convert": "^1.9.0" - }, - "dependencies": { - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - } } }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -9385,12 +8972,9 @@ "dev": true }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "aria-query": { "version": "4.2.2", @@ -9475,23 +9059,29 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "autoprefixer": { - "version": "10.4.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz", - "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==", + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", "dev": true, "requires": { - "browserslist": "^4.21.3", - "caniuse-lite": "^1.0.30001373", + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" } }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, "axe-core": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", - "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.2.tgz", + "integrity": "sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==", "dev": true }, "axios": { @@ -9504,9 +9094,9 @@ } }, "axios-auth-refresh": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/axios-auth-refresh/-/axios-auth-refresh-3.3.3.tgz", - "integrity": "sha512-2IbDhJ/h6ddNBBnnzn1VFK/qx17pE9aVqiafB8rx5LVHsJ1HtFpUGkbXY7PzTG+8P9HJWcyA3fNZl9BikSuilg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/axios-auth-refresh/-/axios-auth-refresh-3.3.4.tgz", + "integrity": "sha512-cGq3bZu+lip5j+byaQRZaZ3wpCUxs93jGV0614VYP5k2H1vbdoaw6HGazaUJxcRsFMctR3DItCAx1Dn7KerlcA==", "requires": {} }, "axobject-query": { @@ -9578,6 +9168,26 @@ "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } } }, "brace-expansion": { @@ -9600,14 +9210,14 @@ } }, "browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "requires": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "update-browserslist-db": "^1.0.9" } }, "btoa": { @@ -9651,14 +9261,14 @@ "dev": true }, "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" }, "caniuse-lite": { - "version": "1.0.30001418", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", - "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==" + "version": "1.0.30001442", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz", + "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==" }, "canvg": { "version": "3.0.10", @@ -9684,6 +9294,13 @@ "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + } } }, "character-entities": { @@ -9733,9 +9350,14 @@ } }, "classnames": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", - "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, + "client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, "clsx": { "version": "1.2.1", @@ -9749,20 +9371,35 @@ "requires": { "color-convert": "^2.0.1", "color-string": "^1.9.0" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } } }, "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "requires": { - "color-name": "~1.1.4" + "color-name": "1.1.3" } }, "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "color-string": { "version": "1.9.1", @@ -9782,9 +9419,9 @@ } }, "comma-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", - "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==" }, "concat-map": { "version": "0.0.1", @@ -9793,19 +9430,9 @@ "dev": true }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "cookies": { "version": "0.8.0", @@ -9817,14 +9444,14 @@ } }, "core-js": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", - "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==" + "version": "3.27.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz", + "integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==" }, "core-js-pure": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", - "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==", + "version": "3.27.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.27.1.tgz", + "integrity": "sha512-BS2NHgwwUppfeoqOXqi08mUqS5FiZpuRuJJpKsaME7kJz0xxuk0xkhDdfMIlP/zLa80krBqss1LtD7f889heAw==", "dev": true }, "core-util-is": { @@ -9833,9 +9460,9 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -9906,9 +9533,9 @@ "dev": true }, "csstype": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", - "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "damerau-levenshtein": { "version": "1.0.8", @@ -9917,11 +9544,11 @@ "dev": true }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } }, "decode-named-character-reference": { @@ -9970,20 +9597,12 @@ "requires": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" - }, - "dependencies": { - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - } } }, "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", "dev": true }, "delayed-stream": { @@ -10066,6 +9685,11 @@ "readable-stream": "^2.0.2" }, "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -10096,9 +9720,9 @@ } }, "electron-to-chromium": { - "version": "1.4.206", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz", - "integrity": "sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA==" + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "emoji-regex": { "version": "9.2.2", @@ -10135,53 +9759,56 @@ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "requires": { "is-arrayish": "^0.2.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - } } }, "es-abstract": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", - "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.0.tgz", + "integrity": "sha512-GUGtW7eXQay0c+PRq0sGIKSdaBorfVqsCMhGHo4elP7YVqZu9nCZS4UkK4gv71gOWNMra/PaSKD3ao1oWExO0g==", "dev": true, "requires": { "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.0", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.0", "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", "object-inspect": "^1.12.2", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" - }, - "dependencies": { - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - } + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + } + }, + "es-set-tostringtag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.0.tgz", + "integrity": "sha512-vZVAIWss0FcR/+a08s6e2/GjGjjYBCZJXDrOnj6l5kJCKhQvJs4cnVqUxkVepIhqHbKHm3uwOvPb8lRcqA3DSg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3", + "has-tostringtag": "^1.0.0" } }, "es-shim-unscopables": { @@ -10210,18 +9837,18 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "eslint": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz", - "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==", + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", + "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", @@ -10240,7 +9867,7 @@ "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", @@ -10270,12 +9897,6 @@ "color-convert": "^2.0.1" } }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -10286,25 +9907,35 @@ "supports-color": "^7.1.0" } }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "ms": "2.1.2" + "color-name": "~1.1.4" } }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, "globals": { - "version": "13.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", - "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -10316,21 +9947,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10343,12 +9959,12 @@ } }, "eslint-config-next": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.0.5.tgz", - "integrity": "sha512-lge94W7ME6kNCO96eCykq5GbKbllzmcDNDhh1/llMCRgNPl0+GIQ8dOoM0I7uRQVW56VmTXFybJFXgow11a5pg==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.1.1.tgz", + "integrity": "sha512-/5S2XGWlGaiqrRhzpn51ux5JUSLwx8PVK2keLi5xk7QmhfYB8PqE6R6SlVw6hgnf/VexvUXSrlNJ/su00NhtHQ==", "dev": true, "requires": { - "@next/eslint-plugin-next": "13.0.5", + "@next/eslint-plugin-next": "13.1.1", "@rushstack/eslint-patch": "^1.1.3", "@typescript-eslint/parser": "^5.42.0", "eslint-import-resolver-node": "^0.3.6", @@ -10377,12 +9993,6 @@ "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true } } }, @@ -10401,19 +10011,10 @@ "synckit": "^0.8.4" }, "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "globby": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", - "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "version": "13.1.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz", + "integrity": "sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==", "dev": true, "requires": { "dir-glob": "^3.0.1", @@ -10423,12 +10024,6 @@ "slash": "^4.0.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -10454,12 +10049,6 @@ "requires": { "ms": "^2.1.1" } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true } } }, @@ -10484,6 +10073,15 @@ "tsconfig-paths": "^3.14.1" }, "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -10492,6 +10090,12 @@ "requires": { "esutils": "^2.0.2" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true } } }, @@ -10514,14 +10118,6 @@ "language-tags": "^1.0.5", "minimatch": "^3.1.2", "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } } }, "eslint-plugin-react": { @@ -10566,12 +10162,6 @@ "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true } } }, @@ -10590,13 +10180,21 @@ "requires": {} }, "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } } }, "eslint-utils": { @@ -10631,14 +10229,6 @@ "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true - } } }, "esprima": { @@ -10706,9 +10296,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -10742,9 +10332,9 @@ "dev": true }, "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -10810,9 +10400,18 @@ "dev": true }, "follow-redirects": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", - "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==" + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } }, "form-data": { "version": "4.0.0", @@ -10904,15 +10503,15 @@ } }, "get-tsconfig": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.2.0.tgz", - "integrity": "sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.3.0.tgz", + "integrity": "sha512-YCcF28IqSay3fqpIu5y3Krg/utCBHBeoflkZyHj/QcqI2nrLPC3ZegS9CmIo+hJb8K7aiGsuUl7PwWVjNG2HQQ==", "dev": true }, "github-buttons": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.22.0.tgz", - "integrity": "sha512-N5bk01s1WgK1FVtoeSUVkRkJpkaSu8yHMPcjye+PTa0jsRjMRNrYqVLgpUf2RA5Kvec05DfHYAT6/68fwkdqPw==" + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.22.2.tgz", + "integrity": "sha512-5oBDfkizyehPc0pfa07uttIvl9QlrdwruMv18ccD/T2/tlZPMDVFxv8MOxH0Rt/gxi/756/btaKwTAlfRB69Ew==" }, "github-from-package": { "version": "0.0.0", @@ -10947,6 +10546,15 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, "globalyzer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", @@ -10973,6 +10581,15 @@ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -10994,6 +10611,25 @@ "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } } }, "has": { @@ -11024,6 +10660,12 @@ "get-intrinsic": "^1.1.1" } }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -11047,6 +10689,26 @@ "inherits": "^2.0.4", "readable-stream": "^3.6.0", "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } } }, "hast-util-whitespace": { @@ -11060,6 +10722,13 @@ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "requires": { "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } } }, "html-parse-stringify": { @@ -11080,29 +10749,6 @@ "minimist": "~1.2.5", "readable-stream": "~1.0.27-1", "through2": "~0.4.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" - } } }, "html2canvas": { @@ -11126,9 +10772,9 @@ } }, "i18next": { - "version": "22.4.6", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.4.6.tgz", - "integrity": "sha512-9Tm1ezxWyzV+306CIDMBbYBitC1jedQyYuuLtIv7oxjp2ohh8eyxP9xytIf+2bbQfhH784IQKPSYp+Zq9+YSbw==", + "version": "22.4.8", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.4.8.tgz", + "integrity": "sha512-XSOy17ZWqflOiJRYE/dzv6vDle2Se32dnHREHb93UnZzZ1+UnvQ8yKtt1fpNL3zvXz5AwCqqixrtTVZmRetaiQ==", "requires": { "@babel/runtime": "^7.20.6" } @@ -11144,15 +10790,15 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "immer": { - "version": "9.0.15", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", - "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==" + "version": "9.0.17", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.17.tgz", + "integrity": "sha512-+hBruaLSQvkPfxRiTLK/mi4vLH+/VQS6z2KJahdoxlleFOI8ARqzOF17uy12eFDlqWmPoygwc5evgwcp+dlHhg==" }, "import-fresh": { "version": "3.3.0", @@ -11195,20 +10841,30 @@ "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", + "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", "dev": true, "requires": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.1.3", "has": "^1.0.3", "side-channel": "^1.0.4" } }, + "is-array-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.0.tgz", + "integrity": "sha512-TI2hnvT6dPUnn/jARFCJBKL1eeabAfLnKZ2lmW5Uh317s1Ii2IMroL1yMciEk/G+OETykVzlsH6x/L4q/avhgw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3" + } + }, "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-bigint": { "version": "1.0.4", @@ -11361,6 +11017,19 @@ "has-symbols": "^1.0.2" } }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -11380,9 +11049,9 @@ } }, "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "isexe": { "version": "2.0.0", @@ -11402,12 +11071,12 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "jsbn": { @@ -11438,9 +11107,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "peer": true }, "jsonp": { @@ -11449,6 +11118,21 @@ "integrity": "sha512-pfog5gdDxPdV4eP7Kg87M8/bHgshlZ5pybl+yKxAnCZ5O7lCIn7Ixydj03wOlnDQesky2BPyA91SQ+5Y/mNwzw==", "requires": { "debug": "^2.1.3" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } } }, "jspdf": { @@ -11511,12 +11195,12 @@ "dev": true }, "language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.7.tgz", + "integrity": "sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw==", "dev": true, "requires": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" } }, "levn": { @@ -11594,11 +11278,12 @@ } }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "peer": true, "requires": { - "yallist": "^4.0.0" + "yallist": "^3.0.2" } }, "markdown-it": { @@ -11611,13 +11296,6 @@ "linkify-it": "^4.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - } } }, "md5.js": { @@ -11660,16 +11338,14 @@ } }, "mdast-util-to-hast": { - "version": "12.2.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.2.2.tgz", - "integrity": "sha512-lVkUttV9wqmdXFtEBXKcepvU/zfwbhjbkM5rxrquLW55dS1DfOrnAXCk5mg1be1sfY/WfMmayGy1NsbK1GLCYQ==", + "version": "12.2.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.2.5.tgz", + "integrity": "sha512-EFNhT35ZR/VZ85/EedDdCNTq0oFM+NM/+qBomVGQ0+Lcg0nhI8xIwmdCzNMlVlCJNXRprpobtKP/IUh8cfz6zQ==", "requires": { "@types/hast": "^2.0.0", "@types/mdast": "^3.0.0", - "@types/mdurl": "^1.0.0", "mdast-util-definitions": "^5.0.0", - "mdurl": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-sanitize-uri": "^1.1.0", "trim-lines": "^3.0.0", "unist-builder": "^3.0.0", "unist-util-generated": "^2.0.0", @@ -11699,9 +11375,9 @@ "dev": true }, "micromark": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.0.10.tgz", - "integrity": "sha512-ryTDy6UUunOXy2HPjelppgJ2sNfcPz1pLlMdA6Rz9jPzhLikWXv/irpWV/I2jd68Uhmny7hHxAlAhk4+vWggpg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz", + "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==", "requires": { "@types/debug": "^4.0.0", "debug": "^4.0.0", @@ -11720,21 +11396,6 @@ "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.1", "uvu": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, "micromark-core-commonmark": { @@ -11895,9 +11556,9 @@ } }, "micromark-util-sanitize-uri": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz", - "integrity": "sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz", + "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==", "requires": { "micromark-util-character": "^1.0.0", "micromark-util-encode": "^1.0.0", @@ -11963,9 +11624,9 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" }, "mkdirp-classic": { "version": "0.5.3", @@ -11978,9 +11639,9 @@ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "multipipe": { "version": "1.0.2", @@ -12037,12 +11698,24 @@ "postcss": "8.4.14", "styled-jsx": "5.0.7", "use-sync-external-store": "1.2.0" + }, + "dependencies": { + "postcss": { + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + } } }, "next-i18next": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/next-i18next/-/next-i18next-13.0.2.tgz", - "integrity": "sha512-aUHyKT2kztMgEP44zDB5KoW8XZUQawIdOYWXcrMH6lxAcS0kBsKX0uKMzGS5XlgLW88gvOVc3D7NdfCznLgyyg==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/next-i18next/-/next-i18next-13.0.3.tgz", + "integrity": "sha512-7AA8J6WbkxRBtSf1+97LSAE7btxWZHsBIJEJ3FuTSBgYtpRiO5NGjcb8XbNAlz6yGU0TtS+yZE+/Wu83KhIT1Q==", "requires": { "@babel/runtime": "^7.20.6", "@types/hoist-non-react-statics": "^3.3.1", @@ -12057,6 +11730,29 @@ "integrity": "sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==", "requires": { "semver": "^7.3.5" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } } }, "node-addon-api": { @@ -12065,9 +11761,9 @@ "integrity": "sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==" }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" }, "normalize-path": { "version": "3.0.0", @@ -12099,9 +11795,10 @@ "dev": true }, "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true }, "object.assign": { "version": "4.1.4", @@ -12113,14 +11810,6 @@ "define-properties": "^1.1.4", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" - }, - "dependencies": { - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - } } }, "object.entries": { @@ -12287,9 +11976,10 @@ "dev": true }, "postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "version": "8.4.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", + "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "dev": true, "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -12327,12 +12017,12 @@ } }, "postcss-nested": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", - "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.6" + "postcss-selector-parser": "^6.0.10" } }, "postcss-selector-parser": { @@ -12351,11 +12041,11 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "posthog-js": { - "version": "1.34.0", - "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.34.0.tgz", - "integrity": "sha512-HkRwwzdz31N5ykQIO3SIkSS8nwhdqqnuDZ/qltitX4FhxrV9/tSRavEXz0YLvioOXeNVmQWtsN3krKajErwkwg==", + "version": "1.39.1", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.39.1.tgz", + "integrity": "sha512-ZbLs0iSv4nCdcY9cy85lejCQtTh8JmXVzSegCVJweRCmGf4lFEJSsfrezm1j7kww4yCn0dFdVr0A245MIfsZuw==", "requires": { - "@sentry/types": "^7.2.0", + "@sentry/types": "7.22.0", "fflate": "^0.4.1", "rrweb-snapshot": "^1.1.14" } @@ -12398,12 +12088,19 @@ "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } } }, "property-information": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.1.1.tgz", - "integrity": "sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz", + "integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==" }, "pump": { "version": "3.0.0", @@ -12512,9 +12209,9 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "react-redux": { - "version": "7.2.8", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.8.tgz", - "integrity": "sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==", + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", + "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", "requires": { "@babel/runtime": "^7.15.4", "@types/react-redux": "^7.1.20", @@ -12617,9 +12314,9 @@ } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "react-mailchimp-subscribe": { "version": "2.1.3", @@ -12632,9 +12329,9 @@ } }, "react-markdown": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.3.tgz", - "integrity": "sha512-We36SfqaKoVNpN1QqsZwWSv/OZt5J15LNgTLWynwAN5b265hrQrsjMtlRNwUvS+YyR3yDM8HpTNc4pK9H/Gc0A==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.4.tgz", + "integrity": "sha512-2oxHa6oDxc1apg/Gnc1Goh06t3B617xeywqI/92wmDV9FELI6ayRkwge7w7DoEqM0gRpZGTNU6xQG+YpJISnVg==", "requires": { "@types/hast": "^2.0.0", "@types/prop-types": "^15.0.0", @@ -12651,19 +12348,12 @@ "unified": "^10.0.0", "unist-util-visit": "^4.0.0", "vfile": "^5.0.0" - }, - "dependencies": { - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - } } }, "react-redux": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.2.tgz", - "integrity": "sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==", + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", + "integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==", "requires": { "@babel/runtime": "^7.12.1", "@types/hoist-non-react-statics": "^3.3.1", @@ -12671,13 +12361,6 @@ "hoist-non-react-statics": "^3.3.2", "react-is": "^18.0.0", "use-sync-external-store": "^1.0.0" - }, - "dependencies": { - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - } } }, "react-resizable": { @@ -12705,13 +12388,14 @@ } }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, "readdirp": { @@ -12732,9 +12416,9 @@ } }, "redux-thunk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", - "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", "requires": {} }, "regenerator-runtime": { @@ -12786,9 +12470,9 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "reselect": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.6.tgz", - "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==" + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz", + "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==" }, "resolve": { "version": "1.22.1", @@ -12892,12 +12576,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "requires": { - "lru-cache": "^6.0.0" - } + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "set-cookie-parser": { "version": "2.5.1", @@ -12919,9 +12600,9 @@ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, "sharp": { - "version": "0.31.2", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.2.tgz", - "integrity": "sha512-DUdNVEXgS5A97cTagSLIIp8dUZ/lZtk78iNVZgHdHbx1qnQR7JAHY0BnXnwwH39Iw+VKhO08CTYhIg0p98vQ5Q==", + "version": "0.31.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", + "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", "requires": { "color": "^4.2.3", "detect-libc": "^2.0.1", @@ -12931,6 +12612,29 @@ "simple-get": "^4.0.1", "tar-fs": "^2.1.1", "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } } }, "shebang-command": { @@ -12980,6 +12684,13 @@ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "requires": { "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } } }, "slash": { @@ -12999,9 +12710,9 @@ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" }, "space-separated-tokens": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", - "integrity": "sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==" }, "split-on-first": { "version": "1.1.0", @@ -13025,12 +12736,9 @@ "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==" }, "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, "string.prototype.matchall": { "version": "4.0.8", @@ -13105,9 +12813,9 @@ } }, "styled-components": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.5.tgz", - "integrity": "sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg==", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz", + "integrity": "sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/traverse": "^7.4.5", @@ -13119,6 +12827,13 @@ "hoist-non-react-statics": "^3.0.0", "shallowequal": "^1.1.0", "supports-color": "^5.5.0" + }, + "dependencies": { + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + } } }, "styled-jsx": { @@ -13128,9 +12843,9 @@ "requires": {} }, "stylis": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" }, "supports-color": { "version": "5.5.0", @@ -13162,9 +12877,9 @@ } }, "tailwindcss": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.7.tgz", - "integrity": "sha512-r7mgumZ3k0InfVPpGWcX8X/Ut4xBfv+1O/+C73ar/m01LxGVzWvPxF/w6xIUPEztrCoz7axfx0SMdh8FH8ZvRQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", + "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", "dev": true, "requires": { "arg": "^5.0.2", @@ -13173,22 +12888,31 @@ "detective": "^5.2.1", "didyoumean": "^1.2.2", "dlv": "^1.1.3", - "fast-glob": "^3.2.11", + "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.14", + "postcss": "^8.4.18", "postcss-import": "^14.1.0", "postcss-js": "^4.0.0", "postcss-load-config": "^3.1.4", - "postcss-nested": "5.0.6", + "postcss-nested": "6.0.0", "postcss-selector-parser": "^6.0.10", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", "resolve": "^1.22.1" + }, + "dependencies": { + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } } }, "tapable": { @@ -13218,6 +12942,26 @@ "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } } }, "text-segmentation": { @@ -13249,26 +12993,10 @@ "xtend": "~2.1.1" }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==" }, "xtend": { "version": "2.1.2", @@ -13291,9 +13019,9 @@ } }, "tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, "to-fast-properties": { "version": "2.0.0", @@ -13337,9 +13065,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -13348,9 +13076,9 @@ } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "tsscmp": { "version": "1.0.6", @@ -13407,10 +13135,21 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, "typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true }, "uc.micro": { @@ -13498,9 +13237,9 @@ } }, "update-browserslist-db": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", - "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -13567,9 +13306,9 @@ } }, "vfile": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.5.tgz", - "integrity": "sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.6.tgz", + "integrity": "sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA==", "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -13578,9 +13317,9 @@ } }, "vfile-message": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", - "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.3.tgz", + "integrity": "sha512-0yaU+rj2gKAyEk12ffdSbBfjnnj+b1zqTBv3OQCTn8yEB02bsPizwdBPrLJjHnK+cU9EMMcUnNv938XcZIkmdA==", "requires": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^3.0.0" @@ -13613,6 +13352,20 @@ "is-symbol": "^1.0.3" } }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -13631,9 +13384,10 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "peer": true }, "yaml": { "version": "1.10.2", diff --git a/frontend/pages/activity/[id].tsx b/frontend/pages/activity/[id].tsx new file mode 100644 index 000000000..974607d0a --- /dev/null +++ b/frontend/pages/activity/[id].tsx @@ -0,0 +1,145 @@ +import React, { useEffect, useState } from 'react'; +import { useRouter } from 'next/router'; +import { useTranslation } from "next-i18next"; +import ActivitySideBar from 'ee/components/ActivitySideBar'; + +import Button from '~/components/basic/buttons/Button'; +import EventFilter from '~/components/basic/EventFilter'; +import NavHeader from '~/components/navigation/NavHeader'; +import { getTranslatedServerSideProps } from '~/components/utilities/withTranslateProps'; + +import getProjectLogs from '../../ee/api/secrets/GetProjectLogs'; +import ActivityTable from '../../ee/components/ActivityTable'; + + +interface logData { + _id: string; + channel: string; + createdAt: string; + ipAddress: string; + user: { + email: string; + }; + actions: { + _id: string; + name: string; + payload: { + secretVersions: string[]; + } + }[] +} + +interface PayloadProps { + _id: string; + name: string; + secretVersions: string[]; +} + +interface logDataPoint { + _id: string; + channel: string; + createdAt: string; + ipAddress: string; + user: string; + payload: PayloadProps[]; +} + +/** + * This is the tab that includes all of the user activity logs + */ +export default function Activity() { + const router = useRouter(); + const [eventChosen, setEventChosen] = useState(''); + const [logsData, setLogsData] = useState([]); + const [currentOffset, setCurrentOffset] = useState(0); + const currentLimit = 10; + const [currentSidebarAction, toggleSidebar] = useState() + const { t } = useTranslation(); + + // this use effect updates the data in case of a new filter being added + useEffect(() => { + setCurrentOffset(0); + const getLogData = async () => { + const tempLogsData = await getProjectLogs({ workspaceId: String(router.query.id), offset: 0, limit: currentLimit, userId: "", actionNames: eventChosen }) + setLogsData(tempLogsData.map((log: logData) => { + return { + _id: log._id, + channel: log.channel, + createdAt: log.createdAt, + ipAddress: log.ipAddress, + user: log.user.email, + payload: log.actions.map(action => { + return { + _id: action._id, + name: action.name, + secretVersions: action.payload.secretVersions + } + }) + } + })) + } + getLogData(); + }, [eventChosen]); + + // this use effect adds more data in case 'View More' button is clicked + useEffect(() => { + const getLogData = async () => { + const tempLogsData = await getProjectLogs({ workspaceId: String(router.query.id), offset: currentOffset, limit: currentLimit, userId: "", actionNames: eventChosen }) + setLogsData(logsData.concat(tempLogsData.map((log: logData) => { + return { + _id: log._id, + channel: log.channel, + createdAt: log.createdAt, + ipAddress: log.ipAddress, + user: log.user.email, + payload: log.actions.map(action => { + return { + _id: action._id, + name: action.name, + secretVersions: action.payload.secretVersions + } + }) + } + }))) + } + getLogData(); + }, [currentLimit, currentOffset]); + + const loadMoreLogs = () => { + setCurrentOffset(currentOffset + currentLimit); + } + + return ( +
+ + {currentSidebarAction && } +
+
+

Activity Logs

+
+

+ Event history for this Infisical project. +

+
+
+ +
+ +
+
+
+
+
+ ); +} + +Activity.requireAuth = true; + +export const getServerSideProps = getTranslatedServerSideProps(["activity"]); \ No newline at end of file diff --git a/frontend/pages/api/serviceToken/addServiceToken.ts b/frontend/pages/api/serviceToken/addServiceToken.ts index 5dad69f69..91019f413 100644 --- a/frontend/pages/api/serviceToken/addServiceToken.ts +++ b/frontend/pages/api/serviceToken/addServiceToken.ts @@ -5,14 +5,21 @@ interface Props { workspaceId: string; environment: string; expiresIn: number; - publicKey: string; encryptedKey: string; - nonce: string; + iv: string; + tag: string; } /** * This route gets service tokens for a specific user in a project - * @param {*} param0 + * @param {object} obj + * @param {string} obj.name - name of the service token + * @param {string} obj.workspaceId - workspace for which we are issuing the token + * @param {string} obj.environment - environment for which we are issuing the token + * @param {string} obj.expiresIn - how soon the service token expires in ms + * @param {string} obj.encryptedKey - encrypted project key through random symmetric encryption + * @param {string} obj.iv - obtained through symmetric encryption + * @param {string} obj.tag - obtained through symmetric encryption * @returns */ const addServiceToken = ({ @@ -20,11 +27,11 @@ const addServiceToken = ({ workspaceId, environment, expiresIn, - publicKey, encryptedKey, - nonce + iv, + tag }: Props) => { - return SecurityClient.fetchCall('/api/v1/service-token/', { + return SecurityClient.fetchCall('/api/v2/service-token/', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -34,13 +41,13 @@ const addServiceToken = ({ workspaceId, environment, expiresIn, - publicKey, encryptedKey, - nonce + iv, + tag }) }).then(async (res) => { if (res && res.status == 200) { - return (await res.json()).token; + return (await res.json()); } else { console.log('Failed to add service tokens'); } diff --git a/frontend/pages/api/serviceToken/deleteServiceToken.ts b/frontend/pages/api/serviceToken/deleteServiceToken.ts new file mode 100644 index 000000000..94f2f1602 --- /dev/null +++ b/frontend/pages/api/serviceToken/deleteServiceToken.ts @@ -0,0 +1,30 @@ +import SecurityClient from '~/utilities/SecurityClient'; + +interface Props { + serviceTokenId: string; +} + +/** + * This route revokes a specific service token + * @param {object} obj + * @param {string} obj.serviceTokenId - id of a cervice token that we want to delete + * @returns + */ +const deleteServiceToken = ({ + serviceTokenId, +}: Props) => { + return SecurityClient.fetchCall('/api/v2/service-token/' + serviceTokenId, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + }).then(async (res) => { + if (res && res.status == 200) { + return (await res.json()); + } else { + console.log('Failed to delete a service token'); + } + }); +}; + +export default deleteServiceToken; diff --git a/frontend/pages/api/serviceToken/getServiceTokens.ts b/frontend/pages/api/serviceToken/getServiceTokens.ts index d2577cc83..db6b035dd 100644 --- a/frontend/pages/api/serviceToken/getServiceTokens.ts +++ b/frontend/pages/api/serviceToken/getServiceTokens.ts @@ -7,7 +7,7 @@ import SecurityClient from '~/utilities/SecurityClient'; */ const getServiceTokens = ({ workspaceId }: { workspaceId: string }) => { return SecurityClient.fetchCall( - '/api/v1/workspace/' + workspaceId + '/service-tokens', + '/api/v2/workspace/' + workspaceId + '/service-token-data', { method: 'GET', headers: { @@ -16,7 +16,7 @@ const getServiceTokens = ({ workspaceId }: { workspaceId: string }) => { } ).then(async (res) => { if (res && res.status == 200) { - return (await res.json()).serviceTokens; + return (await res.json()).serviceTokenData; } else { console.log('Failed to get service tokens'); } diff --git a/frontend/pages/dashboard/[id].tsx b/frontend/pages/dashboard/[id].tsx index 60fcc7a00..9c33daf20 100644 --- a/frontend/pages/dashboard/[id].tsx +++ b/frontend/pages/dashboard/[id].tsx @@ -6,8 +6,9 @@ import { useTranslation } from "next-i18next"; import { faArrowDownAZ, faArrowDownZA, + faArrowLeft, faCheck, - faCopy, + faClockRotateLeft, faDownload, faEye, faEyeSlash, @@ -16,6 +17,8 @@ import { faPlus, } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import getProjectSercetSnapshotsCount from 'ee/api/secrets/GetProjectSercetSnapshotsCount'; +import PITRecoverySidebar from 'ee/components/PITRecoverySidebar'; import Button from '~/components/basic/buttons/Button'; import ListBox from '~/components/basic/Listbox'; @@ -30,12 +33,13 @@ import pushKeys from '~/components/utilities/secrets/pushKeys'; import { getTranslatedServerSideProps } from '~/components/utilities/withTranslateProps'; import guidGenerator from '~/utilities/randomId'; -import { envMapping } from '../../public/data/frequentConstants'; +import { envMapping, reverseEnvMapping } from '../../public/data/frequentConstants'; import getUser from '../api/user/getUser'; import checkUserAction from '../api/userActions/checkUserAction'; import registerUserAction from '../api/userActions/registerUserAction'; import getWorkspaces from '../api/workspace/getWorkspaces'; +const queryString = require("query-string"); interface SecretDataProps { type: 'personal' | 'shared'; @@ -46,6 +50,19 @@ interface SecretDataProps { comment: string; } +interface SnapshotProps { + id: string; + createdAt: string; + secretVersions: { + id: string; + pos: number; + type: "personal" | "shared"; + environment: string; + key: string; + value: string; + }[]; +} + /** * this function finds the teh duplicates in an array * @param arr - array of anything (e.g., with secret keys and types (personal/shared)) @@ -76,22 +93,20 @@ export default function Dashboard() { const [workspaceId, setWorkspaceId] = useState(''); const [blurred, setBlurred] = useState(true); const [isKeyAvailable, setIsKeyAvailable] = useState(true); - const [env, setEnv] = useState( - router.asPath.split('?').length == 1 - ? 'Development' - : Object.keys(envMapping).includes(router.asPath.split('?')[1]) - ? router.asPath.split('?')[1] - : 'Development' - ); + const [env, setEnv] = useState('Development'); + const [snapshotEnv, setSnapshotEnv] = useState('Development'); const [isNew, setIsNew] = useState(false); + const [isLoading, setIsLoading] = useState(false); const [searchKeys, setSearchKeys] = useState(''); const [errorDragAndDrop, setErrorDragAndDrop] = useState(false); - const [projectIdCopied, setProjectIdCopied] = useState(false); const [sortMethod, setSortMethod] = useState('alphabetical'); const [checkDocsPopUpVisible, setCheckDocsPopUpVisible] = useState(false); const [hasUserEverPushed, setHasUserEverPushed] = useState(false); const [sidebarSecretId, toggleSidebar] = useState("None"); + const [PITSidebarOpen, togglePITSidebar] = useState(false); const [sharedToHide, setSharedToHide] = useState([]); + const [snapshotData, setSnapshotData] = useState(); + const [numSnapshots, setNumSnapshots] = useState(); const { t } = useTranslation(); const { createNotification } = useNotificationContext(); @@ -142,17 +157,39 @@ export default function Dashboard() { useEffect(() => { (async () => { try { + console.log(1, 'reloaded') + const tempNumSnapshots = await getProjectSercetSnapshotsCount({ workspaceId: String(router.query.id) }) + setNumSnapshots(tempNumSnapshots); const userWorkspaces = await getWorkspaces(); const listWorkspaces = userWorkspaces.map((workspace) => workspace._id); if ( - !listWorkspaces.includes(router.asPath.split('/')[2].split('?')[0]) + !listWorkspaces.includes(router.asPath.split('/')[2]) ) { router.push('/dashboard/' + listWorkspaces[0]); } - if (env != router.asPath.split('?')[1]) { - router.push(router.asPath.split('?')[0] + '?' + env); - } + const user = await getUser(); + setIsNew( + (Date.parse(String(new Date())) - Date.parse(user.createdAt)) / 60000 < 3 + ? true + : false + ); + + const userAction = await checkUserAction({ + action: 'first_time_secrets_pushed' + }); + setHasUserEverPushed(userAction ? true : false); + } catch (error) { + console.log('Error', error); + setData(undefined); + } + })(); + }, []); + + useEffect(() => { + (async () => { + try { + setIsLoading(true); setBlurred(true); setWorkspaceId(String(router.query.id)); @@ -174,18 +211,7 @@ export default function Dashboard() { dataToSort?.map((item) => item.key).indexOf(item) ).includes(row.key) && row.type == 'shared'))?.map((item) => item.id) ) - - const user = await getUser(); - setIsNew( - (Date.parse(String(new Date())) - Date.parse(user.createdAt)) / 60000 < 3 - ? true - : false - ); - - const userAction = await checkUserAction({ - action: 'first_time_secrets_pushed' - }); - setHasUserEverPushed(userAction ? true : false); + setIsLoading(false); } catch (error) { console.log('Error', error); setData(undefined); @@ -241,9 +267,14 @@ export default function Dashboard() { sortValuesHandler(tempdata, sortMethod == "alhpabetical" ? "-alphabetical" : "alphabetical"); }; - const deleteRow = (id: string) => { + const deleteRow = ({ ids, secretName }: { ids: string[]; secretName: string; }) => { setButtonReady(true); - setData(data!.filter((row: SecretDataProps) => row.id !== id)); + toggleSidebar("None"); + createNotification({ + text: `${secretName} has been deleted. Remember to save changes.`, + type: 'error' + }); + setData(data!.filter((row: SecretDataProps) => !ids.includes(row.id))); }; /** @@ -317,12 +348,21 @@ export default function Dashboard() { /** * Save the changes of environment variables and push them to the database */ - const savePush = async () => { - // Format the new object with environment variables - const obj = Object.assign( - {}, - ...data!.map((row: SecretDataProps) => ({ [row.type.charAt(0) + row.key]: [row.value, row.comment] })) - ); + const savePush = async (dataToPush?: any[], envToPush?: string) => { + let obj; + // dataToPush is mostly used for rollbacks, otherwise we always take the current state data + if ((dataToPush ?? [])?.length > 0) { + obj = Object.assign( + {}, + ...dataToPush!.map((row: SecretDataProps) => ({ [row.type.charAt(0) + row.key]: [row.value, row.comment ?? ''] })) + ); + } else { + // Format the new object with environment variables + obj = Object.assign( + {}, + ...data!.map((row: SecretDataProps) => ({ [row.type.charAt(0) + row.key]: [row.value, row.comment ?? ''] })) + ); + } // Checking if any of the secret keys start with a number - if so, don't do anything const nameErrors = !Object.keys(obj) @@ -346,13 +386,17 @@ export default function Dashboard() { // Once "Save changed is clicked", disable that button setButtonReady(false); - pushKeys({ obj, workspaceId: String(router.query.id), env }); + console.log(envToPush ? envToPush : env, env, envToPush) + pushKeys({ obj, workspaceId: String(router.query.id), env: envToPush ? envToPush : env }); // If this user has never saved environment variables before, show them a prompt to read docs if (!hasUserEverPushed) { setCheckDocsPopUpVisible(true); await registerUserAction({ action: 'first_time_secrets_pushed' }); } + + // increasing the number of project commits + setNumSnapshots(numSnapshots ?? 0 + 1); }; const addData = (newData: SecretDataProps[]) => { @@ -395,27 +439,10 @@ export default function Dashboard() { alink.click(); }; - const deleteCertainRow = (id: string) => { - deleteRow(id); + const deleteCertainRow = ({ ids, secretName }: { ids: string[]; secretName: string; }) => { + deleteRow({ids, secretName}); }; - /** - * This function copies the project id to the clipboard - */ - function copyToClipboard() { - const copyText = document.getElementById('myInput') as HTMLInputElement; - - if (copyText) { - copyText.select(); - copyText.setSelectionRange(0, 99999); // For mobile devices - - navigator.clipboard.writeText(copyText.value); - - setProjectIdCopied(true); - setTimeout(() => setProjectIdCopied(false), 2000); - } - } - return data ? (
@@ -438,6 +465,12 @@ export default function Dashboard() { savePush={savePush} sharedToHide={sharedToHide} setSharedToHide={setSharedToHide} + deleteRow={deleteCertainRow} + />} + {PITSidebarOpen && }
@@ -453,9 +486,22 @@ export default function Dashboard() { /> )}
+ {snapshotData && +
+
}
-

{t("dashboard:title")}

- {data?.length == 0 && ( +
+

{snapshotData ? "Secret Snapshot" : t("dashboard:title")}

+ {snapshotData && {new Date(snapshotData.createdAt).toLocaleString()}} +
+ {!snapshotData && data?.length == 0 && (
-
-

{`${t( - "common:project-id" - )}:`}

- -
- - - {t("common:click-to-copy")} - -
+
+
- {(data?.length !== 0 || buttonReady) && ( -
+ {(data?.length !== 0 || buttonReady) && !snapshotData && ( +
)} + {snapshotData &&
+
}
- {data?.length !== 0 && ( + {(snapshotData || data?.length !== 0) && ( <> - + : }
-
+ {!snapshotData &&
-
+
} + {!snapshotData &&
+
}
-
+ {!snapshotData &&
+
} )}
- {data?.length !== 0 ? ( + {isLoading ? ( +
+ infisical loading indicator +
+ ) : ( + data?.length !== 0 ? (
- {data?.filter(row => !(sharedToHide.includes(row.id) && row.type == 'shared')).map((keyPair) => ( + {!snapshotData && data?.filter(row => row.key.toUpperCase().includes(searchKeys.toUpperCase())) + .filter(row => !(sharedToHide.includes(row.id) && row.type == 'shared')).map((keyPair) => ( item.key + item.type))?.includes(keyPair.key + keyPair.type)} toggleSidebar={toggleSidebar} sidebarSecretId={sidebarSecretId} + isSnapshot={false} + /> + ))} + {snapshotData && snapshotData.secretVersions?.sort((a, b) => a.key.localeCompare(b.key)) + .filter(row => reverseEnvMapping[row.environment] == snapshotEnv) + .filter(row => row.key.toUpperCase().includes(searchKeys.toUpperCase())) + .filter(row => !(snapshotData.secretVersions?.filter(row => (snapshotData.secretVersions + ?.map((item) => item.key) + .filter( + (item, index) => + index !== + snapshotData.secretVersions?.map((item) => item.key).indexOf(item) + ).includes(row.key) && row.type == 'shared'))?.map((item) => item.id).includes(row.id) && row.type == 'shared')).map((keyPair) => ( + item.key + item.type))?.includes(keyPair.key + keyPair.type)} + toggleSidebar={toggleSidebar} + sidebarSecretId={sidebarSecretId} + isSnapshot={true} /> ))}
-
+ {!snapshotData &&
-
+
}
) : (
- {isKeyAvailable && ( + {isKeyAvailable && !snapshotData && ( ))}
- )} + ))}
diff --git a/frontend/pages/requestnewinvite.js b/frontend/pages/requestnewinvite.tsx similarity index 53% rename from frontend/pages/requestnewinvite.js rename to frontend/pages/requestnewinvite.tsx index c33861647..0f1358267 100644 --- a/frontend/pages/requestnewinvite.js +++ b/frontend/pages/requestnewinvite.tsx @@ -2,6 +2,10 @@ import React from "react"; import Head from "next/head"; import Image from "next/image"; +/** + * This is the page that shows up when a user's invitation + * to join a project/organization on Infisical has expired + */ export default function RequestNewInvite() { return (
@@ -9,16 +13,14 @@ export default function RequestNewInvite() { Request a New Invite -
-

Oops, your invite has expired.

-

Ask the administrator for a new one.

-

- Note: If it still {"doesn't work"}, please reach out to us at +

+

Oops, your invite has expired.

+

Ask your admin for a new one.

+

+ Note: If it still {"doesn't work"}, please reach out to us at support@infisical.com

-
+
setProjectIdCopied(false), 2000); + } + } + useEffect(async () => { let userWorkspaces = await getWorkspaces(); userWorkspaces.map((userWorkspace) => { @@ -103,6 +124,8 @@ export default function SettingsBasic() { workspaceId={router.query.id} closeModal={closeAddServiceTokenModal} workspaceName={workspaceName} + serviceTokens={serviceTokens} + setServiceTokens={setServiceTokens} />
@@ -124,7 +147,7 @@ export default function SettingsBasic() {
-

+

{t("common:display-name")}

@@ -150,7 +173,7 @@ export default function SettingsBasic() {
-
+

{t("common:project-id")}

@@ -169,28 +192,57 @@ export default function SettingsBasic() { {t("settings-project:docs")}

-
- +

{t("settings-project:auto-generated")}

+
+

{`${t( + "common:project-id" + )}:`}

+ +
+ + + {t("common:click-to-copy")} + +
-
+

{t("section-token:service-tokens")}

-

+

{t("section-token:service-tokens-description")}

+

+ Please, make sure you are on the + + latest version of CLI + . +

-
+
- - {/*
-

- Project Environments -

-

- Choose which environments will show up - in your Dashboard. Some common ones - include Development, Staging, and - Production. Often, teams choose to add - Testing. -

-

- Note: the text in brackets shows how - these environmant should be accessed in - CLI. -

-
- {envOptions.map((env) => ( -
- {env} -
- ))} -
-
-
-
*/}
-
+

{t("settings-project:danger-zone")}

diff --git a/frontend/pages/signupinvite.js b/frontend/pages/signupinvite.js index 169c5c014..d32d6038d 100644 --- a/frontend/pages/signupinvite.js +++ b/frontend/pages/signupinvite.js @@ -141,16 +141,16 @@ export default function SignupInvite() { // Step 4 of the sign up process (download the emergency kit pdf) const stepConfirmEmail = (
-

+

Confirm your email

verify email -
+