Skip to main content
Glama

mcp-google-sheets

encryption.ts3.4 kB
import * as crypto from 'crypto' import { randomBytes } from 'node:crypto' import { promisify } from 'util' import { AppSystemProp } from '@activepieces/server-shared' import { assertNotNullOrUndefined, isNil, } from '@activepieces/shared' import { Static, Type } from '@sinclair/typebox' import { Mutex } from 'async-mutex' import { redisConnections } from '../database/redis' import { localFileStore } from './local-store' import { RedisType, system } from './system/system' const algorithm = 'aes-256-cbc' const ivLength = 16 const mutexLock = new Mutex() export const EncryptedObject = Type.Composite([Type.Object({ iv: Type.String(), data: Type.String(), })]) export type EncryptedObject = Static<typeof EncryptedObject> const redisType = redisConnections.getRedisType() export const encryptUtils = { decryptString: async (encryptedObject: EncryptedObject): Promise<string> => { const secret = await encryptUtils.getEncryptionKey() const iv = Buffer.from(encryptedObject.iv, 'hex') const key = Buffer.from(secret!, 'binary') const decipher = crypto.createDecipheriv(algorithm, key, iv) let decrypted = decipher.update(encryptedObject.data, 'hex', 'utf8') decrypted += decipher.final('utf8') return decrypted }, decryptObject: async <T>(encryptedObject: EncryptedObject): Promise<T> => { const secret = await encryptUtils.getEncryptionKey() const iv = Buffer.from(encryptedObject.iv, 'hex') const key = Buffer.from(secret!, 'binary') const decipher = crypto.createDecipheriv(algorithm, key, iv) let decrypted = decipher.update(encryptedObject.data, 'hex', 'utf8') decrypted += decipher.final('utf8') return JSON.parse(decrypted) }, encryptObject: async (object: unknown): Promise<EncryptedObject> => { const objectString = JSON.stringify(object) return encryptUtils.encryptString(objectString) }, encryptString: async (inputString: string): Promise<EncryptedObject> => { const secret = await encryptUtils.getEncryptionKey() const iv = crypto.randomBytes(ivLength) assertNotNullOrUndefined(secret, 'secret') const key = Buffer.from(secret, 'binary') const cipher = crypto.createCipheriv(algorithm, key, iv) let encrypted = cipher.update(inputString, 'utf8', 'hex') encrypted += cipher.final('hex') return { iv: iv.toString('hex'), data: encrypted, } }, getEncryptionKey: async (): Promise<string | null> => { const secret = system.get(AppSystemProp.ENCRYPTION_KEY) ?? null if (!isNil(secret)) { return secret } if (redisType === RedisType.MEMORY) { return generateAndStoreSecret() } return null }, } function generateAndStoreSecret(): Promise<string> { return mutexLock.runExclusive(async () => { const storedSecret = await localFileStore.load(AppSystemProp.ENCRYPTION_KEY) if (!isNil(storedSecret)) { return storedSecret } const secretLengthInBytes = 16 const secretBuffer = await promisify(randomBytes)(secretLengthInBytes) const secret = secretBuffer.toString('hex') await localFileStore.save(AppSystemProp.ENCRYPTION_KEY, secret) return secret }) }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server